动态更新自建的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

相关文章

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)

《JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)》:本文主要介绍如何在IntelliJIDEA2020.1中创建和部署一个JavaWeb项目,包括创建项目、配置Tomcat服务... 目录简介:一、创建项目二、tomcat部署1、将tomcat解压在一个自己找得到路径2、在idea中添加

MyBatis-Plus使用动态表名分表查询的实现

《MyBatis-Plus使用动态表名分表查询的实现》本文主要介绍了MyBatis-Plus使用动态表名分表查询,主要是动态修改表名的几种常见场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录1. 引入依赖2. myBATis-plus配置3. TenantContext 类:租户上下文

Redis 命令详解与实战案例

《Redis命令详解与实战案例》本文详细介绍了Redis的基础知识、核心数据结构与命令、高级功能与命令、最佳实践与性能优化,以及实战应用场景,通过实战案例,展示了如何使用Redis构建高性能应用系统... 目录Redis 命令详解与实战案例一、Redis 基础介绍二、Redis 核心数据结构与命令1. 字符

通过DBeaver连接GaussDB数据库的实战案例

《通过DBeaver连接GaussDB数据库的实战案例》DBeaver是一个通用的数据库客户端,可以通过配置不同驱动连接各种不同的数据库,:本文主要介绍通过DBeaver连接GaussDB数据库的... 目录​一、前置条件​二、连接步骤​三、常见问题与解决方案​1. 驱动未找到​2. 连接超时​3. 权限不

SpringBoot18 redis的配置方法

《SpringBoot18redis的配置方法》本文介绍在SpringBoot项目中集成和使用Redis的方法,包括添加依赖、配置文件、自定义序列化方式、使用方式、实际使用示例、常见操作总结以及注意... 目录一、Spring Boot 中使用 Redis1. 添加依赖2. 配置文件3. Redis 配置类

Java中的随机数生成案例从范围字符串到动态区间应用

《Java中的随机数生成案例从范围字符串到动态区间应用》本文介绍了在Java中生成随机数的多种方法,并通过两个案例解析如何根据业务需求生成特定范围的随机数,本文通过两个实际案例详细介绍如何在java中... 目录Java中的随机数生成:从范围字符串到动态区间应用引言目录1. Java中的随机数生成基础基本随

Redis中群集三种模式的实现

《Redis中群集三种模式的实现》Redis群集有三种模式,分别是主从同步/复制、哨兵模式、Cluster,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1. Redis三种模式概述2、Redis 主从复制2.1 主从复制的作用2.2 主从复制流程2

Redis的安全机制详细介绍及配置方法

《Redis的安全机制详细介绍及配置方法》本文介绍Redis安全机制的配置方法,包括绑定IP地址、设置密码、保护模式、禁用危险命令、防火墙限制、TLS加密、客户端连接限制、最大内存使用和日志审计等,通... 目录1. 绑定 IP 地址2. 设置密码3. 保护模式4. 禁用危险命令5. 通过防火墙限制访问6.

基于Nacos实现SpringBoot动态定时任务调度

《基于Nacos实现SpringBoot动态定时任务调度》本文主要介绍了在SpringBoot项目中使用SpringScheduling实现定时任务,并通过Nacos动态配置Cron表达式实现任务的动... 目录背景实现动态变更定时机制配置化 cron 表达式Spring schedule 调度规则追踪定时