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>
改完後,我在本地觀察了一會,好像不會出現以上兩個問題。不過上到生產可能還要觀察一段時間。唉,煩
(觀察了幾天還真沒有再發現問題了)