工作笔记-记一次Jedis连接泄露的问题及解决过程

2023-11-13

问题追踪

我使用的Jedis版本是2.9.0,通过连接池访问,在做压力测试时,发现在高并发环境下,连接泄露,连接池内的连接未能正常返还,导致"could not get resource fron pool". 

看使用代码:

	public void execute(RedisAction callback) {
		Jedis jedis = jedisPool.getResource();

		if (jedis == null) {
			throw new RuntimeException("fetch jedis connection failed ");
		}
		try {
			callback.doInRedis(jedis);
		} finally {
			jedis.close();
		}
	}

使用规范的try-finally方式,使用完毕后归还jedis连接,但是连接仍然泄露,在平稳运行一段时间后应用越来越慢,最后无法获取连接。

我推测是在Jedis归还过程中,由于高并发而导致的连接池泄露,看源码:

  @Override
  public void close() {
    if (dataSource != null) {
      if (client.isBroken()) {
        this.dataSource.returnBrokenResource(this);
      } else {
        this.dataSource.returnResource(this);
      }
      this.dataSource = null;
    } else {
      super.close();
    }
  }

发现:在jedis.close()的过程中,先将jedis归还(this.dataSource.returnResource(this)),再将dataSource设置为null. 问题就在这里了!

在高并发情况下,jedis被归还后的一瞬间即可能被其他线程借去,此时,上一次的close还没有完全执行完,在此时再执行下面的this.dataSource = null 这句,会导致下一个borrow到jedis连接的线程再也无法将连接归还给连接池,而只能走到super.close()将连接关闭。

解决方式

1. 翻github看到官方已经记录并且在2.10.2版本修复了这个问题, 只要将jedis版本升级到2.10.2以上就可以解决这个问题了,附上2.10.2的jedis.close()源码:

  @Override
  public void close() {
    if (dataSource != null) {
      Pool<Jedis]]> pool = this.dataSource;
      this.dataSource = null;
      if (client.isBroken()) {
        pool.returnBrokenResource(this);
      } else {
        pool.returnResource(this);
      }
    } else {
      super.close();
    }
  }

先设置dataSource为null,再归还Jedis连接, 就不会再有连接泄露了。

2. 某些情况下,可能无法直接这么简单地做jedis版本替换。

我一直有一个疑惑,那就是spring boot 2.1.x其实默认依赖的都是jedis2.9.x的版本,为什么使用springboot的时候不会出现jedis连接泄露呢?

我尝试看了spring-data-redis的源码,并没有找到什么特别的处理,工作时间太紧张,没时间追究,只得自己动手fix,当使用2.9.x版本的jedis时,避免连接泄露,在返还连接的时候,这么写:

	@SuppressWarnings("deprecation")
	public void closeJedis(Jedis jedis) {
		if (null != jedis) {
			if (jedisPool != null) {
				jedis.setDataSource(null);
				if (jedis.getClient().isBroken()) {
					jedisPool.returnBrokenResource(jedis);
				} else {
					jedisPool.returnResource(jedis);
				}
			} else {
				jedis.getClient().close();
			}
		}
	}

经过测试可解决问题。

关于spring到底做了什么解决了2.9.x版本的这个问题,有谁知道可以告诉我?网上真的查不到,自己看也看不出。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

工作笔记-记一次Jedis连接泄露的问题及解决过程 的相关文章

  • 如何从 python 将无穷大传递给 redis?

    我正在使用 redis py 并希望将 inf 和 inf 与 ZRANGEBYSCORE 一起使用 我尝试使用 inf 的字符串和浮点来执行此操作 但它们返回一个空集 我怎样才能做到这一点 EDIT 我尝试执行以下命令 redis Str
  • Spring RedisTemplate:8次调用后方法键挂起

    我使用 Spring RedisTemplate spring data redis 1 7 1 与 Redis 进行通信 我需要通过正则表达式获取然后删除键 例如 context user1 我用的方法 RedisTemplate key
  • Node.js 上通过套接字连接 Redis

    由于共享托管 目标主机上的我的 redis 服务器不在端口上运行 而是在非常特定的套接字上运行 可以通过套接字文件连接到该套接字 只有我的用户可以访问 但是 我还没有找到如何通过套接字指定连接node redis and connect r
  • python 3.5 中的 json.loads 和 Redis

    我使用 json dumps 创建了一个 JSON 对象 并在 Redis 列表中将其 RPUSH ed 当使用 LRANGE redis lrange 返回 JSON 时 我收到一个二进制字符串 b si 00 ff 所以 json lo
  • 使用 AWS ElastiCache 请求中的 Airflow CROSSSLOT 密钥未散列到同一插槽错误

    我在 AWS ECS 上运行 apache airflow 1 8 1 并且有一个 AWS ElastiCache 集群 redis 3 2 4 运行 2 个分片 2 个启用多可用区的节点 集群 Redis 引擎 我已经验证气流可以毫无问题
  • 我的 Redis 自动生成的密钥

    我不知道我的 Redis 版本 4 0 9 到底发生了什么 我正在运行一个应用程序并使用 Redis 来存储我的数据库 但是 然后 Redis 自动创建 3 个新键 Backup1 Backup2 Backup3 并删除我的所有数据 这是我
  • redis集群不断打印日志WSA_IO_PENDING

    当我启动redis集群的所有redis服务器时 所有这些服务器不断打印类似WSA IO PENDING clusterWriteDone的日志 9956 03 Feb 18 17 25 044 WSA IO PENDING writing
  • Redis键空间事件不触发

    我有两个 Redis 客户端 在一个文件中我有一个简单的脚本设置并删除了 Redis 键 var redis require redis var client redis createClient 6379 127 0 0 1 client
  • Redis 排序集和解决关系

    我正在使用 Redis 排序集来存储我正在处理的项目的排名 我们没有预料到 我们想要如何处理关系 Redis 按字典顺序对具有相同分数的条目进行排序 但我们想要做的是对具有相同分数的所有条目给予相同的排名 例如在以下情况 redis 127
  • Spring Data Redis JedisConnectionException:流意外结束

    雷迪斯3 0 5Spring数据Redis 1 3 6绝地武士2 6 3 我们的 Web 应用程序通过 pub sub 从 Redis 接收数据 还以键 值对的形式在 Redis 上执行数据读 写 读 写发生在监听线程 独立监控线程和htt
  • 从redis中检索大数据集

    一台服务器上的应用程序查询另一台服务器上运行的 Redis 查询的结果数据集约为 250kzrangebyscore objects locations inf inf这在应用程序服务器上似乎需要 40 秒 当使用命令执行时redis cl
  • 如何测试我的 Redis 缓存是否正常工作?

    我已经安装了 django redis cache 和 redis py 我遵循了 Django 的缓存文档 据我所知 以下设置就是我所需要的 但我如何判断它是否正常工作 设置 py CACHES default BACKEND redis
  • 使用Redis从有限范围内生成唯一ID

    我有一些数据库项目 除了主键之外 还需要项目所属组的唯一索引 我们来调用属性nbr 以及将项目分组在一起并定义唯一范围的属性nbr 我们会打电话group This nbr必须在 1 N 范围内 并且may从外部源导入项目时进行设置 由于所
  • socket.io 广播功能 & Redis pub/sub 架构

    如果有人能帮助我解决一个小疑问 我将不胜感激 使用socket io广播功能和在Redis上使用pub sub设计架构有什么区别 例如 在另一个示例中 node js 服务器正在侦听 socket io 针对 键 模型 todo 和值 数据
  • Redis、会话过期和反向查找

    我目前正在构建一个网络应用程序 并想使用 Redis 来存储会话 登录时 会话会使用相应的用户 ID 插入到 Redis 中 并且过期时间设置为 15 分钟 我现在想实现会话的反向查找 获取具有特定用户 ID 的会话 这里的问题是 由于我无
  • 如何使redis中的“HSET”子键“过期”?

    我需要使 Redis 哈希中所有超过 1 个月的密钥过期 这不可能 https github com antirez redis issues 167 issuecomment 2559040 为了保持 Redis 简单 https git
  • StackExchange.Redis Get 函数抛出 TimeoutException

    我在用着StackExchange Redis与 C 和StackExchangeRedisCacheClient Get函数抛出以下异常 myCacheClient Database StringGet txtKey Text myCac
  • redis 2.8.7 Linux Sentinel环境配置问题,如何使其自启动,应该订阅什么?

    现在我们尝试使用 redis 2 8 7 作为缓存存储 来自使用 booksleeve 客户端的 NET Web 应用程序 目前看来这是一个非常有趣和令人兴奋的任务 redis 文档非常好 但由于缺乏真正的实践经验 我确实有几个关于如何正确
  • Redis 队列工作程序在 utcparse 中崩溃

    我正在尝试按照以下教程获得基本的 rq 工作 https blog miguelgrinberg com post the flask mega tutorial part xxii background jobs https blog m
  • docker-compose:容器之间的 Redis 连接被拒绝

    我正在尝试设置一个 docker compose 文件 该文件旨在替换运行多个进程 RQ 工作线程 RQ 仪表板和 Flask 应用程序 的单个 Docker 容器解决方案导师 http supervisord org 主机系统是 Debi

随机推荐

  • Spring Boot + Vue的网上商城之登陆认证

    Spring Boot Vue的网上商城之登陆认证 本篇博客介绍了如何使用Spring Boot和Vue来实现网上商城的登陆认证功能 下面是本文的主要内容总结 后端实现 创建Spring Boot项目 并添加Spring Security和
  • 为什么spring单例模式可以支持多线程并发访问

    为什么spring单例模式可以支持多线程并发访问 1 spring单例模式是指 在内存中只实例化一个类的对象 2 类的变量有线程安全的问题 就是有get和set方法的类成员属性 执行单例对象的方法不会有线程安全的问题 因为方法是磁盘上的一段
  • Vulnhub靶机-BLACKLIGHT

    项目地址 http download vulnhub com blacklight BLACKLIGHT ova 靶机渗透 网络选择桥接模式 使用命令 arp scan l nmap 192 168 0 130 使用dirb遍历网站目录结构
  • Linux自学笔记

    Linux自学笔记 06 常用命令 文件目录类 Linux自学笔记 01 文件系统和目录结构 Linux自学笔记 02 VIM编辑器的安装与使用 Linux自学笔记 03 Linux网络配置 Linux自学笔记 04 远程登录 Linux自
  • 高速模数转换器(ADC)的INL/DNL测量

    摘要 尽管积分非线性和微分非线性不是高速 高动态性能数据转换器最重要的参数 但在高分辨率成像应用中却具有重要意义 本文简要回顾了这两个参数的定义 并给出了两种不同但常用的测量高速模数转换器 ADC 的INL DNL的方法 近期 许多厂商推出
  • 微信小程序 ---- 【invalid credential, access_token is invalid】

    报错返回 errcode 40001 errmsg invalid credential access token is invalid or not latest rid 6004f3da 1529ba72 5c345f67 报错原因 a
  • oled拼接屏有哪些安装方法?

    嘉峪关是一个历史悠久的城市 也是一个旅游胜地 为了更好地展示城市的文化和旅游资源 嘉峪关市政府决定在市区的重要场所安装oled拼接屏 oled拼接屏是一种高清晰度的显示屏 具有高亮度 高对比度 高色彩饱和度等优点 它可以将图像和视频以更清晰
  • qtp的基本使用方法(1)

    1 action qtp为每一个action生成相应的测试文件和目录 对象库也是和action绑定的 用action 来划分和组织测试流程 编辑action 修改action的名字 action properties 增加action in
  • StartSSL CA证书签名 和 Tomcat Https访问 全过程说明

    第1章 准备工作 IP地址 外网服务器的IP 如X X 47 xx 作用 1 解析域名 2 部署Tomcat7 域 名 将域名 如samuscasting cn 解析 映射到外网IP 注 1 记住购买域名所使用的邮箱 原因 认证机构对域名做
  • QGIS编译(跨平台编译)之五十一:MacOS环境下安装Python、pyqt5、pyqt5-tools等

    目录 1 安装背景 2 卸载Python 3 下载Python3 9 4 安装Python3 9 5 安装pyqt5 6 安装pyqt5 tools
  • 微信小程序 分享图片大小处理

    1 在分享的page 添加 canvas 标签
  • c++单链表的创建、输出、插入、删除操作

    混子来了 单链表的创建 首先单链表的定义就不再赘述了 本文利用带头节点 尾插法的方法进行创建 同时注意头节点在此的重要性 即所有操作都要通过头节点来实现 头节点的值绝对不能被改变 结点的定义 struct ListNode 定义节点 int
  • 最小的前端开发框架 Vanilla JS

    刚刚在看前端文章的时候看到了Vanilla JS 这是什么高端框架 打开了谷鸽google搜索 果然是发现了不得了的技术 VanillaJS是库 框架免费javascript的术语 它有时具有讽刺意味地被称为库 这是为那些可能会盲目使用不同
  • HTML5 Web Audio Api 声音登陆

    之前最早时候给过一个识别hz的demo 今天讲那个demo结合上一篇说的振荡器 做了个声音登录的小demo 原理就是2w hz人听不见 其实1w9左右就很轻微了 直接上代码 识别器 限电脑 span style font size 18px
  • 多线程:获取和设置线程名称

    获取线程名称 第一种方式 使用Thread类中的getName方法 有些线程因为并不是继承Thread的 不能直接使用getName 比如main线程 此时需要先使用Thread类中的currentThread方法 这是一个静态方法 获取当
  • List对象集合如何自定义排序

    List对象集合自定义排序 最近开发个人博客项目的时候 遇到了一个难点 如何排序分类Type集合呢 Type java Data public class Type private Long id private String name p
  • Vue.js--组件注册(全局注册、局部注册)、表行组件、组件中的data、组件数据的共享问题详解

    组件 组件 Component 是 Vue js 最强大的功能之一 组件可以扩展 HTML 元素 封装可重用的代码 组件系统让我们可以用独立可复用的小组件来构建大型应用 几乎任意类型的应用的界面都可以抽象为一个组件树 组件注册 组件与Vue
  • angular随笔 之angular添加ng-zorro-antd组件时相关问题

    最近新建angular项目在添加ng zorro antd组件时9 0 0版本以上 会出现无法添加ng zorro antd组件 一添加ng add ng zorro antd就会报如下错误 Error ng zorro antd 0 0
  • npx的介绍

    npx 是 npm5 2 0版本新增的一个工具包 定义为npm包的执行者 相比 npm npx 会自动安装依赖包并执行某个命令 主要功能有2个 1 临时安装软件包执行后删除软件包 例如 create react app 脚手架创建一个 re
  • 工作笔记-记一次Jedis连接泄露的问题及解决过程

    问题追踪 我使用的Jedis版本是2 9 0 通过连接池访问 在做压力测试时 发现在高并发环境下 连接泄露 连接池内的连接未能正常返还 导致 could not get resource fron pool 看使用代码 public voi