RedisConnectionMonitor.java

RedisConnectionMonitor.java

用于监控 Redis 连接状态,特别是在服务器端定时关闭连接时进行诊断。

复制代码
package further.common.conf.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * Redis 连接健康检查和监控
 * <p>
 * 用于监控 Redis 连接状态,特别是在服务器端定时关闭连接时进行诊断。
 * </p>
 *
 * @author ZengWenFeng
 * @date 2025.12.20
 * @mobile 13805029595
 * @email 117791303@QQ.com
 */
@Component
public class RedisConnectionMonitor
{
	private static final Logger logger = LoggerFactory.getLogger(RedisConnectionMonitor.class);

	@Autowired
	private RedisTemplate<Object, Object> redisTemplate;

	/**
	 * 每5分钟检查一次 Redis 连接健康状态
	 */
	@Scheduled(fixedRate = 300000) // 5分钟 = 300000毫秒
	public void checkConnectionHealth()
	{
		try
		{
			// 执行 PING 命令检查连接
			String result = redisTemplate.getConnectionFactory().getConnection().ping();
			if ("PONG".equals(result))
			{
				logger.debug("Redis 连接健康检查通过: {}", result);
			}
			else
			{
				logger.warn("Redis 连接健康检查异常,返回: {}", result);
			}
		}
		catch (Exception e)
		{
			logger.error("Redis 连接健康检查失败,可能连接已断开: {}", e.getMessage());
			// Lettuce 会自动重连,这里只记录日志
		}
	}

	/**
	 * 每天 4:55 执行一次连接检查(在 5:01 断开前)
	 * 用于诊断是否在 5 点有定时任务
	 */
	@Scheduled(cron = "0 55 4 * * ?")
	public void preDisconnectCheck()
	{
		logger.info("========== Redis 连接预检查(5点前) ==========");
		try
		{
			String result = redisTemplate.getConnectionFactory().getConnection().ping();
			logger.info("Redis 连接正常: {}", result);
		}
		catch (Exception e)
		{
			logger.error("Redis 连接异常: {}", e.getMessage(), e);
		}
		logger.info("=============================================");
	}

	/**
	 * 每天 5:05 执行一次连接检查(在 5:01 断开后)
	 * 用于确认连接是否已自动重连
	 */
	@Scheduled(cron = "0 5 5 * * ?")
	public void postDisconnectCheck()
	{
		logger.info("========== Redis 连接后检查(5点后) ==========");
		try
		{
			String result = redisTemplate.getConnectionFactory().getConnection().ping();
			logger.info("Redis 连接已恢复: {}", result);
		}
		catch (Exception e)
		{
			logger.error("Redis 连接仍未恢复: {}", e.getMessage(), e);
		}
		logger.info("=============================================");
	}
}
复制代码
2025-12-20 05:01:12.121 [lettuce-nioEventLoop-16-1] INFO  io.lettuce.core.protocol.CommandHandler - null Unexpected exception during request: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
java.io.IOException: 远程主机强迫关闭了一个现有的连接。
	at sun.nio.ch.SocketDispatcher.read0(Native Method)
	at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)
	at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
	at sun.nio.ch.IOUtil.read(IOUtil.java:192)
	at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:378)
	at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:253)
	at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1134)
	at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:750)



The method setMaxWait(int, TimeUnit) is undefined for the type GenericObjectPoolConfig<capture#4-of ?>

The method setTimeBetweenEvictionRuns(int, TimeUnit) is undefined for the type GenericObjectPoolConfig<capture#7-of ?>

The method commandTimeout(Duration) in the type LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder is not applicable for the arguments (int, TimeUnit)

The final field RedisConfig.FastJson2JsonRedisSerializer<T>.objectMapper cannot be assigned

登飞来峰 北宋·王安石 飞来山上千寻塔,闻说鸡鸣见日升.不畏浮云遮望眼,只缘身在最高层。

相关推荐
JAVA面经实录9176 小时前
Java企业级工程化·终极完整版背诵手册(无遗漏、全覆盖、面试+落地通用)
java·开发语言·面试
许彰午8 小时前
CacheSQL(二):主从复制——OpLog 环形缓冲区与故障自动恢复
java·数据库·缓存
Bat U9 小时前
JavaEE|多线程初阶(七)
java·开发语言
掌心向暖RPA自动化12 小时前
如何获取网页某个元素在屏幕可见部分的中心坐标影刀RPA懒加载坐标定位技巧
java·javascript·自动化·rpa·影刀rpa
日取其半万世不竭12 小时前
Minecraft Java版社区服务器搭建教程(Linux,适合新手)
java·linux·服务器
TeamDev13 小时前
JxBrowser 9.0.0 版本发布啦!
java·前端·混合应用·jxbrowser·浏览器控件·跨平台渲染·原声输入
AI人工智能+电脑小能手13 小时前
【大白话说Java面试题】【Java基础篇】第24题:Java面向对象有哪些特征
java·开发语言·后端·面试
AI人工智能+电脑小能手13 小时前
【大白话说Java面试题】【Java基础篇】第25题:JDK1.8的新特性有哪些
java·开发语言·后端·面试
likerhood14 小时前
SLF4J: Failed to load class “StaticLoggerBinder“ 解决
java·log4j·maven
早日退休!!!14 小时前
大模型推理瓶颈七层分析模型
java·服务器·数据库