我们使用Redisson连接到AWS弹性缓存上的复制Redis,其中包含1个主节点和2个副本节点 .

该应用程序使用多个 RLocalCachedMap s, Lock 和几千 Topics 来跟踪用户状态 . (当用户上线和离线时,主题和订阅来来去去) .

然而,我们经常得到一系列的 RedisTimeoutException s,最初这些是在服务器运行了几天之后并且会持续发生,直到服务器重新启动,或者因内存不足错误而崩溃 . 这让我觉得缺乏可用的订阅,但是如果我正确理解它们,我们的设置(下面)应该支持超过100,000个订阅,而我们并不接近它 .
其中一些将在预热期间发生,其中服务器上的负载相对较轻,在几个例外之后连接排序并且几天没有主要问题,这表明它不是纯粹的订阅问题 . 这些命令每次都是简单的锁定/发布/订阅,而不是复杂的批次 .

AWS Elasticache节点上的负载始终较小,我们的服务器部署在AWS EC2实例上,因此应具有相对良好的连接性!

我们获得的2个例外是锁定或订阅主题:

Caused by: org.redisson.client.RedisTimeoutException: Subscribe timeout: (7500ms)
at org.redisson.command.CommandAsyncService.syncSubscription(CommandAsyncService.java:142) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonLock.lockInterruptibly(RedissonLock.java:149) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonLock.lockInterruptibly(RedissonLock.java:136) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonLock.lock(RedissonLock.java:118) ~[redisson-3.8.2.jar!/:na]

java.util.concurrent.CompletionException: org.redisson.client.RedisTimeoutException
at org.redisson.misc.RedissonPromise.await(RedissonPromise.java:197) ~[redisson-3.8.2.jar!/:na]
at org.redisson.misc.RedissonPromise.await(RedissonPromise.java:206) ~[redisson-3.8.2.jar!/:na]
at org.redisson.command.CommandAsyncService.syncSubscription(CommandAsyncService.java:141) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonTopic.addListener(RedissonTopic.java:133) ~[redisson-3.8.2.jar!/:na]
at org.redisson.RedissonTopic.addListener(RedissonTopic.java:109) ~[redisson-3.8.2.jar!/:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_111]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_111]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_111]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_111]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_111]
Caused by: org.redisson.client.RedisTimeoutException: null
at org.redisson.pubsub.PublishSubscribeService$4.run(PublishSubscribeService.java:220) ~[redisson-3.8.2.jar!/:na]
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:670) ~[netty-common-4.1.30.Final.jar!/:4.1.30.Final]
at io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:745) ~[netty-common-4.1.30.Final.jar!/:4.1.30.Final]
at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:473) ~[netty-common-4.1.30.Final.jar!/:4.1.30.Final]

我们的配置是:

"subscriptionConnectionMinimumIdleSize":32,
"subscriptionConnectionPoolSize":128,
"slaveConnectionMinimumIdleSize":32,
"slaveConnectionPoolSize":128,
"masterConnectionMinimumIdleSize":64,         
"masterConnectionPoolSize":128,
"subscriptionsPerConnection": 1000,
"timeout": 3000,
"retryAttempts": 3,
"retryInterval": 1500,
"readMode": "SLAVE",
"subscriptionMode": MASTER

我已经阅读了关于超时的Redisson常见问题解答,我们的超时异常显然不是服务器或客户端,所以不确定哪个超时参数更好调整,进一步假设它们是7.5秒,这对于用户请求等待来说相当长 . 同样,我找不到有关连接池大小或每个连接的订阅的建议值的文档,以及 生产环境 部署的合理值 .