美文网首页java
jmeter压测发现redis无法获取到连接

jmeter压测发现redis无法获取到连接

作者: Java分布式架构实战 | 来源:发表于2019-05-21 09:34 被阅读1次

    最近使用jmeter压测了一下网站首页,发现流量上来之后,过了一会,整个网站就不能打开了,白页。然后就登录sentry日志平台查看异常,发现有几千个jedis相关的异常

    异常信息:获取不到redis链接

    Spring Boot版本:2.0.8.RELEASE

    jedis: 2.9.0

    commons-pool2: 2.2

    [http-nio-8017-exec-515] - get异常
    org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool
        at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:286)
    Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
    

    jstack

    然后就尝试使用jstack抓一下JVM线程堆栈,看看JVM在忙什么。ssh远程登录到服务器,然后使用jps -l来查看java进程,定位到进程pid

    [root@xxxbt02 current]# jstack 15782 > ec-04.txt
    

    通过观察jstack发现有很多业务线程接近200个在超时等待redis连接。顺便抓一下内存dump文件。

    jmap

    [root@xxxbt02 current]# jmap -dump:format=b,file=ec-jmap-01.hprof 15782
    Dumping heap to /opt/xxx/xxx-order-api/current/ec-jmap-01.hprof ...
    Heap dump file created
    [root@xxxbt02 current]# 
    
    

    结论

    通过分析jstack堆栈发现,大量线程在尝试获取redis连接,因为配置了最大等待时间2s, 在2s后获取不到连接,导致抛出异常RedisConnectionFailureException。然后线程任务结束。这就证明在2s内已始终获取不到redis连接。由于程序没有兜底方案,所以整个JVM中的服务不可用。应该是redis连接池中始终无可用连接。那应该就是默认的8个连接全部被占用了,没有被释放。最后通过Jedis GitHub源码库也验证了这个问题。原文地址:JedisPool exhausted in Jedis 2.10.0,根据异常表现,线程堆栈及相关源码,确实验证了这一点:连接池中的8个连接被耗尽了,没有返还到池中。所以后来的线程任务一直拿不到redis连接。接着将jedis版本升级到2.10.2,再次测试发现问题修复了。后来也督促项目组对相关代码做了优化,减少redis访问次数,增加兜底方案,增加guava本地缓存,同时将jedis换成lettuce。

    参考资料

    关注公众号交流学习

    关注Java分布式架构实战, 持续精进 联系我,学习交流

    相关文章

      网友评论

        本文标题:jmeter压测发现redis无法获取到连接

        本文链接:https://www.haomeiwen.com/subject/aczkzqtx.html