發佈及其檢查的自動化實踐 (1) 數據庫配置錯誤 (2) Consumer和Provider的數據覈對 (3) 註冊中心狀態報告 (4) 註冊中心重啓引發大量動態數據刪寫 總結

這裏記錄的是Dubbo註冊中心的發佈過程中的自動化改進點。實踐是通用的,希望可以能給你一些借鑑和啓發。

Dubbo註冊中心記錄整個網站服務信息,服務消費者(Consumer)通過註冊中心獲得服務提供者(Provider)列表,才能完成服務調用。註冊中心是網站服務的一個關鍵組件。
# 現在一個站點的註冊中心上的服務Consumer和Provider就有35K+。

隨着註冊中心的服務越來越多,註冊中心上的功能越加越多,註冊中心上線發佈和驗證的過程變得越來越複雜繁瑣,發佈過程常常會出些問題,發佈過程變得危險重重。

應付這些複雜就是持續的改進發布及其檢查。

阿里系線上發佈有,生產環境預發佈環境 2套,這2套環境是隔離的,不同環境的註冊中心使用不同的DB。應用先在預發佈環境發佈,檢驗沒有問題後在生產環境上發佈。

發佈是由SCM來做的,通過使用不同配置文件(包含不同的DB配置)打包發佈。

人操作就會有出錯的可能。有一次SCM在生產環境配置了預發佈環境的DB。DB中有預發佈環境的Provider數據,導致線上應用出錯。

解決方法

監控註冊中心佈置目錄下數據庫配置文件值是否正常。

Dubbo註冊中心的DB信息配置在jdbc.properties文件中:

database.url=jdbc:mysql://1.2.3.4/dubbo_registry
database.username=dubbo_registry
database.password=dubbo_registry
......

監控這個配置中database ip、用戶名的值是否預期的。

PS:監控 文件的內容,URL的輸出結果,URL響應時間,硬盤、內存、網絡使用量 等等是監控系統的基本功能。

原則

人的操作是可能出錯的操作。
可能出錯的地方都加上監控,這樣出錯了就會報警出來。
這樣的監控項應該一直開着。

註冊中心的發佈後,要Consumer和Provider覈對發佈前後是否有缺失。

  • 如果沒有缺失,安心完成發佈。
  • 如果有缺失,則要處理,找出原因,比如,少的Provider是真的下線了?註冊中心原來的髒數據?自己不能處理,則要聯繫對應應用的負責人一起確認處理。

解決方法

1) 註冊中心提供URL可以Dump出Provider、Consumer的數據:(實際上也會做方便查看的頁面。)
# 提供URL是可以方便和腳本集成,可以用其它的方式。

 provider instance
dubbo://10.200.216.119:20882/com.aliyun.crm.panorama.webx.BucAclService com.aliyun.crm.panorama.webx.BucAclService:1.0.0
dubbo://10.246.130.110:20880/com.alibaba.havana.api.member.JoinService hz_idc/com.alibaba.havana.api.member.JoinService:1.0.0
dubbo://10.246.130.110:20880/com.alibaba.havana.api.member.MemberService com.alibaba.havana.api.member.MemberService:1.0.0
dubbo://10.246.130.110:20880/com.alibaba.havana.api.member.MemberService hz_idc/com.alibaba.havana.api.member.MemberService:1.0.0
dubbo://10.246.130.110:20880/com.alibaba.havana.api.member.OperatorService hz_idc/com.alibaba.havana.api.member.OperatorService:1.0.0
......

2) 在發佈的關閉腳本 和 啓動腳本中,添加邏輯:把數據Dump到文件中

wget http://127.0.0.1:${APP_PORT}/sysinfo/dump/providers \
    --timeout=15 --output-document=$DUMP_DIR/providers.dump \
    --output-file=$DUMP_DIR/providers.dump.log

3) 添加一個腳本,Diff數據前後的Provider數據。比如簡單的實現可以是

$ diff dir1/provider.dump dir2/provider.dump

直接使用diff命令輸出的格式不方便直接閱讀,可以實現更好一些。

4) 啓動完成,註冊中心穩定後,執行上面的Diff腳本,快速找到差異。

原則

對於繁瑣的檢驗操作,可以在程序添加邏輯輸出需要的數據。
在發佈腳本中Dump好需要覈對的數據。
再通過腳本來自動完成核對操作。

  • 爲了加速,註冊中心有Cache數據,比如 註冊的Provider信息先在內存中,然後異步寫入DB。如果這樣的Cache如果長時間有數據,說明有問題。
  • 執行任務的線程池狀態。如果線程池Active很高說明有問題。
  • ……

這些業務狀態在發佈過程也需要檢查。

解決方法

註冊中心有一個URL可以訪問,列出這些狀態的情況:

OK
[Cache]
FailedRegitered=0
[ThreadPool]
Active=30
Max=200
Idle=200
......

第一行是一個彙總行。
# 後面對比腳本可以忽略這一項。

這樣可以加上一個監控項,監控這個URL返回是不是OK

在發佈的時候,只要檢查這一個地方就可以拿到所有要的信息。不用到各個地方一項一項的查看。

原則

需要覈對的數據,提供邏輯可以方便的查看。
如果核對是有必要持續,則配置到監控系統中。

Provider和Consumer是動態數據,也就是Provider、Consumer斷開連接後數據會被清除。

這樣功能沒有問題,線上有個問題是,在註冊中心發佈時,註冊中心重啓,連接斷開,註冊中心啓動後,Consumer、Provider連接上來,註冊中心會要把Consumer、Provider的數據刪除和寫入,造成了數據動盪:

  • 大量數據刪除和寫入,註冊中心壓力很大。
    線上註冊中心多次因爲這個問題導致DB被大量操作Hang住,註冊中心無法完成啓動,相當驚險!
  • Consumer可能收到的Provider列表缺失的(數據不完整),會引發應用的問題。
    比如Consumer收到的Provider列表只有一個Provider,Consumer調用到一臺Provider上,會壓垮Provider,結果服務調用出現失敗。

解決方法

註冊中心可以設置warm-up狀態,發佈完成後,等待註冊中心穩定後,關閉warm-up狀態。
# “註冊中心穩定”的意思是,Provider已經重新連接上來,Provider數據不會再動盪。

在warm-up狀態時:

  • Consumer和Provider的動態數據不會刪除(寫入允許)。
  • 註冊中心不通知Consumer,Provider列表的變化不推送給Consumer。
    # 在註冊中心發佈過程中,Provider的變化很少,舊一點數據不會有問題。

有了這個功能,如果不能與發佈腳本集成,那麼發佈過程就多個人肉操作,要和發佈腳本集成。

仍然可以考慮註冊中心提供一個URL來開關warm-up狀態。

curl http://127.0.0.1:${APP_PORT}/sys/config?warmup=true
curl http://127.0.0.1:${APP_PORT}/sys/config?warmup=false

這樣在發佈開始時,發佈腳本中開啓warm-up狀態;完成發佈後等待註冊中心集羣穩定後,關閉warm-up狀態。

warm-up一個臨時狀態,長時間處於warm-up狀態會有故障。所以加上監控項:如果註冊中心是warm-up狀態,報警。
# 這個問題引發過故障,當時warm-up狀態設置還是人肉完成,結果發佈完成後忘記改回來了。
# 這個問題也引出另一個方面的思考,在我的下面這篇博文中說明: 準備一個安全可靠的發佈流程

  1. 越是容易出錯的步驟越是要多執行,越需要自動化是執行。因爲執行多了就可以發現容易出錯的步驟,進而去找出發現出錯的原因去改進,穩定可靠的執行。
  2. 自動化至關重要。當然剛開始爲了安全是手執行的,手動執行幾次後:
    • 步驟會固定下來
    • 會出錯的地方心中有數了

從上面的發現問題到自動化解決,整個過程如下圖:

發佈及其檢查的自動化

隨着發現的問題被逐步自動化,在正常的情況下,腳本運行完成返回正常,就有信心不再需要 人肉介入了。即理想情況下,發佈操作只要運行腳本的“one-line”,極簡人肉介入。
# 非正常情況,如有Provider丟失,則免不了要人肉參與,和用戶一起排查解決問題。 # 命令行的“one-line” vs. GUI的“one-click”

個人博客的博文地址:發佈及其檢查的自動化實踐

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章