redis io.lettuce.core.RedisCommandTimeoutException: Command timed out after

redis報錯遠程主機強迫關閉了一個現有的連接以及超時問題

原創 2019-10-11 16:37 閱讀(841)次

問題說明:

spring boot2.x+redis開發時,總是時不是發生redis超時,時不時報:遠程主機強迫關閉了一個現有的連接以及超時問題。這個問題總是偶有出現,煩人。

spring boot2.x版本默認redis連接池爲lettuce,以前在非spring boot項目中使用jedis連接redis時,好像沒有過這種煩人的問題,搞的現在對redis有陰影。。。我的項目也是使用默認的lettuce連接redis。

我們先看超時問題的報錯:

io.lettuce.core.RedisCommandTimeoutException: Command timed out after 5 second(s)

再看看遠程主機強迫關閉了一個現有的連接報錯:

org.springframework.data.redis.RedisSystemException: Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: 遠程主機強迫關閉了一個現有的連接。
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:74)
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41)
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)

真的煩。

 

這兩個問題我暫時的解決辦法(有待觀察):

將spring boot redis配置設置超時時間比redis.conf中的timeout要小,比如spring boot redis中設置超時30秒,那麼服務器中redis timeout設置爲40秒;另外將redis.conf中的tcp-keepalive改成10:

 

# Unix socket.
#
# Specify the path for the Unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
# unixsocket /tmp/redis.sock
# unixsocketperm 700

# Close the connection after a client is idle for N seconds (0 to disable)
timeout 40

# TCP keepalive.
#
# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
# of communication. This is useful for two reasons:
#
# 1) Detect dead peers.
# 2) Take the connection alive from the point of view of network
#    equipment in the middle.
#
# On Linux, the specified value (in seconds) is the period used to send ACKs.
# Note that to close the connection the double of the time is needed.
# On other kernels the period depends on the kernel configuration.
#
# A reasonable value for this option is 300 seconds, which is the new
# Redis default starting with Redis 3.2.1.
tcp-keepalive 10


 

 

這樣好像就不會報Command timed out after xxx second(s)了,但是對於“遠程主機強迫關閉了一個現有的連接”這個問題貌似只能把lettuce連接池切回jedis了,我今天實在是忍受不了lettuce了。把配置文件改成如下:

 

spring:
  redis:
    host: xxxxx
    port: 6379
    password: xxxxxx
    timeout: 30s
#    lettuce:
#      pool:
#        min-idle: 10
#        max-idle: 20
#        max-active: 200
#        max-wait: -1ms
    jedis:
      pool:
        min-idle: 10
        max-idle: 20
        max-wait: -1ms
        max-active: 200

 

Maven pom.xml:

 

		<!-- redis緩存 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
			<exclusions>
				<exclusion>
					<groupId>redis.clients</groupId>
					<artifactId>jedis</artifactId>
				</exclusion>
				<exclusion>
					<groupId>io.lettuce</groupId>
					<artifactId>lettuce-core</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
			<version>2.6.2</version>
		</dependency>

改完後,我在本地觀察了一會,好像不會出現以上兩個問題。不過上到生產可能還要觀察一段時間。唉,煩

(觀察了幾天還真沒有再發現問題了)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章