赞
踩
写这篇文章前我也是谷歌百度过,可以无非都是千篇一律配置 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。