測試右移-後台服務監控告警實踐

前言

前段時間,公司上線了「大屏」項目,用於對接展示一些業務平台的數據。但是在上線後使用過程中,產品或業務經常回饋前台頁面沒有數據。出現這種情況後,開發人員會去排查問題,解決後再通知產品或業務人員解決修復情況。雖然研發每次都能在較短的時間內響應並解決問題,但運行一段時間後又會反覆出現,也給用戶造成了極其不好的使用體驗。而本文則是基於「測試右移」思想,開展的一次後台服務監控告警的實踐記錄總結,整個實踐過程可以分為:

  1. 收到問題回饋;
  2. 溝通定位問題;
  3. 討論並選定解決方案;
  4. 解決方案實現;
  5. 驗證解決方案;
  6. 優化解決方案;
  7. 實施解決方案;

什麼是「測試右移」

在正式開始之前,先簡單介紹一下「測試右移」:

我們都知道,軟體測試活動應當貫穿整個軟體生命周期,包括需求討論分析階段、研發設計編碼階段、測試階段、上線後的監控運行階段。「測試右移」是在產品上線後,為了驗證在真實的用戶數據環境下,功能、性能以及產品體驗,是否符合預期而開展的一系列監控、分析、測試活動,以達到持續監控軟體線上品質的目的。一旦線上發生任何問題,則可以提前反應,主動分析,儘快處理,給用戶以良好的使用體驗。

一、收到問題回饋

從項目上線不久,即收到產品多次在項目群中回饋的以上問題。開發經過定位後,給出的說法是「後台鏈接斷掉了」。在其重啟後台服務後,該項目確實平穩運行了一段時間,但一段時間後,又會再次發生鏈接斷掉、前台無數據展示的情況。此問題給用戶造成了很不好的使用體驗。

二、溝通定位問題

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後台服務監控告警的一次「測試右移」的實踐過程:

  1. 作為項目的測試人員,除了要完成項目測試的基本工作,還應當能夠及時跟進問題回饋、了解問題背後的真實原因、參與討論解決方案,驅動問題解決,從而「變被動為主動」;
  2. 確切地說,上述解決方案並不是上上之選,是在結合時間、風險、人力等項目實際情況,綜合評定後所做的選擇。截至目前,項目一直平穩運行,未再出現前面項目群中回饋的無數據問題。當然,沒有問題回饋並不代表就可以高枕無憂,

更多測試開發乾貨,歡迎關注!