近年來,伺服器機房多次出現光纜被挖、機房掉電等風險事故。受此影響,支付寶、微信曾一度被迫中斷業務。多機房部署在提升訪問速度的同時,能夠有效應對極端故障事件,一舉多得。
隨著易盾驗證碼使用者量的增多,特別是海外使用者的增長,原有單機房的架構已無法支援業務的發展。易盾引入多機房後,使用者就近訪問,有助於提升驗證碼載入速度,帶來更好的使用體驗。本文主要介紹了常見的多機房部署方案,實際落地過程中遇到的問題以及對應解決方案,希望對大家有所幫助。
01 多機房的技術挑戰
1. 多機房的任務協調:請求路由和會話保持多機房後,一個請求過來後,首先確認請求要路由到哪個機房進行處理,並且保證同一個會話的所有請求都路由到同一機房處理。一般首次訪問路由是透過基於 DNS 的 GSLB 解析到某一具體機房,短時間內後續所有請求都會解析到同一機房。但是當使用者 DNS 或地理位置傳送變化後,DNS 會發生變化,如何保證繼續落到相同機房?在驗證碼的一次會話中,包括使用者的一次校驗,還包括客戶服務端的二次校驗,這兩者往往不在相同的地區,需要額外的路由機制進行保證。
2. 業務資料的強一致性:資料同步方案多機房方案中,每個機房存在自己的儲存元件,並都存在自己的讀寫操作。但大多數業務特點,都需要將各機房的業務資料在全部機房間進行共享,需要一套資料同步的方案,包括資料庫,快取,訊息佇列等元件,並且要保證資料的一致性。當然一致性的要求有高有底,各業務可選擇適合業務場景的方案。驗證碼場景對介面請求的一致性要求高,但對資料儲存和統計的一致性要求相對較低。
3. 網路延時與不穩定:跨機房網路延遲問題當使用者路由傳送變化時,會存在跨機房訪問,而機房間訪問不同於內網環境,網路質量較差,會出現不穩定的情況,特別是國內和海外機房間更是存在網路延時大,網路連線不穩定的問題。
4. 業務無感知遷移:目前易盾驗證碼已接入大量客戶,該方案必須在保證對已接入客戶無感知的情況下進行升級和遷移,包括服務不能中斷,接入方式不能變更。
02 常見的業內方案
2.1 單元化方案
目前,業務的多機房方案多是採用單元化的方式,根據業務特點將服務拆分為一個一個的單元,各個單元相對獨立,各自能進行寫操作,提升整體寫入效能。其缺點在於業務場景必須支援資料分割槽,業務改造成本高,資料同步方案複雜。
單元化方案主要分為以下2種:其一,按使用者進行劃分。一個使用者註冊後被分配到某一機房,後續該使用者的全部請求均路由到該機房進行處理。其二,按地域進行劃分。舉個例子,外賣服務天然跟地理位置有關,使用者、騎手和商家都根據地理位置拆分成多個獨立的單元,保證整個核心業務流程都在同一機房內完成,無需進行跨機房呼叫。
2.2 訊息同步方案
訊息同步方案透過訊息佇列進行機房間的資料同步,底層 DB 作為 master 提供讀寫服務,其他機房 DB 作為 slave 只提供讀服務,寫入操作透過訊息佇列傳送到主機房 DB 完成,自機房透過資料庫同步工具與主機房保持同步。該方案降低了資料同步的複雜度,透過訊息佇列保證最終一致性。這樣實施起來相對簡單,業務改造成本低,但資料一致性保證較低,要求業務能接受一定的資料延遲,適用場景有限。
03 易盾驗證碼多機房部署方案
3.1 流量排程
易盾驗證碼一次會話生命週期主要包括載入驗證碼、校驗答案、二次校驗三個步驟。
圖 | 易盾驗證碼工作流程
為了保證業務正確性,方案需要保證期間全部請求都路由到同一機房,但期間使用者瀏覽器和客戶服務端均需與易盾伺服器進行通訊,而這兩者往往不在同一網路環境。
例如,使用者可能在國外,但客戶伺服器在國內,測試使用者請求落在國外節點,而客戶服務端請求到國內機房。在這種情況下,我們必須透過一種機制將客戶服務端請求轉發到國外節點。
為此,易盾為每次驗證碼會話分配了一個機房標識,透過該標識,透過定製的閘道器轉發模組強制將該會話的全部請求路由到同一機房。整體方案如下圖所示:
首次訪問時,透過基於 DNS 的 GSLB 將使用者請求就近解析到本地機房,其原理是根據使用者的 DNS 所在的地理位置,就近返回解析結果 IP。由於此時請求未攜帶機房標識,所以會直接轉發到當前機房的後端節點處理。處理完成後,請求響應中會帶上當前機房的標識。客戶端獲取到該標識後進行儲存,並在該次會話的後續所有請求中,全面帶上該機房標識,後續的請求無論被 DNS 解析到哪個機房,都能根據該機房標識轉發到正確的機房進行處理。
該方案主要的挑戰在於各機房閘道器必須實現正確、高效的轉發,而實際業務請求如何將機房標識帶上存在不同方案。
業務請求各不相同,有些是 get 請求,標識透過 form 表達傳入,有些是 post 請求,有些介面由於不能增加欄位,需將機房標識隱藏到現有引數中,轉發邏輯維護起來較為複雜。
易盾閘道器邏輯透過 openresty+lua 指令碼實現,使用 lua 指令碼足夠靈活,可滿足複雜多變的定製需求。openresty 在效能上與 nginx 相當,解析邏輯對請求整體延遲的影響幾乎為零。
3.2 資料同步
易盾驗證碼服務底層依賴的資料儲存包括資料庫、redis、kafka、zk、圖片儲存等基礎元件,具體架構圖如下所示:
其中,資料庫層面根據業務特點,將全部的表拆分成三類:各機房共享表、各機房獨有表和中心機房特有表。只需要對第一類表進行同步即可。同步方案採用內部資料庫同步工具 NDC 完成,NDC 透過訂閱 binlog,提供應用層資料同步能力,同步延遲在 ms 級,穩定性和效能可以得到保證。
kafka 主要用於資料非同步計算和儲存,業務上進行解耦,對訊息延遲有 一定的容忍性。在實現上,各機房將訊息傳送至各自私有的 kafka 叢集,統一在中心機房進行消費處理,藉助於一個自研的資料同步中介軟體,完成訊息的同步。其原理可簡單理解為,從一個 kafka 叢集消費訊息後,發往另外一個 kafka 叢集。
值得注意的是,傳送者和消費者應用依賴的 kafka 叢集面臨跨區域網路不穩定的問題。中介軟體解耦能輕鬆解決這一問題。因此,網路問題集中交給中介軟體來解決。
圖片訪問由於使用 cdn 進行分發,天然就具備多機房就近訪問的特性,無需單獨進行處理。圖片上傳則需要考慮合理的寫入方案,由於圖片為讀多寫少操作,並且上傳多為非同步操作,能夠容忍一定的網路延遲,所以各機房共用一套圖片儲存服務。
redis 為快取服務,用於高併發低延遲資料訪問場景。為了保證快取的高效能,各機房獨立部署 redis 叢集,資料不進行機房間同步,由業務上進行拆分,保證各機房間快取資料無相互依賴。
3.3 網路最佳化
無論是資料同步方案,還是路由轉發方案,都存在跨機房網路呼叫的場景。由於機房間物理距離遠,網路鏈路複雜,網路質量相較機房內網路會差很多,特別是國內機房與國外機房則更為嚴重,網路呼叫的延遲高,甚至可能會存在由於網路波動導致短時間網路中斷的現象。
為了最佳化國內外網路問題,網易在香港設定國際網路節點,透過專線從北京、杭州、廣州一直到香港貫穿整個網易自有IDC環境,透過 PNI(Private Network Interconnection)對接了 AWS、Twitch,透過 IX(Internet Exchange Point)對接了 Akamai、i3D、Valve、G-core、Cloudflare、HKcable、Apple,最佳化香港機房與國內機房間的網路質量。
同時,透過與雲平臺建立 DX 通道,可以使國際雲伺服器與國內伺服器透過內網 IP 進行互聯互通,國際雲伺服器透過雲平臺公司內部的跨國海纜專線到網易香港節點,再從香港節點專線回國內。全程專線有效消除網路丟包和時延。
經過實際的網路對比測試發現,採用香港代理和不採用香港代理的方案,在網路延遲和穩定性上有明顯差異,前者效果更優。下表為請求延遲統計資料:
從上述資料可以看到平均RT降低了35%,且穩定性得到很大提升。
04 總結
驗證碼應用於各業務註冊、登入等重要業務場景,對載入失敗率和載入速度有要求。此次多機房部署有幾個關鍵:首先,結合驗證碼業務特點,易盾驗證碼方案在請求中加入機房標識,解決了請求路由和會話保持的問題。其次,方案採用業務拆分和重構,大大簡化資料同步。最後,方案透過在香港機房中轉的方式,化解國內外網路不穩定的問題。在多機房方案落地後,易盾驗證碼服務的載入速度、穩定性、極端故障應對能力都有顯著提升。