动态更新自建的Redis连接池连接数量

2024-06-20 02:52

本文主要是介绍动态更新自建的Redis连接池连接数量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

/*** 定时更新Redis连接池信息,防止资源让费*/private static final ScheduledThreadPoolExecutor DYNAMICALLY_UPDATE_REDIS_POOL_THREAD = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {@Overridepublic Thread newThread(Runnable r) {Thread thread = new Thread(r);/*** 通道检查,对未成功注册路由的设备补偿注册*/thread.setName("dynamically.update.redis.pool");return thread;}});
static {DYNAMICALLY_UPDATE_REDIS_POOL_THREAD.scheduleAtFixedRate(() -> {try {dynamicallyUpdateRedisPool();} catch (Exception e) {logger.warn("Redis扩容缩容失败", e);}//开机延迟5分钟,之后每1分钟执行一次}, 5, 1, TimeUnit.MINUTES);}
/*** 动态更新连接池信息*/private static void dynamicallyUpdateRedisPool() {if (instMap.isEmpty()) {return;}String key = null;MyJedis myJedis = null;int maxConn = 0, activeNum = 0, idleNum = 0, waiterNum = 0, newMaxConn = 0;long maxWaitTime = 0, meanWaitTime = 0;boolean isUpdateConn = false;for (Entry<String, MyJedis> keyMyJedisEntry : instMap.entrySet()) {isUpdateConn = false;key = keyMyJedisEntry.getKey();myJedis = keyMyJedisEntry.getValue();if (myJedis == null || myJedis.pool == null || myJedis.pool.isClosed()) {continue;}maxConn = myJedis.maxConnection;//活跃连接诶数量activeNum = myJedis.pool.getNumActive();//monitor(key + ".active.num", activeNum, null);//空闲连接数量idleNum = myJedis.pool.getNumIdle();//monitor(key + ".idle.num", idleNum, null);//等待连接数量waiterNum = myJedis.pool.getNumWaiters();//monitor(key + ".waiter.num", waiterNum, null);//等待连接最长时间毫秒maxWaitTime = myJedis.pool.getMaxBorrowWaitTimeMillis();//monitor(key + ".max.wait.time", null, maxWaitTime);//等待连接平均毫秒meanWaitTime = myJedis.pool.getMeanBorrowWaitTimeMillis();//monitor(key + ".mean.wait.time", null, meanWaitTime);// 判断连接数是否超出预期范围if (activeNum > maxConn * 0.8) {logger.warn("警告:活跃连接数过多,可能需要优化连接池设置 activeNum:{} maxConn:{}。", activeNum, maxConn);isUpdateConn = true;} else if (idleNum < MAX_IDLE * 0.2) {logger.warn("警告:空闲连接数过少,可能需要优化连接池设置 idleNum:{} maxIdle:{}。", idleNum, MAX_IDLE);isUpdateConn = true;}if (isUpdateConn) {newMaxConn = Double.valueOf(maxConn * (1 + 0.25)).intValue();if (newMaxConn >= REDIS_MAX_CONN) {logger.warn("警告:redis已达可申请的最大连接数量,不能继续扩容 maxConn:{} redisScalesUpTheMost:{}", maxConn, REDIS_MAX_CONN);continue;}updateJedisPool(myJedis, newMaxConn);continue;}// 当空闲连接过多,并且总连接数小于最大值的0.2if (idleNum > MIN_IDLE && activeNum < maxConn * 0.2) {logger.warn("警告:空闲连接过多,活跃连接太少 idleNum:{} minIdle:{} activeNum:{} maxConn:{}。", idleNum, MIN_IDLE, activeNum, maxConn);newMaxConn = Double.valueOf(maxConn * 0.75).intValue();if (newMaxConn <= REDIS_MIN_CONN) {logger.warn("警告:redis已达缩容的最小连接数量,不能继续缩容 maxConn:{} redisScalesUpTheMost:{}", maxConn, REDIS_MIN_CONN);continue;}updateJedisPool(myJedis, newMaxConn);}}}private static void updateJedisPool(MyJedis myJedis, int newMaxConn) {//空闲连接数为空 & 当前活跃连接数量,已达最大连接数量 & 最大等待时间达到了 5s & 平均等待时间达到了 1s,连接池扩大0.5倍JedisPool oldJedisPool = myJedis.pool;myJedis.pool = initJedisPool(myJedis, newMaxConn);myJedis.maxConnection = newMaxConn;try {Thread.sleep(5000);//等待5s,防止redis访问还在使用,之后回收老的连接池oldJedisPool.destroy();} catch (InterruptedException e) {}}
/*** 初始化Redis连接信息** @param maxConn* @return*/private static JedisPool initJedisPool(MyJedis myJedis, int maxConn) {JedisPoolConfig config = new JedisPoolConfig();//最大连接数config.setMaxTotal(maxConn);//最大空闲连接数config.setMaxIdle(MAX_IDLE);//最小空闲连接数config.setMinIdle(MIN_IDLE);//获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1config.setMaxWaitMillis(1000 * 10);//在获取连接的时候检查有效性config.setTestOnBorrow(false);//返回连接时检查有效性config.setTestOnReturn(false);//空闲时检查有效性config.setTestWhileIdle(true);if (StringUtils.isNoneBlank(myJedis.password)) {return new JedisPool(config, myJedis.host, myJedis.port, 8000, myJedis.password, myJedis.database);} else {return new JedisPool(config, myJedis.host, myJedis.port, 8000, null, myJedis.database);}}

Spring bean的Redis连接池也可以类似思路更新。

这篇关于动态更新自建的Redis连接池连接数量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1076902

相关文章

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL

Redis在windows环境下如何启动

《Redis在windows环境下如何启动》:本文主要介绍Redis在windows环境下如何启动的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Redis在Windows环境下启动1.在redis的安装目录下2.输入·redis-server.exe

MySQL中的交叉连接、自然连接和内连接查询详解

《MySQL中的交叉连接、自然连接和内连接查询详解》:本文主要介绍MySQL中的交叉连接、自然连接和内连接查询,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、引入二、交php叉连接(cross join)三、自然连接(naturalandroid join)四

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.

Redis实现延迟任务的三种方法详解

《Redis实现延迟任务的三种方法详解》延迟任务(DelayedTask)是指在未来的某个时间点,执行相应的任务,本文为大家整理了三种常见的实现方法,感兴趣的小伙伴可以参考一下... 目录1.前言2.Redis如何实现延迟任务3.代码实现3.1. 过期键通知事件实现3.2. 使用ZSet实现延迟任务3.3

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Redis分片集群的实现

《Redis分片集群的实现》Redis分片集群是一种将Redis数据库分散到多个节点上的方式,以提供更高的性能和可伸缩性,本文主要介绍了Redis分片集群的实现,具有一定的参考价值,感兴趣的可以了解一... 目录1. Redis Cluster的核心概念哈希槽(Hash Slots)主从复制与故障转移2.

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.