解决io.lettuce.core.RedisCommandTimeoutException: Command timed out, mysql 访问15分钟阻塞等待

写这篇文章前我也是谷歌百度过,可以无非都是千篇一律配置 timeout 或者  lettuce的连接池,可是更改完这些配置,问题依旧,于是开始了自我探索之路,请出Wireshark大杀器,每当动用Wireshark时,我都知道我摊上大事了,文章是两个问题一个redis,一个mysql,但是都是一个原因造成的,所以写在了一起

一:redis超时

1.出现问题的现象是每隔5,6分钟(这个时间是反复观察测试出来结果),redis访问就会报lettuce超时错误,下一次重新访问就好了,所以从这个为突破点,本地用Wireshark监控发往服务器的数据包,

很明显服务器连接有问题,于是在服务器多次运行netstat -an |grep 6379命令,并没有发现服务器发现tcp主动关闭连接(没有time_wait标识),再次多次运行netstat -an |grep 本地连接redis端口,发现一会儿连接就突然没了,不符合逻辑,通过用tcpdump抓服务器的数据包,也没有发现明显的问题,那么连接到底怎么没的?

第二天早上想会不会是服务器自身问题,于是开始搜索 蓝云Azure  tcp断开问题,还真找到了

https://docs.microsoft.com/zh-cn/azure/load-balancer/load-balancer-tcp-reset,原来是这个原因

解决方法:

第一种:redis,mysql 配置文件写成服务器的内网ip即可,不走他的网关,缺点就是本地开发没办法用

第二种

lettuce换成jredis,因为通过用Wireshark发现jredis默认是发心跳包的,而lettuce是不发心跳包的,所以能骗过蓝云的网关,更改如下

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </exclusion>
        <exclusion>
            <artifactId>lettuce-core</artifactId>
            <groupId>io.lettuce</groupId>
        </exclusion>
    </exclusions>
</dependency>
<!-- jedis客户端 -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
<!-- spring2.X集成redis所需common-pool2,使用jedis必须依赖它-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

第三种:

自己写个定时器轮询访问redis,模拟一下心跳,其实这个方法也没什么不好,只是需要自己写代码

二:mysql 查询网关超时

同一个接口中redis问题解决了,又发现mysql有时访问一直阻塞,导致zulll网关超时,于是打印日志监控执行时间,发现mysql查询需要15分钟,并且没有报错,推测本质上应该也是这个tcp被意外断开了,由于项目只是使用了阿里的druid连接池,并没有进行配置,于是先尝试配置一下连接池,发现问题完美解决偶尔15分钟查询阻塞问题,以下是druid的配置

##### druid配置
#连接池配置(通常来说,只需要修改initialSize、minIdle、maxActive
spring.datasource.druid.initial-size=10
spring.datasource.druid.max-active=100
spring.datasource.druid.min-idle=50
# 配置获取连接等待超时的时间
spring.datasource.druid.max-wait=60000
#打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
spring.datasource.druid.validation-query=SELECT 'x'
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.validation-query-timeout=5000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.druid.time-between-eviction-runs-millis=60000
#配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.druid.min-evictable-idle-time-millis=300000
spring.datasource.druid.filters=stat,wall
# WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter
#是否启用StatFilter默认值true
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions="*.js , *.gif ,*.jpg ,*.png ,*.css ,*.ico , /druid/*"
spring.datasource.druid.web-stat-filter.session-stat-max-count=1000
spring.datasource.druid.web-stat-filter.profile-enable=true
spring.datasource.druid.web-stat-filter.session-stat-enable=false
# StatViewServlet配置
#展示Druid的统计信息,StatViewServlet的用途包括:1.提供监控信息展示的html页面2.提供监控信息的JSON API
#是否启用StatViewServlet默认值true
spring.datasource.druid.stat-view-servlet.enabled=false
#根据配置中的url-pattern来访问内置监控页面,如果是上面的配置,内置监控页面的首页是/druid/index.html例如:http://127.0.0.1:9000/druid/index.html
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
#允许清空统计数据
spring.datasource.druid.stat-view-servlet.reset-enable=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin

猜你喜欢

转载自blog.csdn.net/zw521cx/article/details/101212549