JedisConnectionException: java.net.SocketException: Socket closed;Unknown reply: ; It seems like server has closed the connection.解决办法
最近在使用Jedis pool的时候,写好的servlet程序一经高并发的测试,就会抛出各种Exception,像JedisConnectionException: java.net.SocketException: Socket closed;Unknown reply: ; It seems like server has closed the connection.等等。在网上查了好多资料,很多都说和Redis的timeout的默认设置有关,timeout默认设置是300s,一个redis socket连接超过这个时限,但没有对redis做任何操作的话,redis server就会主动关闭了这个连接。一种解决办法是将timeout设置为0(无限制)就行了。
由于一些因素,redis一直无法设置然后进行重启。然后我就在timeout=300s的情况下,做了各种尝试,保证既可以使用jedis pool又不会在高并发的时候出错。怪我查找资料不力,一直没有找到解决的办法,只能放弃使用连接池,每次函数调用就new一个jedis对象,然后对redis进行操作。这种方法要注意:jedis.disconnect().这种方式下,虽然在高并发的时候会对redis server造成压力,但很稳定速度也挺快的。
后来再次试图解决之前的问题的时候,发现Jedis pool 还有两个参数: TestOnBorrow,在borrow一个jedis实例时,是否提前进行validate操作,如果为true,则得到的jedis实例均是可用的;TestOnReturn,在return一个jedis实例时,是否提前进行validate操作.
设置了这两个参数以后,问题就得到解决了,做并发测试没有什么问题。
[cpp] view plain copy
- //jedis pool 设置
- public static JedisPool pool;
- static{
- JedisPoolConfig config = new JedisPoolConfig();
- config.setMaxActive(con.getIntValue("redis.maxActive", 300));
- config.setMaxIdle(con.getIntValue("redis.maxIdle", 10));
- //config.setMinIdle(10);
- config.setMaxWait(con.getLongValue("redis.maxWait", 1000L));
- config.setTestOnBorrow(true);
- config.setTestOnReturn(true);
- //config.testWhileIdle=true;
- //config.minEvictableIdleTimeMillis=30000;
- //config.timeBetweenEvictionRunsMillis=30000;
- pool = new JedisPool(config, redisaddr, redisport);
- }
- //获取jedis pool 对象
- try{
- jee= pool.getResource();
- }catch(JedisConnectionException e){
- pool.returnBrokenResource(jee);
- }
- //读取redis
- if(jee!=null){
- try{
- stationList=jee.lrange("trps:lineinfo", 0, -1);
- } catch (Exception e) {
- pool.returnBrokenResource(jee);
- } finally{
- if(null != jee){
- pool.returnResource(jee);
- }
- }
- }
from:http://blog.csdn.net/wangzaizhen2009/article/details/50592826?locationNum=13&fps=1
文:Redis : It seems like server has closed the connection
Small problem : redis.clients.jedis.exceptions.JedisConnectionException: It seems like server has closed the connection.
At first ,I Don’t have to configure redis-config # maxclients
So , Get me wrong this problem
But , redis — info
# Clients
connected_clients:2
this is a bad idea , really, when redis server send back “Protocol error” message , the server will close socket; but jedis Protocol.java just throw a JedisDataException exception and ignored tcp close segment; so if you reuse this connection, jedis will throw an exception with “It seems like server has closed the connection” message.
maxidletime default value is five minutes,the server will continue to cycle detection clinet last communication time, if more than ,close and return source.then,the client sends the data to the server and problem occurs.
final solution : config.setTestOnBorrow(true);
中文:http://www.chepoo.com/jedis-connection-exception-it-seems-like-server-has-closed-the-connection.html
看提示,应该是服务端主动关闭了连接。查看线上redis服务器的配置的timout选项:
|
该配置指的是客户端连接空闲超过多少秒后,服务端主动关闭连接,默认值0表示服务端永远不主动关闭。客户端使用了一个连接池管理访问redis的所有连接,这些连接是长连接,当业务量较小时,客户端部分连接使用率较低,当两次使用之间的间隔超过30秒时,redis服务端就主动关闭了这个连接,而等客户端下次再使用这个连接对象时,发现服务端已经关闭了连接,进而报错。
连接池setTimeBetweenEvictionRunsMillis(60000);// 失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程 每隔1分钟检查一下连接池建立的连接。
解决方案:把timeout值大于60s即可。改为300,问题解决。
+
+
+
=
=
=