首页

解决“redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset by peer: socket write error”多线并发问题

标签:JedisConnectionException,SocketException,redis,jedis,多线程并发,ArrayIndexOutOfBoundsException,RedisOutputStream     发布时间:2017-07-30   

一、问题描述

通过多线程基于jedis客户端并发访问redis做数据更新操作报“redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset by peer: socket write error..java.lang.ArrayIndexOutOfBoundsException: 10803..”异常,详细日志如下

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset by peer: socket write error@b@	at redis.clients.jedis.Protocol.sendCommand(Protocol.java:94)@b@	at redis.clients.jedis.Protocol.sendCommand(Protocol.java:74)@b@	at redis.clients.jedis.Connection.sendCommand(Connection.java:80)@b@	at redis.clients.jedis.BinaryClient.set(BinaryClient.java:92)@b@	at redis.clients.jedis.Client.set(Client.java:24)@b@	at redis.clients.jedis.Jedis.set(Jedis.java:62)@b@	at com.xwood.publisher.util.JedisUtil.set(JedisUtil.java:66)@b@	at com.xwood.publisher.util.JedisUtil.setEncode(JedisUtil.java:48)@b@	at com.xwood.publisher.master.PublishEntityDataHandler.pushRemoteRedis(PublishEntityDataHandler.java:58)@b@	at com.xwood.publisher.master.PublishEntityDataHandler.run(PublishEntityDataHandler.java:33)@b@	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)@b@	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)@b@	at java.util.concurrent.FutureTask.run(FutureTask.java:138)@b@	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)@b@	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)@b@	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)@b@	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)@b@	at java.lang.Thread.run(Thread.java:662)@b@Caused by: java.net.SocketException: Connection reset by peer: socket write error@b@	at java.net.SocketOutputStream.socketWrite0(Native Method)@b@	at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)@b@	at java.net.SocketOutputStream.write(SocketOutputStream.java:136)@b@	at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:31)@b@	at redis.clients.util.RedisOutputStream.write(RedisOutputStream.java:38)@b@	at redis.clients.jedis.Protocol.sendCommand(Protocol.java:80)@b@	... 17 more@b@@b@java.lang.ArrayIndexOutOfBoundsException: 10803@b@	at redis.clients.util.RedisOutputStream.write(RedisOutputStream.java:40)@b@	at redis.clients.jedis.Protocol.sendCommand(Protocol.java:80)@b@	at redis.clients.jedis.Protocol.sendCommand(Protocol.java:74)@b@	at redis.clients.jedis.Connection.sendCommand(Connection.java:80)@b@	at redis.clients.jedis.BinaryClient.set(BinaryClient.java:92)@b@	at redis.clients.jedis.Client.set(Client.java:24)@b@	at redis.clients.jedis.Jedis.set(Jedis.java:62)@b@	at com.xwood.publisher.util.JedisUtil.set(JedisUtil.java:66)@b@	at com.xwood.publisher.util.JedisUtil.setEncode(JedisUtil.java:48)@b@	at com.xwood.publisher.master.PublishEntityDataHandler.pushRemoteRedis(PublishEntityDataHandler.java:58)@b@	at com.xwood.publisher.master.PublishEntityDataHandler.run(PublishEntityDataHandler.java:33)@b@	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)@b@	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)@b@	at java.util.concurrent.FutureTask.run(FutureTask.java:138)@b@	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)@b@	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)@b@	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)@b@	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)@b@	at java.lang.Thread.run(Thread.java:662)

二、解决方法

1. 方法一:基于jedisPipeline,具体用法示例参考其他更多文章页

2. 方法二:将原有的异步多线程池处理改为主线程处理,在在性能上区别不大,具体修改对比如下

原来的代码如下

for(Map m:datas){@b@ 	 waiting_ha_entitys.add(new PublishEntityDataHandler(ha_entity,ii));@b@}@b@ @b@ //多线程优化处理,降低数据库延时@b@ while(waiting_ha_entitys.remainingCapacity()>0){ @b@	 if(waiting_ha_entitys.size()==0)  @b@		 break;@b@				 @b@	 f(SlaveProcesserHandler.getExecutor()!=null)@b@	    SlaveProcesserHandler.getExecutor().execute(waiting_ha_entitys.poll());  @b@	 } @b@ }

修改为

for(Map m:datas){@b@      waiting_ha_entitys.add(new PublishEntityDataHandler(ha_entity,ii,jpl));@b@      new PublishEntityDataHandler(ha_entity,ii).run(); //将PublishEntityDataHandler去掉Runable接口@b@}