解决redis lettuce连接池经常出现连接拒绝(Connection refused)问题

一.软件环境

windows10、11系统、springboot2.x、redis 6 7

linux(centos)系统没有出现这问题,如果你是linux系统碰到的,本文也有一定大参考价值。

根本思路就是:tcp/ip连接的保活(keepalive)。

二.问题描述

在springboot项目中使用了lettuce作为redis的连接池,在本地开发环境windows系统中,隔5分钟不操作,再次需要访问redis时,从连接池获取一个连接去操作redis就会出现连接拒绝,一般直到取完max-idle(最大空闲连接数)所有连接都是连接拒绝,直到开始创建新的连接,才能连接上redis。

三.问题分析

测试环境(linux)连的是同一个redis服务,却没有出现这样的问题。

之前也试着从连接池配置去解决问题,然并卵。。。

复制代码
    lettuce:
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: 1
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池中的最小空闲连接
        min-idle: 0
      cluster:
        refresh:
          adaptive: true
          #20秒自动刷新一次
          period: 20

也试过网上说的各种方法都没有效果。

后面想着,既然在linux系统中运行没问题,windows系统有问题,在其它条件相同的情况下,那就只有操作系统的差异了。

那就可能是两个系统维护tcp/ip的方式的不同了,因为连接池中的连接,本质上就是一个个tcp/ip连接,要想让连接保活,服务端和客户端,至少得有一方去做保活(keepalive)操作。

为什么是隔5分钟不操作,就必然出现redis连接拒绝呢?于是在redis配置文件中搜索"keepalive"发现tcp-keepalive配置,默认300s,这不正好5分钟吗?该配置是服务端每隔300秒检查一下客户端连接,如果可以连通,则让连接保活,如果连不通了,则将连接销毁。

那么导致redis服务端做保活操作后,redis连接就不可用了,应该就是windows系统在这5分钟内,将tcp/ip连接给干掉了,导致redis服务端连接不到就把连接干掉了,而lettuce并不知道连接已经断开了,当有请求需要连接redis时,就从lettuce中拿一个已经被服务端断开连接去操作redis,于是就得到了连接拒绝的响应。

四.解决方案

方案 1:减少redis服务端配置文档的tcp-keepalive的间隔时间,将上图中的设置改为60后,重启服务,经过测试就没有连接拒绝的问题了。

方案2:增加windows系统的tcp/ip连接的存活时间,但是这个修改过几个配置,好像没有效,也有说法是防火墙、杀毒软件的防护策略等管理着tcp/ip的存活时间。如不可用,建议直接使用方案1。

下面的设置没有效果。

复制代码
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "KeepAliveTime" -Value 180000

Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "KeepAliveInterval" -Value 1000

Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "KeepAliveProbes" -Value 10
相关推荐
liulun2 分钟前
在浏览器中使用SQLite(官方sqlite3.wasm)
数据库·sqlite·wasm
IT项目管理1 小时前
达梦数据库DMHS介绍及安装部署
linux·数据库
你都会上树?1 小时前
MySQL MVCC 详解
数据库·mysql
大春儿的试验田1 小时前
高并发收藏功能设计:Redis异步同步与定时补偿机制详解
java·数据库·redis·学习·缓存
likeGhee1 小时前
python缓存装饰器实现方案
开发语言·python·缓存
hqxstudying1 小时前
Redis为什么是单线程
java·redis
C182981825752 小时前
OOM电商系统订单缓存泄漏,这是泄漏还是溢出
java·spring·缓存
Ein hübscher Kerl.2 小时前
虚拟机上安装 MariaDB 及依赖包
数据库·mariadb
醇醛酸醚酮酯2 小时前
Qt项目锻炼——TODO清单(二)
开发语言·数据库·qt
GreatSQL社区3 小时前
用systemd管理GreatSQL服务详解
数据库·mysql·greatsql