When I am reading the file content from server it returns the following error message:
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:462)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:240)
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:119)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
at org.apache.coyote.Response.doWrite(Response.java:504)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:383)
... 28 more
and my servlet program is
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition","attachment;filename="+filename);
FileInputStream in = new FileInputStream(new File(filepath));
ServletOutputStream output=response.getOutputStream();
byte[] outputByte=new byte[4096];
while(in.read(outputByte,0,4096)!=-1){
output.write(outputByte,0,4096);//error indicates in this line
}
in.close();
output.flush();
output.close();
How to solve this issue?
asked Oct 20, 2012 at 8:03
7
I’ve got the same exception and in my case the problem was in a renegotiation procecess. In fact my client closed a connection when the server tried to change a cipher suite. After digging it appears that in the jdk 1.6 update 22 renegotiation process is disabled by default. If your security constraints can effort this, try to enable the unsecure renegotiation by setting the sun.security.ssl.allowUnsafeRenegotiation
system property to true
. Here is some information about the process:
Session renegotiation is a mechanism within the SSL protocol that
allows the client or the server to trigger a new SSL handshake during
an ongoing SSL communication. Renegotiation was initially designed as
a mechanism to increase the security of an ongoing SSL channel, by
triggering the renewal of the crypto keys used to secure that channel.
However, this security measure isn’t needed with modern cryptographic
algorithms. Additionally, renegotiation can be used by a server to
request a client certificate (in order to perform client
authentication) when the client tries to access specific, protected
resources on the server.
Additionally there is the excellent post about this issue in details and written in (IMHO) understandable language.
answered Jul 15, 2013 at 14:15
DmitryDmitry
3,0285 gold badges44 silver badges65 bronze badges
The socket has been closed by the client (browser).
A bug in your code:
byte[] outputByte=new byte[4096];
while(in.read(outputByte,0,4096)!=-1){
output.write(outputByte,0,4096);
}
The last packet read, then write may have a length < 4096, so I suggest:
byte[] outputByte=new byte[4096];
int len;
while(( len = in.read(outputByte, 0, 4096 )) > 0 ) {
output.write( outputByte, 0, len );
}
It’s not your question, but it’s my answer…
answered Oct 20, 2012 at 8:10
AubinAubin
14.5k9 gold badges62 silver badges84 bronze badges
4
The correct way to ‘solve’ it is to close the connection and forget about the client. The client has closed the connection while you where still writing to it, so he doesn’t want to know you, so that’s it, isn’t it?
answered Oct 20, 2012 at 9:11
2
It seems like your problem may be arising at
while(in.read(outputByte,0,4096)!=-1){
where it might go into an infinite loop for not advancing the offset (which is 0 always in the call). Try
while(in.read(outputByte)!=-1){
which will by default try to read upto outputByte.length into the byte[]
. This way you dont have to worry about the offset. See FileInputStrem’s read method
answered Oct 20, 2012 at 9:27
prajeesh kumarprajeesh kumar
1,8961 gold badge17 silver badges17 bronze badges
I had the same problem with small difference:
Exception was raised at the moment of flushing
It is a different stackoverflow issue. The brief explanation was a wrong response header setting:
response.setHeader(«Content-Encoding», «gzip»);
despite uncompressed response data content.
So the the connection was closed by the browser.
answered May 2, 2016 at 14:24
Kayvan TehraniKayvan Tehrani
2,9702 gold badges31 silver badges45 bronze badges
When I am reading the file content from server it returns the following error message:
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:462)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:240)
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:119)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
at org.apache.coyote.Response.doWrite(Response.java:504)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:383)
... 28 more
and my servlet program is
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition","attachment;filename="+filename);
FileInputStream in = new FileInputStream(new File(filepath));
ServletOutputStream output=response.getOutputStream();
byte[] outputByte=new byte[4096];
while(in.read(outputByte,0,4096)!=-1){
output.write(outputByte,0,4096);//error indicates in this line
}
in.close();
output.flush();
output.close();
How to solve this issue?
asked Oct 20, 2012 at 8:03
7
I’ve got the same exception and in my case the problem was in a renegotiation procecess. In fact my client closed a connection when the server tried to change a cipher suite. After digging it appears that in the jdk 1.6 update 22 renegotiation process is disabled by default. If your security constraints can effort this, try to enable the unsecure renegotiation by setting the sun.security.ssl.allowUnsafeRenegotiation
system property to true
. Here is some information about the process:
Session renegotiation is a mechanism within the SSL protocol that
allows the client or the server to trigger a new SSL handshake during
an ongoing SSL communication. Renegotiation was initially designed as
a mechanism to increase the security of an ongoing SSL channel, by
triggering the renewal of the crypto keys used to secure that channel.
However, this security measure isn’t needed with modern cryptographic
algorithms. Additionally, renegotiation can be used by a server to
request a client certificate (in order to perform client
authentication) when the client tries to access specific, protected
resources on the server.
Additionally there is the excellent post about this issue in details and written in (IMHO) understandable language.
answered Jul 15, 2013 at 14:15
DmitryDmitry
3,0285 gold badges44 silver badges65 bronze badges
The socket has been closed by the client (browser).
A bug in your code:
byte[] outputByte=new byte[4096];
while(in.read(outputByte,0,4096)!=-1){
output.write(outputByte,0,4096);
}
The last packet read, then write may have a length < 4096, so I suggest:
byte[] outputByte=new byte[4096];
int len;
while(( len = in.read(outputByte, 0, 4096 )) > 0 ) {
output.write( outputByte, 0, len );
}
It’s not your question, but it’s my answer…
answered Oct 20, 2012 at 8:10
AubinAubin
14.5k9 gold badges62 silver badges84 bronze badges
4
The correct way to ‘solve’ it is to close the connection and forget about the client. The client has closed the connection while you where still writing to it, so he doesn’t want to know you, so that’s it, isn’t it?
answered Oct 20, 2012 at 9:11
2
It seems like your problem may be arising at
while(in.read(outputByte,0,4096)!=-1){
where it might go into an infinite loop for not advancing the offset (which is 0 always in the call). Try
while(in.read(outputByte)!=-1){
which will by default try to read upto outputByte.length into the byte[]
. This way you dont have to worry about the offset. See FileInputStrem’s read method
answered Oct 20, 2012 at 9:27
prajeesh kumarprajeesh kumar
1,8961 gold badge17 silver badges17 bronze badges
I had the same problem with small difference:
Exception was raised at the moment of flushing
It is a different stackoverflow issue. The brief explanation was a wrong response header setting:
response.setHeader(«Content-Encoding», «gzip»);
despite uncompressed response data content.
So the the connection was closed by the browser.
answered May 2, 2016 at 14:24
Kayvan TehraniKayvan Tehrani
2,9702 gold badges31 silver badges45 bronze badges
I am trying to implement an HTTP Server using Sockets. If the Client (For example a browser) requests a directory the server displays a list of available files. The problem arises when the client is requesting a file. I get the following error:
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at cf.charly1811.java.web.RequestHandler.writeFile(RequestHandler.java:152)
at cf.charly1811.java.web.RequestHandler.processRequest(RequestHandler.java:139)
at cf.charly1811.java.web.RequestHandler.handleRequest(RequestHandler.java:110)
at cf.charly1811.java.web.RequestHandler.run(RequestHandler.java:86)
at java.lang.Thread.run(Thread.java:745)
The stacktrace shows that the problem is coming from the writeFile()
methods:
private void writeFile(File request) throws IOException
{
InputStream byteReader = new BufferedInputStream(new FileInputStream(request));
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = byteReader.read(buffer)) != -1)
{
outputStream.write(buffer, 0, bytesRead);
}
byteReader.close();
}
But I can’t figure out what’s wrong.
Can you help me?
EDIT
Thanks everyone for your answers. After I read your answers I understood that the problem was that the Socket when an error occured. Here’s was my wrong code:
// Method to process a single request
handleRequest() throw IOException
{
// process here
// if the client request a file
writeFile();
// close socket when the request is processed
}
// The method is called
public run()
{
try{
// If an error occurs the try/catch won't be called because it is implemented outside the loop. So when an IOException occurs, the loop just stop and exit the program
while(true)
{
handleRequest();
}
}
catch(IOException e) {
// Handle exception here
}
}
And my new code was looking like this:
// Method to process a single request
handleRequest()
{
try {
// process here
// if the client request a file
writeFile();
// close socket when the request is processed
}
// If this exception occurs the catch() method will be called
catch(IOException e)
{
// handle exception here
}
}
// The method is called
public run()
{
while(true)
{
handleRequest();
}
}
}
Disclosure: This article may contain affiliate links. When you purchase, we may earn a commission.
Hello guys, for the past few months, I have been writing about different socket-related errors on Java applications, and today I am going to talk about another common socket-related exception in Java — java.net.SocketException: Connection reset Exception. There is no difference between exceptions thrown by the client and server. This is also very similar to the java.net.SocketException: Failed to read from SocketChannel: Connection reset by a peer but there is some subtle difference. The difference between connection reset and connection reset by peer is that the first means that your side reset the connection, the second means the peer did it. Nothing to do with clients and servers whatsoever
The java.net.SocketException: Connection reset error usually comes when one of the parties in TCP connection like client or server is trying to read/write data, but other parties abruptly close the connection like it was crashed, stopped, or terminated.
You will also not receive this error if the Client closes the connection using the close() method before sever sends the response. This occurred when Server closed the connection, while the client is still waiting to read data from its InputStream.
For example, if you are using BufferedReader for writing data then it will block if you don’t write n or line terminator on the message.
Similarly, on the server side you will see the following error :
Exception in thread "main" java.net.SocketException: Connection reset at java.net.SocketInputStream.read(Unknown Source) at sun.nio.cs.StreamDecoder.readBytes(Unknown Source
This occurs when the Server is reading data and blocked on a read() call but the client was terminated, this time you saw the message on the server-side. As you can see we get a SocketException with the message Connection reset. This happens when one of the parties closes the connection without using the close() method.
Btw, this is my fourth article in the series on how to deal with Socket related exceptions in Java. If you haven’t read the other articles of
this series, here are them
- How to fix java.net.SocketException: Software caused connection abort: recv failed
- How to fix java.net.SocketException: Failed to read from SocketChannel: Connection reset by peer
- Overview of 7 common Socket Exception in Java applications
- How to deal with java.net.SocketException: Broken pipe exception
If you struggle to solve socket-related exceptions in client-server Java applications then you can go through those articles to learn more about how to deal with these exceptions.
How to solve java.net.SocketException: Connection reset Exception in Java
If you are a client and getting this error while connecting to the server-side application then you can do the following things:
1. First, check if the Server is running by doing telnet on the host port on which the server runs.
In most cases, you will find that either server is not running or restarted manually or automatically.
2. Check if the server was restarted
3. Check if the server failed over to a different host
4. log the error
5. Report the problem to the server team
Though, as a Java programmer, you should have good knowledge of Socket API, both old and new and if you need the recommendation to level up your skill, I suggest you join a comprehensive Java course like The Complete Java Programming MasterClass course by Tim Buchalaka on Udemy. It’s not only the most comprehensive course but also the most up-to-date and covers news features from recent Java releases.
That’s all about how to deal with the java.net.SocketException: Connection reset Exception in Java. As I told you it doesn’t matter whether this error is coming on server-side Java application or client-side Java application then underlying cause is always that the other party terminated the connection or the connection is lost due to network issues. You also cannot rule out the possibility of that host is restarted or the server-side application crashed.
Other Java troubleshooting articles you may like:
- java.sql.SQLException: No suitable driver found for ‘jdbc:mysql://localhost:3306/mysql [Solution]
- How to solve java.lang.ClassNotFoundException: com.mysql.jdbc.Driver error? (hint)
- java.sql.SQLServerException: The index 58 is out of range — JDBC (solution)
- How to fix Caused By: java.lang.NoClassDefFoundError: org/apache/log4j/Logger (solution)
- org.Springframework.Web.Context.ContextLoaderListener (solution)
- How to connect to MySQL database in Java? (tutorial)
- Fixing java.lang.UnsupportedClassVersionError Unsupported major.minor version 50.0 (solution)
- How to fix ‘javac’ is not recognized as an internal or external command (solution)
- java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory error (solution)
- Common reasons of java.lang.ArrayIndexOutOfBoundsException in Java? (solution)
- java.lang.ClassNotFoundException :
- How to avoid ConcurrentModificationException in Java? (tutorial)
- How to solve the «could not create the Java virtual machine» error in Java? (solution)
- 10 common reasons for java.lang.NumberFormatException in Java? (tutorial)
- How to fix the «illegal start of expression» compile-time error in Java? (tutorial)
- Cause and solution of «class, interface, or enum expected» compiler error in Java? (fix)
- How to solve java.lang.OutOfMemoryError: Java Heap Space in Eclipse, Tomcat? (solution)
- How to fix «Error: Could not find or load main class» in Eclipse? (guide)
- How to solve java.lang.classnotfoundexception oracle.jdbc.driver.oracledriver? (solution)
- How to solve «variable might not have initialized» compile-time error in Java? (answer)
Thanks for reading this article, if you like this article then please share it with your friends and colleagues too. If you have any doubt or questions then please drop a comment.
P. S. — It’s worth noting that both Socket and Network
Programming is advanced skill and worth learning. If you want to learn more about Socket Programming in Java, I suggest you check the Java: Socket Programming Simplified, a free course on Udemy.
when write 50w data(something like:a hashmap includes 50w row) to redis server,it works.
but when i write 55w data to redis server,this exception has been throwed.
at first,i think it’s caused by timeout,but i set maxtimewait from 1000*1000 to -1, it also doesn’t work.
then i think there is not enough memery,but i change env to my local, my local mem is 8g,and redisconf’s [maxmemory] is default not be set,so i think the problom is not here,
at last,i have changed env to my local,and it also doesn’t work,so i think the reason is not on server,it maybe client’s problem,i really can’t not understand why it doesn’t work.help!
jedis version is:2.2.1,(2.6.0 also)
redis info:
Server
redis_version:2.8.4
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:c727d0517b021f2
redis_mode:standalone
os:Linux 2.6.32-431.el6.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.7
process_id:2852
run_id:0294dde7a8ea2b23ddd86069d62752a0a33
tcp_port:6379
uptime_in_seconds:12528
uptime_in_days:0
hz:10
lru_clock:2050369
config_file:/usr/local/redis/conf/redis.co
Clients
connected_clients:7
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
Memory
used_memory:9235096
used_memory_human:8.81M
used_memory_rss:17690624
used_memory_peak:80723800
used_memory_peak_human:76.98M
used_memory_lua:33792
mem_fragmentation_ratio:1.92
mem_allocator:jemalloc-3.2.0
Persistence
loading:0
rdb_changes_since_last_save:1
rdb_bgsave_in_progress:0
rdb_last_save_time:1425595531
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
Stats
total_connections_received:192
total_commands_processed:892515
instantaneous_ops_per_sec:0
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:6
evicted_keys:0
keyspace_hits:3559
keyspace_misses:188
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:12960
Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
CPU
used_cpu_sys:141.56
used_cpu_user:32.85
used_cpu_sys_children:1.75
used_cpu_user_children:3.52
Keyspace
db0:keys=21715,expires=18,avg_ttl=20991829
i met the problem the same, more of 500 thousands of data in hashmap write failed with exception
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset by peer: socket write error
at redis.clients.jedis.Protocol.sendCommand(Protocol.java:94)
at redis.clients.jedis.Protocol.sendCommand(Protocol.java:74)
at redis.clients.jedis.Connection.sendCommand(Connection.java:78)
at redis.clients.jedis.BinaryClient.hmset(BinaryClient.java:242)
at redis.clients.jedis.Client.hmset(Client.java:158)
at redis.clients.jedis.Jedis.hmset(Jedis.java:631)
at com.axon.scene.RedisHmsetTest.main(RedisHmsetTest.java:114)
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:31)
at redis.clients.util.RedisOutputStream.write(RedisOutputStream.java:53)
at redis.clients.util.RedisOutputStream.write(RedisOutputStream.java:44)
at redis.clients.jedis.Protocol.sendCommand(Protocol.java:90)
maybe the buffer in RedisOuputStream is full, default is 8K,nor do i know the sulotion to solve it .
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import redis.clients.jedis.Jedis;
import com.google.gson.Gson;
public class RedisHmsetTest {
public static class DataModel {
private int cid = 0;
private List map = new ArrayList();
public List getMap() {
return map;
}
public void setMap(List map) {
this.map = map;
}
}
public static class TTMap {
private int tid;
private long tm;
public long getTm() {
return tm;
}
public void setTm(long tm) {
this.tm = tm;
}
public TTMap(int tid, long tm) {
this.tid = tid;
this.tm = tm;
}
}
public static void main(String[] args) throws UnsupportedEncodingException {
long pCnt = 2500000L;
int tCnt = 4;
Gson gson = new Gson();
long t1,t2,t3,t4,t5;
Map<String, String> sttg = new HashMap<String, String>((int) pCnt);
Map<Long, DataModel> rsttg = new HashMap<Long, RedisHmsetTest.DataModel>();
long tm = System.currentTimeMillis() / 1000;
t1 = System.currentTimeMillis();
for (long p=100001569758007822L; p<100001569758007822L+pCnt; p++) {
DataModel d = new DataModel();
for (int t=180000; t<180000+tCnt; t++) {
d.getMap().add(new TTMap(t, tm + t));
}
sttg.put(String.valueOf(p), gson.toJson(d, DataModel.class));
}
t2 = System.currentTimeMillis();
System.out.println(String.format("generate %d items to sttg use %d ms", pCnt, t2 - t1));
Jedis jedis = null;
try {
jedis = RedisPool.getJedis();
System.out.println(jedis.hmset("RedisHmsetTest", sttg));
t3 = System.currentTimeMillis();
System.out.println(String.format("write %d items from sttg use %d ms", sttg.size(), t3 - t2));
Map<String, String> mm = jedis.hgetAll("RedisHmsetTest");
t4 = System.currentTimeMillis();
System.out.println(String.format("read %d items from sttg use %d ms", mm.size(), t4 - t3));
for (Map.Entry<String, String> entry : mm.entrySet()) {
rsttg.put(Long.valueOf(entry.getKey()), gson.fromJson(entry.getValue(), DataModel.class));
}
t5 = System.currentTimeMillis();
System.out.println(String.format("load %d items to rsttg use %d ms", mm.size(), t5 - t4));
} catch (Exception e) {
e.printStackTrace();
} finally {
RedisPool.returnResource(jedis);
}
}
}
i used the JedisPool with the default configuration except the timeout, what is like below:
new JedisPool(config, ProcessConfig.getInstance().getProperty(«redisIp»), Integer.valueOf(ProcessConfig.getInstance().getProperty(«redisPort»)), 60 * 1000);
import java.io.IOException;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisPool {
private static JedisPool pool = null;
public static synchronized Jedis getJedis() throws NumberFormatException, IOException {
if (pool == null) {
JedisPoolConfig config = new JedisPoolConfig();
pool = new JedisPool(config, ProcessConfig.getInstance().getProperty("redisIp"), Integer.valueOf(ProcessConfig.getInstance().getProperty("redisPort")), 60 * 1000);
}
return pool.getResource();
}
public static synchronized void returnResource(Jedis jedis) {
if (jedis != null) {
pool.returnResource(jedis);
}
}
}
@marcosnils
@lquterqtd
Thanks for sharing!
Seems like you doesn’t handle connection exception while returning instance to Pool.
Did you set timeout to Redis configuration? It means that Redis will disconnect connections with idle timeout.
@HeartSaVioR @marcosnils
do you mean the timeout configuration on the server?
i used the default «timeout 0».
in the exception block i should use returnBrokenResource method?
i don’t think i need to use jedis.close() in the finally block. returnResource is just enough.
i will modify the exception block and try again.
@lquterqtd returnResource
and returnBrokenResource
are deprecated in 2.6 and 2.7. You need to use jedis.close()
in the finally block.
i used 2.6.2 and i mentioned the source code, jedis.close() is implemented:
@OverRide
public void close() {
if (dataSource != null) {
if (client.isBroken()) {
this.dataSource.returnBrokenResource(this);
} else {
this.dataSource.returnResource(this);
}
} else {
client.close();
}
}
i did not find the deprecated tag over the returnResource method.
@marcosnils thanks a lot, i read the part of the wiki.i will try later.
@lquterqtd I just run your code locally and after tuning the JVM Heap and GCOvearHeadLimit it passed without problems. I used redis 2.8.19 and Jedis 2.6.3.
It took a while to complete but I didn’t get any exception. I used a redis server with the default configuration.
Looking at your stacktrace seems like redis is closing the connections for some reason. I’d recommend setting your redis logs to «DEBUG» and see if it complains there.
Another thing to notice is that the way you’re calling hmset is not optimal in terms of memory and performance because you’re basically generating a huge stream chunk and sending all the data to redis at once. I’d recommend using pipeline and batching the inserts to reduce the memory footprint and improve the insertion times.
@antirez is there a max limit in terms of key — value pairs that hmset
can handle?. @lquterqtd is trying to hmset 5M items (keys + values) in a single redis operation and for some reason as soon as Jedis is starting to write into the socket we get a Broken pipe
exception which I’ve confirmed is redis closing the client connection.
I have checked and the query buffer limit (http://redis.io/topics/clients#query-buffer-hard-limit) is not being reached. I’ve also set the loglevel to DEBUG and I see redis disconnecting the client before getting the exception from the java side but it doesn’t say anything why it’s disconnecting it.
@antirez @lquterqtd @HeartSaVioR just reproduced it making a simple python / telnet program.
if you set the total
variable any number higher than 524287 you’ll get the Broken pipe error.
I guess this might be some redis/os limit we’re hitting. I’ve tried looking in the redis documentation but I didn’t find anything about it.
This happens with all version of Redis.
import telnetlib start = 100001569758007822 value = '{"cid":0,"map":[{"tid":180000,"tm":1431560060},{"tid":180001,"tm":1431560061},{"tid":180002,"tm":1431560062},{"tid":180003,"tm":1431560063}]}' total = 2500000 redis_total = total * 2 + 2 tn = telnetlib.Telnet("localhost", 6379) tn.write("*"+str(redis_total)+"rn$5rnHMSETrn$14rnRedisHmsetTestrn") for x in range(start, start + total ): key = str(x) tn.write("$"+str(len(key))+"rn") tn.write(key) tn.write("rn") tn.write("$"+str(len(value))+"rn") tn.write(value+"rn") print tn.read_some() tn.close()
@lquterqtd @marcosnils
This is not about connection but about limitation of multibulk size.
Redis restrict maximum size of multibulk as (1024 * 1024).
https://github.com/antirez/redis/blob/unstable/src/networking.c#L1023-1027
I could confirm this by tcpdump.
09:17:27.740553 IP localhost.53053 > localhost.6379: Flags [P.], seq 1:8191, ack 1, win 12759, options [nop,nop,TS val 404996303 ecr 404994609], length 8190
E. 2..@.@............=..0....9mX..1..'.....
.#...#.1*1048578 <---- exceed limitation
$5
HMSET
$14
RedisHmsetTest
$18
100001569758228599
$18
09:17:27.740797 IP localhost.6379 > localhost.53053: Flags [P.], seq 1:48, ack 8191, win 12503, options [nop,nop,TS val 404996303 ecr 404996303], length 47
E..cg.@.@..............=.9mX0.:...0..W.....
.#...#..-ERR Protocol error: invalid multibulk length <-- protocol error
... omitted ...
09:17:27.740865 IP localhost.6379 > localhost.53053: Flags [R], seq 238644616, win 0, length 0
E..(..@.@..............=.9m.....P....... <-- RST
So in this case, limitation of max key/value pair if 524288, (1024*1024) / 2.
I thought two action items from this
- Check multibulksize before write to output stream. Maybe
Protocol.sendCommand
is good point. - From tcpdump Redis send RESP Errors before reset connection. So in erronouse case, we can check intput stream to show reason of error.
If agreed, I’ll send PR for these.
@itugs thanks for the investigation, do you know if that is documented somewhere in the redis docs?, I couldn’t find it. @HeartSaVioR realized that if you use the «VERBOSE» logevel you can see the error in redis logs (weird that in DEBUG it doesn’t show up, @antirez is this possible?).
@itugs regarding to your propositions I believe i’d only do number 2 so if redis limitation changes in the future we don’t need to change anything from the Jedis side. What do you think?
I posted strange logging behavior to Redis repo.
@marcosnils No I could not found any docs about that. As you said I check tcpdump because I could not see any log from redis log. And even «VERBOSE» we can not see specific reason of error, like invalid multibulk length
. I think it’s better to print out specific reason to redis log, but I don’t know if this is spec.
About propositions, yes I agree with you. If number two is done, number one is not a big deal. About number 1, I wanna hear the reason of that limitation. @antirez could you tell us about the number?
@marcosnils i just read the @itugs investigation, the problem is that in server side multibulk size is limit to 1024*1024, is that right?
I will use pipeline or batch inserts to have a try.
See if your redis is running in protected mode, disable the protected mode
During a moderate load below error appears in weblogic logs : Connection reset by peer: socket write error
Environment:
They are running Weblogic in a windows 2003 ESX vmware environment.
The configuration starts with a RHEL 5.1 running apache, cluster of 6 servers with the weblogic plugin.
The plugin points to a cisco load balancer which will forward the requests to a weblogic tier servers.
The weblogic tier has a cluster of 4 servers and another 5 managed servers.
ERROR
####<Nov 26, 2011 12:52:31 PM AST> <Error> <HTTP> <TechPaste> <PRE-WL3> <ExecuteThread: '18' for queue: 'weblogic.kernel.Default'> <<WLS Kernel>> <BEA-101017> <http://ServletContext(id=24499159,name=spWeb.war,context-path=) Root cause of ServletException. javax.servlet.jsp.JspException: ServletException in:/games/confirm.jsp Input/output error: java.net.SocketException: Connection reset by peer: socket write error' at org.apache.struts.taglib.tiles.InsertTag$InsertHandler.processException(InsertTag.java:875) at org.apache.struts.taglib.tiles.InsertTag$InsertHandler.doEndTag(InsertTag.java:835) at org.apache.struts.taglib.tiles.InsertTag.doEndTag(InsertTag.java:466) at jsp_servlet._templates.__main_template._jspService(__main_template.java:655) at weblogic.servlet.jsp.JspBase.service(JspBase.java:33) at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077) at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465) at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348) at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:336) at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1058) at org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestProcessor.java:269) at org.apache.struts.tiles.TilesRequestProcessor.processTilesDefinition(TilesRequestProcessor.java:249) at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(TilesRequestProcessor.java:303) at org.apache.struts.action.RequestProcessor.processActionForward(RequestProcessor.java:401) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:279) at car.lce.plays.ui.struts.PsRequestProcessor.process(PsRequestProcessor.java:391) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1420) at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:520) at javax.servlet.http.HttpServlet.service(HttpServlet.java:760) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077) at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465) at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348) at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:7058) at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121) at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3902) at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2756) at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224) at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
Below are the logs seen in cisco load balancer probes while probing for server
Nov 27 2011 13:40:25 : %ACE-3-251010: Health probe failed for server 10.136.12.243 on port 443, graceful disconnect timeout (no FIN ACK) Nov 27 2011 13:40:55 : %ACE-3-251010: Health probe failed for server 10.136.12.243 on port 443, graceful disconnect timeout (no FIN ACK) Nov 27 2011 13:41:06 : %ACE-3-251010: Health probe failed for server 10.136.21.421 on port 443, graceful disconnect timeout (no FIN ACK) Nov 27 2011 13:41:11 : %ACE-3-251010: Health probe failed for server 10.136.12.243 on port 443, graceful disconnect timeout (no FIN ACK) Nov 27 2011 13:41:11 : %ACE-4-442002: Health probe TCP-443 detected RS-EWAPPS_PRE-WL3 (interface vlan619) in serverfarm SF_WLSAPPS-443 changed state to DOWN The server cannot write to the socket (OS level).
There are bridge errors detected by the apache web server. The user gets a strange error
Failure of server APACHE bridge: _____ No backend server available for connection: timed out after 12 seconds or idempotent set to OFF. _____
CAUSE:
As the load increased, the Cisco load balancer was configured to probe the weblogic cluster managed servers at the port.
If the response from the port 443 probe exceeded a value (number of probes and timeout) the load balancer would set the server status as down, thus getting the connection reset by peer error in the weblogic server logs and a bridge error in the apache logs / end users screen.
SOLUTION:
Turning the port probe off or setting the probe values larger would impact the users in a positive way and would not reset the connection at all or not as quickly as the case may be.
In case of any ©Copyright or missing credits issue please check CopyRights page for faster resolutions.
Error Message
When encountering a network issue, the following error is generally returned in ArcGIS Server logs.
"Unable to process request. java.net.SocketException: Connection reset by peer: socket write error"
Cause
The following are possible causes for the error:
- The error occurs when a connection is closed abruptly (when a TCP connection is reset while there is still data in the send buffer). The condition is very similar to a much more common ‘Connection reset by peer’. It can happen sporadically when connecting over the Internet, but also systematically if the timing is right (for example, with keep-alive connections on localhost).
- The Transmission Control Protocol (TCP) socket is closed because the socket received a close command from a remote database machine.
- A Reset (RST) packet is received from a remote machine and interrupts the established connection. The sent RST packets may indicate that the TCP packets sent are not recognized, a connection between the local and remote database machine is broken, or a particular port is closed and is not allowing communication.
- There is a timeout or a restart of the remote database. If there is an idle timeout or if the machine with the database is restarted, the database becomes unreachable.
Solution or Workaround
Run the ping command to determine if the remote machine is reachable.
- Navigate to Windows Start.
- Type cmd in the Search programs and files search bar.
- Click cmd from the search results.
- In the command line, type ping followed by the remote server address, and press Enter. The following is an example of a successful ping request.
Note: Even if the results are successful, there are instances where the target machine does not respond and can still return a successful ping result. The data returned can help determine if there are any communication issues between the remote machine and the local machine.
- Run the tracert command to diagnose if and where the lapse in communications is happening:
- Follow Steps 1 through 3 from above.
- For Step 4, in the command line, type tracert followed by the destination address, and press Enter. The following is an example of a successful tracert request.
Note: The tracert command is similar to the ping command; however, the tracert command displays in detail all the routes taken to establish a connection with the target machine.
- Run the telnet command to check if the ports are open on the local machine.
- Follow Steps 1 through 3 from above.
- For Step 4, in the command line, type telnet, followed by the destination address. This can be the local computer name or IP address, followed by the port number. Press Enter.
Note: If successful, the screen turns blank, indicating the port is open; however, if the port is closed, the following message is returned.
Note: The telnet feature can be enabled on a Windows machine by navigating to Windows Start > Control Panel > Programs (and Features). On the left sidebar, click Turn Windows features on or off, and ensure the Telnet Client check box is checked. Click OK.
- Run SDEINTERCEPT to diagnose ArcSDE performance and connection issues. The following technical document describes this process in detail:
HowTo: Diagnose ArcSDE connection and performance issues using SDEINTERCEPT.Note: If the cause of the issue is identified to be the database server, contact a database administrator (DBA) for further troubleshooting.
Related Information
- ArcGIS for Server: Ports used by ArcGIS Server
- ArcGIS for Server: Configuring a secure environment for ArcGIS Server
- Esri: Tracing ArcSDE Queries with SQL Profiler
- Official reasons for “Software caused connection abort: socket write error”
- StackOverflow Thread: java.net.SocketException: Software caused connection abort: recv failed
- HowTo: Diagnose ArcSDE connection and performance issues using SDEINTERCEPT
Last Published: 5/9/2019
Article ID: 000012876
Software: ArcGIS GeoEvent Server 10.3.1, 10.3 ArcGIS Image Server 10.3.1, 10.3 ArcGIS Server 10.3.1, 10.3