再談ESB匯流排的高可用(10.17)
在10.11日已經寫過一篇從心跳檢查,叢集和HA,分域部署,流量控制等多方面來保證ESB服務匯流排的高可用性,今天就高可用性再做一些思考和總結。對於叢集,分域部署等在前面已經談過的內容不再重複。
ESB本身叢集節點故障
首先,不能因為叢集中的單個節點故障導致整個叢集不可用或出現服務異常呼叫。這個我在前面也談過到,最怕的就是叢集節點本身是假死狀態,即埠仍然還能訪問到,但是介面服務呼叫卻耗時很長或超時,這就直接導致負載均衡仍然會將請求分發到該節點,導致故障。
其次就是在遭遇大資料量呼叫的時候,會出現第二種情況,即將負載均衡中的某一個計算節點調出故障後,新的大資料量訪問請求直接路由到新的計算節點,導致整個叢集中的所有計算節點大面積出現故障。這個時候往往只能夠重啟整個OSB服務叢集才能夠解決問題。這將直接引起整個叢集和服務不可用狀態,影響很大。
對於第一種情況,仍然需要有一個實時監控的探針,這個探針最好的就是做一個模擬服務實時去呼叫,該服務可以是訪問管控資料庫的一個服務,如果發現服務耗時很長,特別是總時長明顯大於源時長10倍以上,總耗時又在20秒甚至更長,那麼最好的方式就是需要將該節點從叢集中禁用掉,或者自動對該節點進行重啟。
當然,如果是大資料量併發服務引起的額,我們仍然需要啟用前面講過的流量控制機制,即對於訊息報文大於某個基準值,則直接拒絕服務請求訪問,以變快速的釋放JVM記憶體和訪問連線。
源端業務系統出現故障
源端業務系統出現故障,實際上有兩種情況,一種就是源端業務系統本身假死,即仍然是能夠接收ESB匯流排傳遞過去的訪問請求,連線一直佔有並保持,要到300或600秒超時才返回超時的錯誤。還有一直情況就是源端本身就不可用,比如埠本身就無法訪問到了,這個時候會在<10秒內就報出連線超時的錯誤。
對於本身連線超時對ESB匯流排影響不大,即可以快速的得到源端的響應和返回,同時釋放連線。而對於第一種假死情況,則影響很大,並不是佔有太多JVM記憶體無法釋放,而是大量的佔有Session連線池中的會話連線,將直接導致有新的服務呼叫請求無法獲取連線的情況,即出現大量的新服務請求無法獲取連線情況。
對於源端訪問1-2秒,而整個ESB服務返回耗時>100秒甚至更長的情況,往往並不一定是因為記憶體原因導致,還是有用無法從可用連線池獲取連線,導致進行排隊引起。如果這個假設成立,那麼重點就是在於如何快速的清理和釋放出可用連線是關鍵。
對於ESB匯流排有一個總的連線池,比如2000,那麼這個執行緒池是公有的,如果資源全部被長連線佔用完畢,那麼新請求就無法獲取到新連線,導致耗時很長或連線超時。
當發現源業務系統出現不可用,有幾張操作方式,一種就是對該系統提供的所有服務取消服務授權,提示服務處於不可用狀態服務訪問。其次就是直接將ESB叢集中部署的服務禁用掉。對於第一種情況管控可以記錄日誌,但是對於第二種情況則管控服務記錄日誌。
那麼能否是自動去檢測源端服務,如果發現服務不可用,則自動禁用服務。當發現源服務恢復後,自動對服務進行啟用,如果能夠做到這種方式往往是一種最佳方案。
消費端業務系統出現大併發,大資料量呼叫
這種場景下,可能消費系統和提供系統都沒有問題,但是由於傳輸的資料量太大,導致ESB匯流排本身的管道破裂或記憶體溢位。這是ESB匯流排出現問題很場景的一種情況。
對於這種情況,前面也講到必須進行基於資料量的流量控制,該控制既包括了入口流控,也把控了出口流控,首先計算pipeline in 和 out的資料量,如果大於基準值則對服務呼叫進行中斷並返回異常資訊,以便於快速的釋放連線並對JVM記憶體進行垃圾回收。
前面也講到過,對於大併發短耗時呼叫,對於小併發大資料量呼叫等場景,ESB服務匯流排處理起來都無問題,即都不會造成連線被佔用滿服務是否或JVM記憶體佔滿無法垃圾回收的問題。真正導致問題的往往都是大資料量大併發引起的長耗時呼叫。因此對於這種呼叫情況必須密切關注。
業務系統停機引起的服務不可用
先說源端業務系統停機,如果服務仍然允許呼叫,那麼就會出現前面說的問題,大量服務呼叫失敗或大量佔有連線導致其它可用的服務也出現無法呼叫的情況。因此對於業務系統停機這種情況,原來處理方式都是手工對ESB匯流排提供的服務進行暫停,或對整個ESB匯流排叢集也進行停機,等業務系統啟動起來後再恢復和啟動ESB匯流排,當然這種方式下會導致整個ESB匯流排不可用的問題,並不是一直很好的方式。
舉一個場景來說,如果ERP系統需要停機發版,那麼最好的方式就是對ERP提供的所有服務進行臨時禁用,同時在ESB系統重啟恢復後,再對ESB提供的服務進行啟用。
當然,是否可以考慮一直更加智慧的方式來處理,即在管控系統裡面維護各個業務系統的停機時間,在服務消費或呼叫時,如果發現該業務系統在停機時間間隔,則直接返回請求拒絕或停機提示通知,而過了停機間隔期後又自動通過所有服務請求。相對來說這是一隻比較好的實現方式。
遺留思考問題點
1. 對於執行緒池連線不夠用的時候,是否能夠對長時間的連線自動進行中斷處理以釋放連線?
2. 對於記憶體無法回收記憶體不夠用的時候,能否對大資料量呼叫的連線進行中斷以是否內容?
3. 能否進一步在前端,比如流量控制裝置上面啟用相應的資料量和併發請求的流控機制?