记录一次并发情况下的redis导致服务假死的问题
问题描述
最近项目在做性能压测,框架使用的是 spring boot 2.1.2 + jedis 2.9.1,80个并发持续压测4-5分钟服务就假死,所有的请求就pending,查看服务日志没有任何异常,查看其它没有使用redis的接口都能正常请求。
查找问题思路
查看了一下redis的连接配置,都是正常够用的
再使用jstack看一下堆栈信息
发现很多WAITING的线程,再往下看都是redis的getResource方法导致的等待。
查看redis的源码
Jedis.java
@Override public void close() {if (dataSource != null) {//1if (client.isBroken()) {this.dataSource.returnBrokenResource(this);} else {this.dataSource.returnResource(this); // 2}this.dataSource = null; // 3} else {super.close();} }
分析一下这个代码,
client.isBroken()
这里默认值是false,连接释放的时候先释放resource 然后再将dataSource置为null,那如果是并发的情况下话,那有可能再下一个线程进来的时候dataSource已经就是null了,在执行第2步的时候dataSource刚好被置为null,那这个时候就无法释放连接了。这个时候我们再看下获取连接的方法。JedisSentinelPool.java
@Override public Jedis getResource() {while (true) {Jedis jedis = super.getResource();jedis.setDataSource(this); // <-- This line // get a reference because it can change concurrentlyfinal HostAndPort master = currentHostMaster;final HostAndPort connection = new HostAndPort(jedis.getClient().getHost(), jedis.getClient().getPort());if (master.equals(connection)) {// connected to the correct masterreturn jedis;} else {returnBrokenResource(jedis);}} }
这里
jedis.setDataSource(this);
设置的则为null。
问题解决方案
我查看了一下jedis的github,在issue上有找到有人曾经提出过这样的问题,https://github.com/redis/jedis/issues/1920
,给出的解决方案是升级jedis的jar包到2.10.2版本以上,换成高版本的以后问题果然就解决了。
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.10.2</version>
</dependency>
这里要注意一下的是jedis的版本跟spring-data-redis的版本是有一个对应关系的。
spring-data-redis 2.1.x 对应的jedis版本是2.x.x 版本
spring-data-redis 2.2.x 对应的jedis 版本就是3.x版本了
分析升级版本以后的改动
还是看那两个类,看看新版本做了什么改动
public void close() {if (this.dataSource != null) {Pool<Jedis> pool = this.dataSource;this.dataSource = null;if (this.client.isBroken()) {pool.returnBrokenResource(this);} else {pool.returnResource(this);}} else {super.close();}}
这里很明显的处理方式就是讲dataSource复制给pool,然后用pool去释放资源,这个时候设置dataSource与这个就没有关系了,就不存在释放资源释放不了的情况了。
}
这里很明显的处理方式就是讲dataSource复制给pool,然后用pool去释放资源,这个时候设置dataSource与这个就没有关系了,就不存在释放资源释放不了的情况了。
记录一次并发情况下的redis导致服务假死的问题相关推荐
- 淘宝从百个并发到千万级并发情况下架构的十四次演进
1.概述 本文以淘宝作为例子,介绍从一百个并发到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则. ...
- 在高并发情况下如何解决用户超领优惠券问题
在高并发情况下如何解决单用户超领优惠券问题 一. 场景描述 在近期的项目里面有一个功能是领取优惠券的功能,每一个优惠券一共发行多少张,每个用户可以领取多少张: 如:A优惠券一共发行120张,每一个用户 ...
- 秒杀系统并发情况下解决超卖问题
非分布式秒杀系统 并发情况下解决超卖问题 乐观锁防止超卖 / 令牌桶限流/ redis缓存 /接口限流/接口加盐/单用户限制访问频率/消息队列异步处理订单 #数据库表drop table if exi ...
- php通过标识加锁,PHP通过加锁实现并发情况下抢码功能
基于php语言使用加锁实现并发情况下抢码功能,特定时间段开放抢码并不允许开放的码重复: 需求:抢码功能 要求: 1.特定时间段才开放抢码: 2.每个时间段放开的码是有限的: 3.每个码不允许重复: 实 ...
- mysql update 负数_解决并发情况下库存减为负数问题--update2016.04.24
场景: 一个商品有库存,下单时先检查库存,如果>0,把库存-1然后下单,如果<=0,则不能下单,事务包含两条sql语句: select quantity from products WHE ...
- php mysql 库存变负数_解决并发情况下库存减为负数问题
场景: 一个商品有库存,下单时先检查库存,如果>0,把库存-1然后下单,如果<=0,则不能下单,事务包含两条sql语句: select quantity from products WHE ...
- mysql 并发避免锁表_Yii+MYSQL锁表防止并发情况下重复数据的方法
本文实例讲述了Yii+MYSQL锁表防止并发情况下重复数据的方法.分享给大家供大家参考,具体如下: lock table 读锁定 如果一个线程获得在一个表上的read锁,那么该线程和所有其他线程只能从 ...
- 高并发情况下修改系统参数
单进程最大打开文件数限制 一般的发行版,限制单进程最大可以打开1024个文件,这是远远不能满足高并发需求的,调整过程如下: 在#号提示符下敲入: ulimit–n 65535 限制修改失败了,会显示 ...
- hashmap扩容_面试官问:HashMap在并发情况下为什么造成死循环?一脸懵
这个问题是在面试时常问的几个问题,一般在问这个问题之前会问Hashmap和HashTable的区别?面试者一般会回答:hashtable是线程安全的,hashmap是线程不安全的. 那么面试官就会紧接 ...
最新文章
- 论文Very Deep Convolutional Networks for Large-Scale Image Recognition
- 天坑的:Fatal Python error: init_sys_streams: can‘t initialize sys standard streams解决方案
- 轻轻松松明白什么是反射,反射有什么用,简单上手反射以及反射的优缺点
- 免费注册丨全国社会媒体处理大会(SMP 2020)召开,98场报告日程全公开
- 字节跳动---万万没想到之抓捕孔连顺
- Chrome开发者工具使用console.trace的一个小技巧
- github设置仓库可见性 私人仓库设置
- 改善Java应用程序性能的快速技巧
- redis key设计技巧
- asp.net中,%#%,%=%和%%分别是什么意思,有什么区别
- Spark 之 解决数据倾斜(一)
- ITPUB那些事儿——写在pub十周年之际
- 参数是html代码,一些html标签的参数messup html/php代码
- Cisco路由器上传和下载IOS
- G.Power教程 | 样本量估计
- Proxmark3教程1:用PM3解密复制M1全加密门禁IC卡图文详细介绍
- IDEA从零到精通(34)之IDEA 强大的文件对比功能
- 重磅!《中华人民共和国个人信息保护法》今日起施行!
- RK3399 opencv rtsp流报错drm prime is not supported as input pixel format
- 求两个数的最小公倍数及多个数的最小公倍数的求法
热门文章
- vim 写文档 (自身功能tags, txt2tags生成网页pdf等)
- Oracle DataGuard介绍
- python元组可以排序吗,关于python:如何对列表/元组进行排序(list/tuple)?
- 高效的公式提取神器Mathpix snipping Tool+ Mathtype
- css中“~”(波浪号)、“,”(逗号)、 “ + ”(加号)和 “ ”(大于号)是什么意思?
- ubuntu 安装软件 tar.gz deb
- Unity3D 创建一个简单的2D游戏
- 这4个资源搜索网站,你可能还不知道,但非常的实用
- Android之TextView
- 以下html标记语言表示网页标题的标记是,第8章 HTML标记语言.ppt