問題背景
- Django項(xiàng)目第一次發(fā)布到生產(chǎn)環(huán)境,啟動(dòng)后發(fā)現(xiàn)連不上Redis集群。
- 測(cè)試環(huán)境的redis集群沒有密碼,導(dǎo)致測(cè)試環(huán)境生產(chǎn)的配置格式會(huì)有差異
- 生產(chǎn)環(huán)境使用的redis配置,之前沒人驗(yàn)證過,不知道是單機(jī)還是集群
- 生產(chǎn)環(huán)境redis的密碼中特殊符合@,同事說可能會(huì)Django Cache配置的URI切割符號(hào)沖突,他之前在celery broker_url配置時(shí)就遇到這個(gè)坑。
排查思路
- 測(cè)試環(huán)境和生產(chǎn)環(huán)境的配置不一樣,因此要格外小心,生產(chǎn)環(huán)境配置不能照抄測(cè)試環(huán)境的
- 優(yōu)先使用官方redis-cli確定redis是集群還是客戶端,再去修改代碼相關(guān)的配置
- 本地?zé)o法連接生產(chǎn)環(huán)境,因?yàn)樾枰ㄟ^跳板機(jī)登錄上去生產(chǎn)環(huán)境,直接利用Django shell調(diào)試,而不每次修改代碼后重新提交,然后構(gòu)建。
- 出問題時(shí),優(yōu)先懷疑自己的代碼問題,而不是找框架本身的問題,尤其是Django這種大框架。
排查過程
確認(rèn)客戶端類型
- 做一個(gè)最簡(jiǎn)單的set命令測(cè)試,直接報(bào)錯(cuò)。
rhea-flaskapi-live-sg(sg2|10.xxx:40681)@/workspace$ redis-cli -h redis.xxx.shopee.io -p 10010 -a xxxx@123
redis.xxx.shopee.io:10010> set a 123
(error) MOVED 15495 10.xxx.104:10011
- 經(jīng)過搜索引擎查詢,確認(rèn)這個(gè)redis是集群,集群的連接命令是
redis-cli -c -h 連接地址 -p 端口 -a 密碼上面的命令少了-c參數(shù)
啟動(dòng)Django Shell連接redis
from django_redis import get_redis_connection
conn = get_redis_connection()
直接就一個(gè)連接失敗


確認(rèn)賬號(hào)密碼和端口沒問題后,問題同事配置有沒驗(yàn)證過,他說直接從網(wǎng)上cv的,完全沒經(jīng)過驗(yàn)證??影。。?!
修改配置后重新測(cè)試
把生產(chǎn)的配置和測(cè)試配置比較好,修改了幾個(gè)地方
-
LOCATION從str改成List[str],加上默認(rèn)db,也就是[ f'redis://{DEFAULT_REDIS_URL}:{DEFAULT_REDIS_PORT}/0'] -
REDIS_CLIENT_CLASS': 'rediscluster.RedisCluster這個(gè)集群連接需要的客戶端 - 連接池配置改成
'CONNECTION_POOL_CLASS': 'rediscluster.connection.ClusterConnectionPool'
信心滿滿,重啟啟動(dòng)django shell測(cè)試,結(jié)果還是連接上不!這時(shí)候心情開始有點(diǎn)糟糕~
冷靜,django shell不行,那用python shell直連試試?
Python Shell直連redis

一點(diǎn)毛病都沒有,直接連上了!
一臉懵逼,這到底是啥問題啊!
不死心,反復(fù)修改配置,測(cè)試Django Shell連接Redis
結(jié)果依然是連接不上。
下班回家過程中的思考
不知不覺已經(jīng)到了晚上九點(diǎn),好累,不想卷了。下班回家吧
回家路上整個(gè)腦子都被這個(gè)問題困擾著。難道密碼中含有@符號(hào)的redis集群,Django真的連接不上?反復(fù)的問自己。
問了其他同事,生產(chǎn)環(huán)境是否有其他的redis集群可以用來調(diào)試。很遺憾,并沒有。
要不,我自己創(chuàng)建一個(gè)redis集群,把密碼設(shè)置成含有@符號(hào)?
可是,自己本地創(chuàng)建redis集群好麻煩啊。要本地安裝虛擬機(jī),想到一堆配置就直接勸退。
回到家后的糾結(jié)
洗完澡,和老婆聊了1h左右的視頻。已經(jīng)到11點(diǎn)多,準(zhǔn)備睡覺?
那是不可能的,帶著問題是很難入睡!哎,這個(gè)是老毛病了。
突然想到了一個(gè)點(diǎn),最小試錯(cuò)原則。自己搭建本地集群很麻煩,公司又沒有多余的集群。
那直接買一個(gè)云版的redis集群?說干就干,直接從床上起來,打開電腦。
最小試錯(cuò)原則,買云Redis集群,而不是自己搭建
這時(shí)問題又來了,阿里云還是騰訊云?
鑒于雙11買了騰訊云2c 4g 8m的服務(wù)器,只要199就能3年。
再對(duì)比之前買阿里云那個(gè)1c 2g 1m服務(wù)器,3年也要100多。
瞬間對(duì)騰訊云好感倍增,決定先買騰訊云。
買騰訊云redis集群
一頓操作,發(fā)現(xiàn)騰訊云是真的難用:
- 購(gòu)買頁(yè)面選好配置好,提交后,因?yàn)槲覜]有余額,提示我充值。等我充值完,結(jié)果之前選擇的配置沒了,只好重新選擇。
- redis集群沒有重啟功能???
- 設(shè)置安全組時(shí),只能在安全組的頁(yè)面綁定實(shí)例;在實(shí)例頁(yè)面無法綁定安全組。
最最最重要,給把實(shí)例綁定了安全組后,外網(wǎng)還是無法訪問???(不管了,反正我就是很生氣)
買阿里云redis集群
對(duì)騰訊云太失望了,不得不把最后一根稻草壓在阿里云身上。
所幸,阿里云沒有讓我失望!
咔咔咔,一頓操作:
創(chuàng)建實(shí)例,這點(diǎn)阿里云是比騰訊云慢很多,大概要7min左右(純感覺)
-
配置外網(wǎng)訪問,很方便。這操作邏輯簡(jiǎn)直是秒殺騰訊云。
image-20211130120920961 -
配置白名單,redis-cli連接測(cè)試,成功通過!
image-20211130121327756 修改配置,啟動(dòng)Django shell測(cè)試。
- image-20211130121629842

密碼中含有@符號(hào),但連接一點(diǎn)毛病都沒有!?。?/p>
至此,問題終于解決了?。。?/p>
我已經(jīng)迫不及待明天去公司驗(yàn)證,但回過頭一看,已經(jīng)是深夜一點(diǎn)半。
自言自語(yǔ)的說了一句:"睡吧,卷王"
第二天去公司驗(yàn)證
rhea-flaskapi-live-sg(sg2|xxxx:26863)@/workspace$ python3.8 manage.py shell --settings=rhea.settings.prod
rhea.settings.prod
Python 3.8.7 (default, Oct 1 2021, 14:58:33)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django_redis import get_redis_connection
>>> conn = get_redis_connection()
>>>>conn.get("rhea:access_token:abc")
'huacai.li@shopee.com'
經(jīng)過對(duì)比,發(fā)現(xiàn)配置只需要生產(chǎn)的配置僅需要在測(cè)試的配置上加多一個(gè):

修復(fù)最磨人的bug,往往僅需要一點(diǎn)小小的改動(dòng)~
為什么測(cè)試環(huán)境沒報(bào)錯(cuò)了呢???
因?yàn)闇y(cè)試環(huán)境的redis集群不需要密碼
總結(jié)
一切沒經(jīng)過自己驗(yàn)證的代碼,一定要謹(jǐn)慎使用
最小試錯(cuò)原則。想驗(yàn)證一件事情時(shí),盡量使用最小的成本去驗(yàn)證
生產(chǎn)和測(cè)試環(huán)境盡量保持配置相同


