使用SpringBoot Data Redis無(wú)法連接Redis-Cluster集群
最近在研究系統(tǒng)高并發(fā)下的緩存架構(gòu),因此自己在自己買的云服務(wù)器上搭建好Redis 5.0 版本的集群后欲低,使用springboot的 RedisTemplate連接是發(fā)現(xiàn)總是訪問(wèn)不到集群節(jié)點(diǎn)荧飞。上網(wǎng)百度了發(fā)現(xiàn)沒有好的解決辦法消略,沒辦法只好自己debug。
RedisTemplat封裝Lettuce來(lái)實(shí)現(xiàn)Redis操作
在Spring boot 2.X 之后,SpringBoot 將默認(rèn)的客戶端換成了Lettuce畏妖。對(duì)于這個(gè)客戶端的好處傅瞻,大家可以自行查找踢代。
Lettuce 初始化連接池時(shí),無(wú)法連接到Redis-Cluster集群
在使用Jedis創(chuàng)建Redis-Cluster集群連接時(shí)嗅骄,沒有任何問(wèn)題胳挎,但是使用了Lettuce客戶端創(chuàng)建,就會(huì)出現(xiàn)連接超時(shí)的問(wèn)題溺森,具體配置如下:
但是當(dāng)我啟動(dòng)程序時(shí)慕爬,Redis客戶端訪問(wèn)的IP:PORT 與我在如上圖所示配置的IP和端口不一致窑眯。這就讓我很無(wú)奈。于是只好針對(duì)日志打印的類去查找相關(guān)源碼医窿。
最后查找到了這個(gè)方法io.lettuce.core.cluster.topology.NodeTopologyView#getOwnPartition
RedisClusterNode getOwnPartition() {
for (RedisClusterNode partition : partitions) {
if (partition.is(RedisClusterNode.NodeFlag.MYSELF)) {
return partition;
}
}
在走到這段代碼的時(shí)候磅甩,他會(huì)將當(dāng)前Redis服務(wù)器對(duì)外的互聯(lián)網(wǎng)及IP轉(zhuǎn)變?yōu)?本機(jī)IP。 知道這個(gè)問(wèn)題就好辦了姥卢。通過(guò)查看redis.conf配置文件卷要,我發(fā)現(xiàn)了這么一段內(nèi)容。
########################## CLUSTER DOCKER/NAT support ########################
# In certain deployments, Redis Cluster nodes address discovery fails, because
# addresses are NAT-ted or because ports are forwarded (the typical case is
# Docker and other containers).
#
# In order to make Redis Cluster working in such environments, a static
# configuration where each node knows its public address is needed. The
# following two options are used for this scope, and are:
#
# * cluster-announce-ip
# * cluster-announce-port
# * cluster-announce-bus-port
#
# Each instruct the node about its address, client port, and cluster message
# bus port. The information is then published in the header of the bus packets
# so that other nodes will be able to correctly map the address of the node
# publishing the information.
#
# If the above options are not used, the normal Redis Cluster auto-detection
# will be used instead.
#
# Note that when remapped, the bus port may not be at the fixed offset of
# clients port + 10000, so you can specify any port and bus-port depending
# on how they get remapped. If the bus-port is not set, a fixed offset of
# 10000 will be used as usually.
#
# Example:
#
#cluster-announce-ip 127.0.01
#cluster-announce-port 7001
#cluster-announce-bus-port 6380
我們通過(guò)上面的英文解讀可以知道這段配置的大致內(nèi)容
在某些部署中独榴,Redis 群集節(jié)點(diǎn)地址發(fā)現(xiàn)失敗僧叉,因?yàn)榈刂肥?NAT-ted 或者因?yàn)槎丝诒晦D(zhuǎn)發(fā)(典型的情況是Docker 和其他集裝箱)為了讓 Redis 集群在這樣的環(huán)境中工作,靜態(tài)配置棺榔,每個(gè)節(jié)點(diǎn)都知道它的公共地址是必需的瓶堕。
我們可以知道 以下這幾個(gè)配置 是可以靜態(tài)配置,保證Redis集群工作的時(shí)候掷豺,可以發(fā)現(xiàn)需要的公共地址(這里就是我所配置的外網(wǎng)地址)
因此我將以上兩個(gè)配置取消了注釋捞烟,并修改為我對(duì)外訪問(wèn)的集群 IP和PORT
cluster-announce-ip 對(duì)外訪問(wèn)IP
cluster-announce-port 對(duì)外端口
修改完之后,重啟集群再啟動(dòng)SpringBoot 程序即可当船。
小結(jié)
有些網(wǎng)上的解決方法题画,不一定是我們真正需要的,凡是還是要自己去探索和動(dòng)腦德频。