測試右移-後台服務監控告警實踐
前言
前段時間,公司上線了「大屏」項目,用於對接展示一些業務平台的數據。但是在上線後使用過程中,產品或業務經常回饋前台頁面沒有數據。出現這種情況後,開發人員會去排查問題,解決後再通知產品或業務人員解決修復情況。雖然研發每次都能在較短的時間內響應並解決問題,但運行一段時間後又會反覆出現,也給用戶造成了極其不好的使用體驗。而本文則是基於「測試右移」思想,開展的一次後台服務監控告警的實踐記錄總結,整個實踐過程可以分為:
- 收到問題回饋;
- 溝通定位問題;
- 討論並選定解決方案;
- 解決方案實現;
- 驗證解決方案;
- 優化解決方案;
- 實施解決方案;
什麼是「測試右移」
在正式開始之前,先簡單介紹一下「測試右移」:
我們都知道,軟體測試活動應當貫穿整個軟體生命周期,包括需求討論分析階段、研發設計編碼階段、測試階段、上線後的監控運行階段。「測試右移」是在產品上線後,為了驗證在真實的用戶數據環境下,功能、性能以及產品體驗,是否符合預期而開展的一系列監控、分析、測試活動,以達到持續監控軟體線上品質的目的。一旦線上發生任何問題,則可以提前反應,主動分析,儘快處理,給用戶以良好的使用體驗。
一、收到問題回饋
從項目上線不久,即收到產品多次在項目群中回饋的以上問題。開發經過定位後,給出的說法是「後台鏈接斷掉了」。在其重啟後台服務後,該項目確實平穩運行了一段時間,但一段時間後,又會再次發生鏈接斷掉、前台無數據展示的情況。此問題給用戶造成了很不好的使用體驗。
二、溝通定位問題
1.服務架構
經過和研發的幾次溝通交流,我畫了份草圖,嘗試理解和說明問題的產生原因。先簡單介紹一下大屏項目的後台服務架構,後台服務假設為B服務。B服務監聽的是本地5081埠,通過TCP與網關進行連接,網關通過websocket將B服務傳來的後台數據推送給前端進行展示,用戶可以通過9530埠進行頁面訪問。網關與前端之間的websocket連接相對較為穩定,導致出問題的是B服務與網關之間的TCP連接經常斷掉,從而導致網關拿不到數據,前端無法展示數據。
三、討論並選定解決方案
1.討論分析解決方案
既然了解了問題所在,那麼就可以針對性地設計解決方案。經過與研發的交流討論,共總結了以下方案:
① 監控後台服務埠
通過shell腳本+定時任務,每幾分鐘輪詢一次,判斷5081埠是否處於連接狀態,來確定後台服務與網關之間的TCP鏈接是否正常,若是斷鏈,則向企業微信發送告警消息、通知人為處理,並自動重啟後台服務。這種方法優點是:
- 最為簡單快捷,能夠及時通知相關研發測試及時去關注服務連通性,而不是等待客戶發現,做到了主動監控;
- 通過重啟機制,能重啟後台服務、重新建立TCP鏈接;
缺點是:
- 啟動shell腳本,開啟進程,佔用系統資源;
- 部分情況下可能並不是TCP鏈接斷掉,也可能是連接數量達到上限導致的問題,並沒有從根本層面解決問題;
② 業務層程式碼解決
在業務層的程式碼中增加「定期檢查與網關之間的TCP連接狀態」機制,若出現連接斷掉的情況,及時重新連接,和上述第一種方式類似,只不過由shell腳本改成了業務程式碼的形式。
③ 修改底層框架
對於底層通訊框架,這個我了解不多。從研發出得到的結論是,改動比較大,需要修改地方比較多,可能會造成其他連帶風險。
2.選定解決方案
由於底層框架修改代價較高,可能會導致其他風險、甚至影響到其他在運行項目,且項目需要重新排期,因此,經過一番權衡,我們決定採用第一種通過shell腳本監控後台服務狀態的方式來實現解決。
四、解決方案實現
1.總體方案設計
- send_msg.py:python腳本,向企微發送消息,通知人為干預;
- monitor.sh:shell腳本,用於監聽5081埠,判斷服務是否為正常連接狀態,若連接異常,則重啟服務,並驅動執行send_msg.py的,向企微發送消息;
- 定時任務:配置一個每五分鐘執行一次的定時任務,用於執行monitor.sh,檢測TCP連接狀態;
2.編寫監控腳本
1)服務監控腳本
5081為後台服務本地埠,其與網關之間建立連接後,正常連接下,監聽狀態為「ESTABLISHED」;異常連接時,監聽狀態為「TIME_WAIT」。因此可以通過判斷監聽狀態來判斷服務的連接情況。
具體實現如下
#!/bin/sh export PYTHON_HOME=/home/python3 export PATH=${PATH}:${PYTHON_HOME}"/bin" # 判斷5081埠連接狀態 connect_number=`netstat -antp | grep 5081 | grep ESTABLISHED | wc -l` echo $connect_number if [ $connect_number != "0" ];then echo "5081埠連接狀態正常" else echo "5081埠已斷開!!!" # 重啟後台服務 /home/BCS/bin/start.sh # 執行Python腳本,發送企微消息通知 /home/python3/bin/python3 /home/send_msg.py fi
注意事項:
腳本開頭一定要導出環境變數,否則系統會識別不到Python3,即使/etc/profile中已配置好了Python3的環境變數。(在配置定時任務時發現,怎麼都不執行發送消息的Python腳本,困擾了好久)
2)Python發送通知腳本
伺服器需提前安裝Python環境,可參照前面的文章《Linux下一鍵安裝Python3&更改鏡像源&虛擬環境管理技巧》
class EnterpriseWechatNotification: def __init__(self, hook: list): self.hook_url_list = [f"//qyapi.weixin.qq.com/cgi-bin/webhook/send?key={i}" for i in hook] self.header = {'Content-Type': 'application/json'} def send_msg(self, result=''): """發送企業微信消息通知""" global payload current_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) content = f"""** 【大屏服務監控】** > 當前時間: {current_time} > 當前環境: #開發環境 > 告警事件: #大屏服務斷鏈,請及時處理!!! {result}""" payload = { "msgtype": "markdown", "markdown": { "content": content } } for hook_url in self.hook_url_list: requests.post(url=hook_url, headers=self.header, data=json.dumps(payload)) if __name__ == '__main__': # 企業微信群中創建一個機器人,即可拿到hook_url # 此處為一個hook ID的列表,傳入多個,則發送到多個群 EnterpriseWechatNotification(hook=["xxxxxxxxxx"]).send_msg()
3.配置伺服器定時任務
1)編輯定時任務
crontab -e
配置內容如下:
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed # 每5分鐘執行一次monitor.sh */5 * * * * root /home/monitor.sh &
2)重啟定時任務服務
systemctl restart crond
五、測試環境驗證
將項目後台服務斷掉,五分鐘後,企業微信收到消息通知。可見,腳本及定時任務均正常運行。
由於服務重連需要一段時間,通常在一分鐘以內。過一分鐘後查看,服務已自動重啟:
六、優化解決方案
上述方案雖能夠監控服務連接狀態並重啟服務、發送消息通知等情況,但也面臨一些缺點:運行腳本的伺服器需要安裝Python3,Python3相關進程也會佔用系統資源。Python腳本的本質是調用企業微信的webhook,發送指定內容,那麼能否直接在shell腳本中來實現同樣的功能?答案是肯定的。(下列腳本為本項目後台開發設計編寫,此處僅作引用、添加了一些注釋方便理解,以供參考)
#!/bin/bash date=`date +%Y/%m/%d\ %H:%M:%S` # 重連函數 re_connet() { echo $date ">>>連接已經斷開,正在重連中..." cd /home/jumploo/risun/BCS/bin sh restart cd - watch_msg # 調用發送消息函數 } # 發送消息函數 watch_msg() { num=$connect_num # 循環20次,每3秒輪詢一次,時長共60秒 for i in {1..20};do # 此處判斷邏輯與上述腳本中相同 link_num_=`netstat -antp | grep 5081 | grep "ESTABLISHED" | wc -l` sleep 3s if [ $link_num_ == 1 ];then echo $date ">>>重新連接成功!" break; fi if [ $i == 20 ];then echo $date ">>>重新連接失敗 , 發送企微消息" # 通過curl命令工具請求企業微信群機器人的webhook_url,發送消息通知到企業微信 curl '//qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d ' { "msgtype": "markdown", "markdown": { "content": "<font color=\"warning\">大屏監控消息</font>\n > 影響範圍:<font color=\"comment\">開發環境 120.48.19.238</font>\n > 狀態:<font color=\"comment\">當前嘗試連接失敗!</font>" } }' fi done } #echo "=============== 監控 大屏數據 bcs 連接 開始! ===================" link_num=`netstat -antp | grep 5081 | grep "ESTABLISHED" | wc -l` if [ $link_num = 0 ];then re_connet # 調用重連函數 else echo $date ">>>連接依舊存在!" fi
再創建一個腳本,用於生成日誌文件,內容如下:
#!/bin/bash sh /home/watch.sh >> /home/log_watch.log &
配置定時任務,5分鐘執行一次。測試環境,手動停止B項目的後台服務後,企業微信通知效果如下:
七、實施解決方案
我們採用的是Shell腳本中發送企微通知的方案,這樣更有利於節約資源。在測試環境驗證通過後,即可在生產環境進行部署,步驟同測試環境中的部署步驟一致。
小結
以上就是基於xx後台服務監控告警的一次「測試右移」的實踐過程:
- 作為項目的測試人員,除了要完成項目測試的基本工作,還應當能夠及時跟進問題回饋、了解問題背後的真實原因、參與討論解決方案,驅動問題解決,從而「變被動為主動」;
- 確切地說,上述解決方案並不是上上之選,是在結合時間、風險、人力等項目實際情況,綜合評定後所做的選擇。截至目前,項目一直平穩運行,未再出現前面項目群中回饋的無數據問題。當然,沒有問題回饋並不代表就可以高枕無憂,
更多測試開發乾貨,歡迎關注!