掌门教育微服务体系 Solar | 阿里巴巴 Nacos 企业级落地中篇
聯席作者:吳毅挺 任浩軍 童子龍
鄭重鳴謝:Nacos - 彥林,Spring Cloud Alibaba - 小馬哥、洛夜,Nacos 社區 - 張龍(pader)、春少(chuntaojun)
相關文章推薦:
- 掌門教育微服務體系 Solar | 阿里巴巴 Nacos 企業級落地上篇
前言
在高速發展的時候,公司規模越來越大,老師人數越來越多,這時候公司不能鋪太多人去做運營與服務,必須提高每個人效,這就需要技術驅動。因此掌門教育轉變成一家技術驅動型的公司,如果被迫成為一家靠資金驅動的公司就活不下去了。
– 張翼(掌門教育創始人兼 CEO)
掌門教育自 2014 年正式轉型在線教育以來,秉承“讓教育共享智能,讓學習高效快樂”的宗旨和愿景,經歷云計算、大數據、人工智能、 AR / VR / MR 以及現今最火的 5G ,一直堅持用科技賦能教育。掌門教育的業務近幾年得到了快速發展,特別是今年的疫情,使在線教育成為了新的風口,也給掌門教育新的機遇。
隨著業務規模進一步擴大,流量進一步暴增,微服務數目進一步增長,使老的微服務體系所采用的注冊中心 Eureka 不堪重負,同時 Spring Cloud 體系已經演進到第二代,第一代的 Eureka 注冊中心已經不大適合現在的業務邏輯和規模,同時它目前被 Spring Cloud 官方置于維護模式,將不再向前發展。如何選擇一個更為優秀和適用的注冊中心,這個課題就擺在了掌門人的面前。經過對 Alibaba Nacos 、HashiCorp Consul等開源注冊中心做了深入的調研和比較,最終選定 Alibaba Nacos 做微服務體系 Solar 中的新注冊中心。
背景故事
兩次 Eureka 引起業務服務大面積崩潰后,雖然通過升級硬件和優化配置參數的方式得以解決,Eureka 服務器目前運行平穩,但我們依舊擔心此類事故在未來會再次發生,最終選擇落地 Alibaba Nacos 作為掌門教育的新注冊中心。
Nacos 開發篇
Nacos Eureka Sync 方案演進
① Sync 官方方案
經過研究,我們采取了官方的 Nacos Eureka Sync 方案,在小范圍試用了一下,效果良好,但一部署到 FAT 環境后,發現根本不行,一臺同步服務器無法抗住將近 660 個服務(非實例數)的頻繁心跳,同時該方案不具備高可用特點。
② Sync 高可用一致性 Hash + Zookeeper 方案
既然一臺不行,那么就多幾臺,但如何做高可用呢?
我們率先想到的是一致性 Hash 方式。當一臺或者幾臺同步服務器掛掉后,采用 Zookeeper 臨時節點的 Watch 機制監聽同步服務器掛掉情況,通知剩余同步服務器執行 reHash ,掛掉服務的工作由剩余的同步服務器來承擔。通過一致性 Hash 實現被同步的業務服務列表的平均分配,基于對業務服務名的二進制轉換作為 Hash 的 Key 實現一致性 Hash 的算法。我們自研了這套算法,發現平均分配的很不理想,第一時間懷疑是否算法有問題,于是找來 Kafka 自帶的算法(見 Utils.murmur2 ),發現效果依舊不理想,原因還是業務服務名的本身分布就是不平均的,于是又回到自研算法上進行了優化,基本達到預期,下文會具體講到。但說實話,直到現在依舊無法做到非常良好的絕對平均。
③ Sync 高可用主備 + Zookeeper 方案
這個方案是個小插曲,當一臺同步服務器掛掉后,由它的“備”頂上,當然主備切換也是基于 Zookeeper 臨時節點的 Watch 機制來實現的。后面討論下來,主備方案,機器的成本很高,實現也不如一致性 Hash 優雅,最后沒采用。
④ Sync 高可用一致性 Hash + Etcd 方案
折騰了這么幾次后,發現同步業務服務列表是持久化在數據庫,同步服務器掛掉后 reHash 通知機制是由 Zookeeper 來負責,兩者能否可以合并到一個中間件上以降低成本?于是我們想到了 Etcd 方案,即通過它實現同步業務服務列表持久化 + 業務服務列表增減的通知 + 同步服務器掛掉后 reHash 通知。至此方案最終確定,即兩個注冊中心( Eureka 和 Nacos )的雙向同步方案,通過第三個注冊中心( Etcd )來做橋梁。
⑤ Sync 業務服務名列表定時更新優化方案
解決了一致性 Hash 的問題后,還有一個潛在風險,即官方方案每次定時同步業務服務的時候,都會去讀取全量業務服務名列表,對于業務服務數較少的場景應該沒問題,但對于我們這種場景下,這么頻繁的全量去拉業務服務列表,會不會對 Nacos 服務器的性能有所沖擊呢?接下去我們對此做了優化,取消全量定時讀取業務服務名列表,通過 DevOps 的發布系統平臺實施判斷,如果是遷移過來的業務服務或者新上 Nacos 的業務服務,由發布平臺統一調用 Nacos 接口來增加新的待同步業務服務 Job,當該業務服務全部遷移完畢后,在官方同步界面上刪除該同步業務服務 Job 即可。
⑥ Sync 服務器兩次擴容
方案實現后,上了 FAT 環境上后沒發現問題(此環境,很多業務服務只部署一個實例),而在 PROD 環境上發現存在雙向同步丟心跳的問題,原因是同步服務器來不及執行排隊的心跳線程,導致 Nacos 服務器無法及時收到心跳而把業務服務踢下來。我們從 8 臺 4C8G 同步服務器擴容到 12 臺,情況好了很多,但觀察下來,還是存在一天內存在一些業務服務丟失心跳的情況,于是我們再次從 12 臺 4C8G 同步服務器擴容到 20 臺,情況得到了大幅改善,但依舊存在某個同步服務器上個位數丟失心跳的情況,觀察下來,那臺同步服務器承受的某幾個業務服務的實例數特別多的情況,我們在那臺同步服務器調整了最大同步線程數,該問題得到了修復。我們將繼續觀察,如果該問題仍舊復現,不排除升級機器配置到 8C16G 來確保 PROD 環境的絕對安全。
至此,經過 2 個月左右的努力付出,Eureka 和 Nacos 同步運行穩定, PROD 環境上同步將近 660 個服務(非實例數),情況良好。
非常重要的提醒:一致性 Hash 的虛擬節點數,在所有的 Nacos Sync Server 上必須保持一致,否則會導致一部分業務服務同步的時候會被遺漏。
Nacos Eureka Sync 落地實踐
① Nacos Eureka Sync 目標原則
-
注冊中心遷移目標
- 過程并非一蹴而就的,業務服務逐步遷移的過程要保證線上調用不受影響,例如, A 業務服務注冊到 Eureka 上, B 業務服務遷移到 Nacos ,A 業務服務和 B 業務服務的互相調用必須正常;
- 過程必須保證雙注冊中心都存在這兩個業務服務,并且目標注冊中心的業務服務實例必須與源注冊中心的業務服務實例數目和狀態保持實時嚴格一致。
-
注冊中心遷移原則
- 一個業務服務只能往一個注冊中心注冊,不能同時雙向注冊;
- 一個業務服務無論注冊到 Eureka 或者 Nacos,最終結果都是等效的;
- 一個業務服務在絕大多數情況下,一般只存在一個同步任務,如果是注冊到 Eureka 的業務服務需要同步到 Nacos ,那就有一個 Eureka -> Nacos 的同步任務,反之亦然。在平滑遷移中,一個業務服務一部分實例在 Eureka 上,另一部分實例在 Nacos 上,那么會產生兩個雙向同步的任務;
- 一個業務服務的同步方向,是根據業務服務實例元數據( Metadata )的標記 syncSource 來決定。
② Nacos Eureka Sync 問題痛點
- Nacos Eureka Sync 同步節點需要代理業務服務實例和 Nacos Server 間的心跳上報。Nacos Eureka Sync 將心跳上報請求放入隊列,以固定線程消費,一個同步業務服務節點處理的服務實例數超過一定的閾值會造成業務服務實例的心跳發送不及時,從而造成業務服務實例的意外丟失。
- Nacos Eureka Sync 節點宕機,上面處理的心跳任務會全部丟失,會造成線上調用大面積失敗,后果不堪設想。
- Nacos Eureka Sync 已經開始工作的時候,從 Eureka 或者 Nacos 上,新上線或者下線一個業務服務(非實例),都需要讓 Nacos Eureka Sync 實時感知。
③ Nacos Eureka Sync 架構思想
- 從各個注冊中心獲取業務服務列表,初始化業務服務同步任務列表,并持久化到 Etcd 集群中;
- 后續遷移過程增量業務服務通過 API 接口持久化到 Etcd 集群中,業務服務遷移過程整合 DevOps 發布平臺。整個遷移過程全自動化,規避人為操作造成的遺漏;
- 同步服務訂閱 Etcd 集群獲取任務列表,并監聽同步集群的節點狀態;
- 同步服務根據存活節點的一致性 Hash 算法,找到處理任務節點,后端接口通過 SLB 負載均衡,刪除任務指令輪詢到的節點。如果是自己處理任務則移除心跳,否則找到處理節點,代理出去;
- 同步服務監聽源注冊中心每個業務服務實例狀態,將正常的業務服務實例同步到目標注冊中心,保證雙方注冊中心的業務服務實例狀態實時同步;
- 業務服務所有實例從 Eureka 到 Nacos 后,需要業務部門通知基礎架構部手動從 Nacos Eureka Sync 同步界面摘除該同步任務。
④ Nacos Eureka Sync 方案實現
基于官方的 Nacos Sync 做任務分片和集群高可用,目標是為了支持大規模的注冊集群遷移,并保障在節點宕機時,其它節點能快速響應,轉移故障。技術點如下,文中只列出部分源碼或者以偽代碼表示:
詳細代碼,請參考:https://github.com/zhangmen-tech/nacos
服務一致性 Hash 分片路由
- 根據如圖 1 多集群部署,為每個節點設置可配置的虛擬節點數,使其在 Hash 環上能均勻分布;
- 根據業務服務名的 FNV1_32_HASH 算法計算每個業務服務的哈希值,計算該 Hash 值順時針最近的節點,將任務代理到該節點。
同步節點宕機故障轉移
- 節點監聽:監聽其它節點存活狀態,配置 Etcd 集群租約 TTL , TTL 內至少發送 5 個續約心跳以保證一旦出現網絡波動避免造成節點丟失;
-
節點宕機:其中某個節點宕機,其任務轉移到其它節點,因為有虛擬節點的緣故,所以此節點的任務會均衡 ReSharding 到其它節點,那么,集群在任何時候,任務處理都是分片均衡的,如圖 2 中, B 節點宕機, ##1 、 ##2 虛擬節點的任務會分別轉移到 C 和 A 節點,這樣避免一個節點承擔宕機節點的所有任務造成剩余節點連續雪崩;
-
節點恢復:如圖 3,節點的虛擬節點重新添加到 Hash 環中, Sharding 規則變更,恢復的節點會根據新的 Hash 環規則承擔其它節點的一部分任務。心跳任務一旦在節點產生都不會自動消失,這時需要清理其它節點的多余任務(即重新分配給復蘇節點的任務),給其它節點減負(這一步非常關鍵,不然也可能會引發集群的連續雪崩),保障集群恢復到最初正常任務同步狀態;
- 節點容災:如果 Etcd 集群連接不上,則存活節點從配置文件中獲取,集群正常運作,但是會失去容災能力。
Nacos Eureka Sync 保障手段
① Nacos Eureka Sync 同步界面
從如下界面可以保證,從 Eureka 或者 Nacos 上,新上線或者下線一個業務服務(非實例),都能讓 Nacos Eureka Sync 實時感知。但我們做了更進一層的智能化和自動化:
- 新增同步:結合 DevOps 發布平臺,當一個業務服務(非實例)新上線的時候,智能判斷它是從哪個注冊中心上線的,然后回調 Nacos Eureka Sync 接口,自動添加同步接口,例如,A 業務服務注冊到 Eureka 上,DevOps 發布平臺會自動添加它的 Eureka -> Nacos 的同步任務,反之亦然。當然從如下界面的操作也可實現該功能;
- 刪除同步:由于 DevOps 發布平臺無法判斷一個業務服務(非實例)下線,或者已經遷移到另一個注冊中心,已經全部完畢(有同學會反問,可以判斷的,即查看那個業務服務的實例數是否是零為標準,但我們應該考慮,實例數為零在網絡故障的時候也會發生,即心跳全部丟失,所以這個判斷依據是不嚴謹的),交由業務人員來判斷,同時配合釘釘機器人告警提醒,由基礎架構部同學從如下界面的操作實現該功能;
② Nacos Eureka Sync Etcd 監控
從如下界面可以監控到,業務服務列表是否在同步服務的集群上呈現一致性 Hash 均衡分布。
③ Nacos Eureka Sync 告警
- 業務服務同步完畢告警
Nacos Eureka Sync 升級演練
- 7 月某天晚上 10 點開始, FAT 環境進行演練,通過自動化運維工具 Ansible 兩次執行一鍵升級和回滾均沒問題;
- 晚上 11 點 30 開始,執行災難性操作,觀察智能恢復狀況, 9 臺 Nacos Eureka Sync 掛掉 3 臺的操作,只丟失一個實例,但 5 分鐘后恢復(經調查,問題定位在 Eureka 上某個業務服務實例狀態異常);
- 晚上 11 點 45 開始,繼續掛掉 2 臺,只剩 4 臺,故障轉移,同步正常;
- 晚上 11 點 52 開始,恢復 2 臺,Nacos Eureka Sync 集群重新均衡 ReHash ,同步正常;
- 晚上 11 點 55 開始,全部恢復,Nacos Eureka Sync 集群重新均衡 ReHash ,同步正常;
- 12 點 14 分,極限災難演練, 9 臺掛掉 8 臺,剩 1 臺也能抗住,故障轉移,同步正常;
- 凌晨 12 點 22 分,升級 UAT 環境順利;
- 凌晨 1 點 22,升級 PROD 環境順利;
- 容災恢復中的 ReHash 時間小于 1 分鐘,即 Nacos Eureka Sync 服務大面積故障發生時,恢復時間小于 1 分鐘。
作者介紹
- 吳毅挺,掌門技術副總裁,負責技術中臺和少兒技術團隊。曾就職于百度、eBay 、攜程,曾任攜程高級研發總監,負責從零打造攜程私有云、容器云、桌面云和 PaaS 平臺。
- 任浩軍,掌門基礎架構部負責人。曾就職于平安銀行、萬達、惠普,曾負責平安銀行平臺架構部 PaaS 平臺 Halo 基礎服務框架研發。10 多年開源經歷,Github ID:@HaojunRen,Nepxion 開源社區創始人,Nacos Group Member,Spring Cloud Alibaba & Nacos & Sentinel & OpenTracing Committer。
參與 Nacos 落地的基礎架構部成員,包括:
- 童子龍,張彬彬,廖夢鴿,張金星,胡振建,謝璐,謝慶芳,伊安娜
“阿里巴巴云原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦云原生流行技術趨勢、云原生大規模的落地實踐,做最懂云原生開發者的公眾號。”
總結
以上是生活随笔為你收集整理的掌门教育微服务体系 Solar | 阿里巴巴 Nacos 企业级落地中篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringCloud 应用在 Kube
- 下一篇: 技术人的灵魂 3 问,阿里工程师如何解答