记录一次排查jedis连接失败的问题

 

事件背景:这次不是直接使用jedis集成,而是按要求集成公司封装的工具包,配置项也是自定义的。

 

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    at redis.clients.jedis.util.Pool.getResource(Pool.java:84)
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:370)
    ......此处略过几十行
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Failed to create socket.
    at redis.clients.jedis.DefaultJedisSocketFactory.createSocket(DefaultJedisSocketFactory.java:110)
    at redis.clients.jedis.Connection.connect(Connection.java:226)
    at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:140)
    at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:310)
    at redis.clients.jedis.BinaryJedis.initializeFromClientConfig(BinaryJedis.java:88)
    at redis.clients.jedis.BinaryJedis.<init>(BinaryJedis.java:293)
    at redis.clients.jedis.Jedis.<init>(Jedis.java:169)
    at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:177)
    at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:918)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:431)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:356)
    at redis.clients.jedis.util.Pool.getResource(Pool.java:75)
    ... 72 more
Caused by: java.net.SocketTimeoutException: connect timed out
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at redis.clients.jedis.DefaultJedisSocketFactory.createSocket(DefaultJedisSocketFactory.java:80)
    ... 83 more

 

第一个问题:Could not get a resource from the pool

  这个问题的原因无法就这几种:

  1. 参数问题,有可能是连接池太小引起

  2. jedis版本问题引起

  3.服务器性能引起

  初步判断是Redis连接数不够用,调大了里连接参数

                  maxActive: 1000
                  maxTotal: 100
                  maxIdle: 100
                  minIdle: 50

  重启项目后发现问题依然存在,翻找源码,加断点看一下 JedisPool 里到底加载了什么。

  这不是初始值么,我的参数根本没起作用,又翻找加载 JedisPool 的过程源码,才发现,配置文件少了一级。原来是 **.**.pool.maxActive=20 这样的配置路径。

  配置文件修改好之后,jedisPool  可以正常加载我设置的参数了,但问题依然存在。那就只能从第二个提示入手了。

 

第二个问题:Failed to create socket.

  这个提示很好排查,就是验证你的Redis是否可以连接上。用连接工具、程序都可以尝试验证,网上有多排查此原因的方式,都是因为Redis服务器端配置的问题。

  写个验证程序:

    public static void main(String[] args) {
        Jedis jedis = new Jedis("服务器的IP", 端口号);
        System.out.println(jedis.ping());
    }

  第一次执行的报了异常:

Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException: Failed to create socket.
    at redis.clients.jedis.DefaultJedisSocketFactory.createSocket(DefaultJedisSocketFactory.java:110)
    at redis.clients.jedis.Connection.connect(Connection.java:226)
    at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:140)
    at redis.clients.jedis.Connection.sendCommand(Connection.java:163)
    at redis.clients.jedis.Connection.sendCommand(Connection.java:158)
    at redis.clients.jedis.BinaryClient.ping(BinaryClient.java:191)
    at redis.clients.jedis.BinaryJedis.ping(BinaryJedis.java:379)
    at com.gientech.core.core.account.Test.main(Test.java:9)
Caused by: java.net.SocketTimeoutException: connect timed out
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at redis.clients.jedis.DefaultJedisSocketFactory.createSocket(DefaultJedisSocketFactory.java:80)
    ... 7 more

  这就真尴尬了,再核对服务器资源文档上的Redis信息,原来服务器IP和端口是不能直接用的。需要用外网映射IP和端口。改完之后连接正常。

 

posted @ 2022-12-02 11:31  闲人鹤  阅读(1055)  评论(0编辑  收藏  举报