• Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out


    问题:
    java连接不上redis。

    异常信息:
    Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out

    package com.redis;
    
    import redis.clients.jedis.Jedis;
    
    public class HelloRedis {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Jedis jedis = new Jedis("192.168.144.130", 6379);
    		jedis.set("java", "http://www.baidu.com");
    		String value = jedis.get("java");
    		System.out.println(value);
    
    	}
    
    }
    

     当 我们获取连接后对redis进行操作时,抛出 redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out异常。

    异常代码如下:

    redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out

    at redis.clients.jedis.Protocol.process(Protocol.java:79)
    at redis.clients.jedis.Protocol.read(Protocol.java:131)
    at redis.clients.jedis.Connection.getIntegerReply(Connection.java:188)
    at redis.clients.jedis.Jedis.sismember(Jedis.java:1266)

    这是一个比较麻烦的异常,困扰了我一天的时间。我们都知道Redis是对内存进行操作,速度应该都在毫秒级,这是我们通常的认识,所以当对Redis操作出现几秒的超时时间,你能想象吗?
    我们还是先分析一下Jedis的源代码吧,以sadd操作为例:

    1. public Long sadd(final String key, final String... members) {
    2. checkIsInMulti();
    3. client.sadd(key, members);
    4. return client.getIntegerReply();
    5. }

    client是redis.clients.jedis.Client.java的实例,继承关系如下:
    public class Client extends BinaryClient implements Commands;

    public class BinaryClient extends Connection;

    Connection 包装了对Redis server的socket操作,命令写操作通过socket.getOutputStream()输出流将命令信息发送到redis server,当写完命令后要通过socket.getInputStream()的到的输入流将
    命令执行结果返回,这中间必然会有一个命令执行到结果返回的延时时间,这就是一个Jedis调用redis命令操作所用的时间。

    需要说明的是,Redis server是单线程执行所有连接发送过来的命令的,也就是说不管并发中有多少个client在发送命令,redis-server端是单线程处理的,并按照默认的FIFO方式处理请求,

    这个可在redis.conf配置文件中配置。关于redis server的详细运行机制参见:http://redis.io/documentation

    所 以client.sadd(key, members);调用完后只是将命令信息发送到了redis server端,具体有没有执行要看redis server的负载情况。然后,通过client.getIntegerReply();等待(time out)返回结果。
    Connection初始化socket时有多种选择,其中设置socket time out 的方法如下:

    1. public void rollbackTimeout() {
    2.           try {
    3.             socket.setSoTimeout(timeout);
    4.             socket.setKeepAlive(false);
    5.           } catch (SocketException ex) {
    6.             throw new JedisException(ex);
    7.           }
    8.       }

    由redis.clients.jedis.Protocol.DEFAULT_TIMEOUT = 2000 我们知道默认的超时时间是2秒,这个时间相对于redis操作内存毫秒级的速度来说已经很长,那我们为什么还会遇到
    ava.net.SocketTimeoutException: Read timed out异常呢?redis操作内存虽然平均毫秒级的,但当数据量很大时未必都如此快速。在我的开发过程中就遇到过一个集合到了

    千万级数据量,一次操作超时时间在秒级是很正常的,而且机器性能很好的情况下已经如此,更何况我们本机开发的机器相对于生产服务器来说速度会更慢了。所以在初始化JedisPool时应该根据实际

    情况通过redis.clients.jedis.JedisPoolConfig合理设置连接池参数,通过edisPool构造方法,合理设置socket读取输入InputStream的超时时间。

     

    1. pool = new JedisPool(config, host, port, 100000);

     

    注意第四个参数time out,设置成我们能容忍的超时时间,单位是毫秒。但不知道为什么既然单位是毫秒,为什么参数类型是int而不是long。

    设置第四个参数后,我在四千万数据量集合上操作最多一次大概超时5秒,问题基本解决。

  • 相关阅读:
    怎样克服 JavaScript 框架疲劳?
    jQuery 简单归纳总结
    锋利的JQuery —— 事件和动画
    锋利的JQuery —— DOM操作
    锋利的JQuery —— 选择器
    Maven日常 —— 你应该知道的一二三
    《时间简史》—— 读后总结
    Elasticsearch之_default_—— 为索引添加默认映射
    Elasticsearch 动态映射——自动检测
    安装了Node.js 从VScode 使用node -v 和 npm -v等命令却无效
  • 原文地址:https://www.cnblogs.com/interdrp/p/7856177.html
Copyright © 2020-2023  润新知