当前位置: 首页 > news >正文

动态更新自建的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连接池也可以类似思路更新。

http://www.lryc.cn/news/377057.html

相关文章:

  • 浅谈设计师的设计地位
  • C/C++ string模拟实现
  • 微信小程序学习(八):behaviors代码复用
  • 【The design pattern of Attribute-Based Dynamic Routing Pattern (ADRP)】
  • 2713. 矩阵中严格递增的单元格数
  • git创建子模块
  • 把Deepin塞进U盘,即插即用!Deepin To Go来袭
  • ​​给【AI硬件】创业者的论文、开源项目和产品整理
  • 模拟面试题卷二
  • 22种常用设计模式示例代码
  • Java面试题:对比ArrayList和LinkedList的内部实现,以及它们在不同场景下的适用性
  • ping: www.baidu.com: 未知的名称或服务(IP号不匹配)
  • 谷神前端组件增强:子列表
  • 测试cudaStream队列的深度
  • ​海康威视 isecure center 综合安防管理平台任意文件上传漏洞
  • shadertoy-安装和使用
  • matlab线性多部法求常微分方程数值解
  • 前端页面实现【矩阵表格与列表】
  • GPT4v和Gemini-Pro调用对比
  • 破布叶(Microcos paniculata)单倍型染色体级别基因组-文献精读22
  • 浅谈RC4
  • uniapp微信小程序开发物料
  • 大数据工程师如何做到数据可视化?
  • Java 序列化与反序列化
  • 自定义防抖注解
  • 【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)
  • 【html】用html+css做地表最强王者荣耀辅助工具
  • TF-IDF、BM25传统算法总结
  • 项目五 OpenStack镜像管理与制作
  • LabVIEW回热系统热经济性分析及故障诊断