一文為你介紹ServiceComb Service-Center三大高性能優(yōu)化點

      網(wǎng)友投稿 1077 2022-05-30

      背景

      隨著業(yè)務(wù)規(guī)模不斷增長,傳統(tǒng)單體結(jié)構(gòu)變得越來越臃腫,在此背景下,單體應(yīng)用在演進的過程中,進行微服務(wù)化拆分改造,成為主流的演進方向,逐步衍生出了微服務(wù)架構(gòu)。

      在微服務(wù)架構(gòu)中,注冊中心是最核心的組件之一,它承擔(dān)著數(shù)量龐大的不同微服務(wù)之間的動態(tài)尋址問題。如下圖:

      注冊中心架構(gòu)按CAP定理可以分為AP和CP兩種架構(gòu),現(xiàn)在市面上的注冊中心CP架構(gòu)的注冊中心有zk,etcd,nacos1.0等,AP架構(gòu)的有:eureka,nacos2.0等。

      ServiceComb Service-Center簡介

      ServiceComb項目是華為開源的微服務(wù)框架,于 2017 年 11 月捐贈給 Apache 社區(qū)并啟動孵化。作為一站式微服務(wù)解決方案,ServiceComb包含 java-chassis, service-center,kie, pack等多個子項目,Service-Center就是其注冊中心組件。

      Service-Center 是一個高可用、無狀態(tài)的微服務(wù)注冊中心,基于Go 語言實現(xiàn),可提供服務(wù)實例注冊、發(fā)現(xiàn)、依賴管理、黑白名單控制等管理能力。

      隨著業(yè)務(wù)規(guī)模擴大,我們在實踐中發(fā)現(xiàn)Service-Center 1.X版本因其CP架構(gòu)設(shè)計,存在性能天花板,只能達到萬級別的實例管理能力。據(jù)此,我們開展了一系列性能優(yōu)化的探索,例如切換底層存儲(etcd換成Mongo DB)、異步批量注冊、心跳長連接等等,在實踐中性能有了顯著的提升,下面將詳細(xì)展開介紹。

      Service-Center 1.X版本架構(gòu)以及問題

      首先我們來看一下service-center 1.X版本的架構(gòu),并結(jié)合測試分析存在的幾個關(guān)鍵問題。

      雙層架構(gòu)

      Service-Center是雙層架構(gòu),分為session層(圖中SC節(jié)點)和data層(圖中etcd節(jié)點)。SC主要用于跟客戶端交互,接收注冊請求、推送實例信息等,etcd中持久化了服務(wù)信息、實例信息,同時將所有數(shù)據(jù)同步給了所有SC,充當(dāng)了一個同步器。

      Service-Center客戶端通過HTTP請求發(fā)送注冊請求到SC節(jié)點,然后SC把注冊信息存儲到etcd數(shù)據(jù)庫里,并且緩存到本地內(nèi)存中。

      provider實例客戶端會向SC層發(fā)送注冊請求和心跳請求,兩種都是HTTP請求;consumer實例客戶端會向SC層發(fā)送訂閱請求,基于websocket協(xié)議,建立websocket長連接,通過listwatch機制,獲取SC中新注冊的實例。

      Service-Center的實例信息最終會存儲到etcd數(shù)據(jù)庫中,并且其他SC通過監(jiān)聽etcd的變化,同步獲取所有實例信息。

      問題發(fā)現(xiàn)與分析

      在測試中我們發(fā)現(xiàn)了幾個問題:

      心跳請求頻繁

      實例通過心跳續(xù)約,每30s上報一次心跳,當(dāng)服務(wù)/實例規(guī)模上升時,心跳請求輪詢數(shù)量眾多。心跳請求又是基于HTTP短連接模型的,每次客戶請求都會創(chuàng)建和銷毀TCP連接,而銷毀釋放TCP連接需要一定的時間,導(dǎo)致有很多TIME_WAIT狀態(tài)的連接,這樣一來業(yè)務(wù)處理的時間小于連接建立銷毀的時間,導(dǎo)致資源空耗嚴(yán)重。

      逐條寫數(shù)據(jù)庫

      注冊數(shù)據(jù)逐條寫到etcd,每一個注冊請求都會對應(yīng)一條寫DB的操作,隨著規(guī)模的增長,對etcd的壓力顯著增大,這時寫etcd 就成為瓶頸點。

      etcd集群數(shù)據(jù)同步采用RAFT強一致算法,根據(jù)CAP理論,保證了強一致性,系統(tǒng)在可用性上就需要做出犧牲。etcd在寫操作存在性能上限,導(dǎo)致服務(wù)實例注冊速度慢;讀操作雖然SC層有緩存機制,請求量過大時,會造成對etcd讀請求壓力過大及service center內(nèi)存不夠問題。

      Service-Center 2.0版本高性能優(yōu)化

      雙層架構(gòu)

      該架構(gòu)兼容了1.X架構(gòu)的功能,并且新增了DB存儲對接Mongo DB的功能、websocket心跳長連接的功能、異步批量注冊等功能(具體的選型過程可見后面章節(jié))。

      優(yōu)化點

      1.選型調(diào)研

      對于etcd的性能限制的問題,我們對底層數(shù)據(jù)庫進行了選型,需要一個滿足最終一致性、批量操作、橫向擴展、訂閱、高可用、TTL等功能的DB,經(jīng)篩選發(fā)現(xiàn)MongoDB是一個適合的數(shù)據(jù)庫,同時還具有文檔結(jié)構(gòu)存儲方式,方便獲取數(shù)據(jù),完全能滿足性能要求。

      2.實現(xiàn)細(xì)節(jié)

      實現(xiàn)過程中,首先我們保證功能向前兼容,可以通過配置來選擇存儲使用etcd還是MongoDB,

      做到了客戶端和服務(wù)端交互無感知。

      SC實現(xiàn)了一套流程來對接mongo DB,如下圖。API、訂閱等流程復(fù)用了1.X中的邏輯,數(shù)據(jù)緩存因為跟etcd的存儲結(jié)構(gòu)存在差異,單獨實現(xiàn)了對mongo DB結(jié)構(gòu)的適配,Dao層封裝了service\instance\Dependency等資源的CRUD接口,最終通過mongo的client與mongo DB交互。

      Cache和同步實現(xiàn)

      緩存以及多個SC之間的數(shù)據(jù)同步是通過SC與mongo DB的list watch機制實現(xiàn)的。SC啟動時,會觸發(fā)list watch定時任務(wù),list操作即調(diào)用查詢所有資源接口,list操作會定時執(zhí)行,時間可以通過配置文件配置(默認(rèn)120s);而watch操作用到了MongoDB的Change Stream機制,下面詳細(xì)介紹一下。

      Mongo DB的Change Stream機制,是指通過一次Change Stream API 調(diào)用,即可從MongoDB側(cè)獲取增量修改。通過 resume token 來標(biāo)識拉取位置,只需在 API 調(diào)用時,帶上上次結(jié)果的 resume token,即可從上次的位置接著訂閱,這樣可以保證數(shù)據(jù)不丟失。

      SC啟動doWatch流程后,傳入resume token與mongo與建立watch長連接,這期間mongo DB會實時推送變更數(shù)據(jù)給SC,并更新resume token。在異常情況下,因mongo DB故障或其他原因?qū)е聎atch失敗或斷連,SC則記錄故障前的resume token,下次watch重新建立連接時傳入resume token,SC就可以接著故障前的記錄訂閱,保證了不丟數(shù)據(jù),也保證了可用性。

      Dao層封裝

      Mongo DB是文檔存儲結(jié)構(gòu),在DB里創(chuàng)建了service 、instance、dependency等集合來存儲服務(wù)、實例、依賴關(guān)系的信息。然后封裝了每個集合的CRUD操作命令,并且封裝了一些公共的過濾條件用于不同的文檔操作(查詢,更新,刪除)。在實踐中還發(fā)現(xiàn)了DB慢查詢問題,為了解決該問題,我們設(shè)計了合理的索引,然后SC在啟動流程中加上了建立索引的流程,保證有效高效的進行數(shù)據(jù)庫操作。

      當(dāng)然在DB操作方面還有一定的優(yōu)化空間,后面我們也會繼續(xù)去分析優(yōu)化方法,保證高效的數(shù)據(jù)庫操作。

      3.優(yōu)化成果

      切換Mongo DB之后與使用etcd的SC接口性能進行了對比測試,SC(8u16g*2)+Mongo DB(16u32g*2)的規(guī)格下,Mongo DB注冊服務(wù)接口TPS達到5w,相比etcd只有6k,提升了8倍,Mongo DB注冊實例接口TPS達到3w,相比etcd版本的4k,提升了7.5倍。

      1.選型調(diào)研

      因為心跳HTTP請求對資源空耗過多,于是我們分析并嘗試使用長連接來解決問題。對grpc、thrift、websocket進行了一個簡單的測試。簡單定義了傳輸消息的protobuf文件,在2臺4u8g的機子上分別部署server和client。下表是相關(guān)的測試數(shù)據(jù)(每組數(shù)據(jù)分別測了10次取了平均值):

      通過分析可知,相同條件下,thrift的資源消耗率最低,但是吞吐率最低;websocket的吞吐率最高,資源消耗也適中。我們最終選擇了websocket,是因為原有1.X架構(gòu)里SC訂閱推送用的就是websocket長連接,考慮到長連接復(fù)用問題。其實grpc也是很好的備選項,它能額外能支持stream,適合傳輸一些大數(shù)據(jù),以及服務(wù)端和客戶端長時間的數(shù)據(jù)交互,我們后期不排除會支持grpc。

      websocket長連接復(fù)用了HTTP的握手通道,客戶端通過HTTP請求與websocket服務(wù)端協(xié)商升級協(xié)議,協(xié)議升級完成后,后續(xù)的數(shù)據(jù)交換則遵照websocket協(xié)議。

      2.實現(xiàn)細(xì)節(jié)

      在實例注冊完之后,客戶端發(fā)送HTTP心跳請求,SC接收到心跳請求后把HTTP協(xié)議升級為websocket協(xié)議, 然后SC通過websocket長連接每30s發(fā)送一次ping請求給客戶端,客戶端則返回 pong 請求給SC,這樣SC就能知道實例是否還在線。

      SC收到心跳之后,還會去更新DB中實例的modTimestamp列,這是為了配合Mongo DB的TTL索引機制,來保證SC故障場景沒有數(shù)據(jù)殘留,后面文章會詳細(xì)說明。

      實例正常下線時候,會主動調(diào)用注銷接口的,但不排除有些實例可能意外下線了,還沒來得及調(diào)用注銷接口,這時候SC發(fā)送ping請求給客戶端,就無法得到響應(yīng)了,這樣SC識別到心跳超時,就會主動去刪除DB中存儲的實例信息,保證實例及時下線。

      當(dāng)所有SC實例故障時,websocket連接斷連,注銷接口也無法調(diào)用,這時DB中的實例就可能永遠(yuǎn)無法下線了,為了解決這個問題我們用到了Mongo DB的TTL索引機制。

      TTL全稱是(Time To Live), TTL索引能對一個單列配置過期屬性來實現(xiàn)對文檔的自動過期刪除,我們對實例的modTimestamp列創(chuàng)建TTL索引,默認(rèn)設(shè)置expireAfterSeconds為300s, 這樣 Mongo DB會自動去清理超過300s沒有報心跳的實例。

      3.優(yōu)化成果

      實現(xiàn)心跳長連接之前,SC(8u16g)規(guī)格下實例數(shù)量到3w時, SC節(jié)點因為HTTP連接建立斷開的空耗,開始出現(xiàn)注冊階段CPU過高的情況,優(yōu)化為長連接之后,實例注冊節(jié)點運行更加穩(wěn)定,CPU消耗減少一半,總體支持的數(shù)量也明顯提升。

      前期測試

      發(fā)現(xiàn)逐條注冊對DB的壓力問題之后,通過調(diào)研和測試發(fā)現(xiàn)批量寫相比逐條寫TPS能提升8倍,所以我們決定實現(xiàn)一套異步批量注冊流程,來滿足大規(guī)模、高性能的場景。

      實現(xiàn)細(xì)節(jié)

      左邊是實例異步批量注冊的流程圖,右邊是實例逐條注冊的流程圖:

      默認(rèn)使用逐條注冊流程,如果規(guī)模大,對高性能有要求的場景可以開啟異步批量注冊。

      正常情況:

      異步注冊收到實例注冊請求后,把實例注冊信息放入隊列,最終通過定時任務(wù)批量注冊到MongoDB中(默認(rèn)100ms)。

      異常情況下:

      如果Mongo和服務(wù)中心的連接斷開,注冊失敗,實例會被放入失敗隊列重新注冊;

      如果連續(xù)3次注冊失敗,熔斷器會控制暫停5s,注冊成功后恢復(fù);

      單個實例注冊失敗超過一定次數(shù)(默認(rèn)500次),該實例將被丟棄,當(dāng)心跳發(fā)現(xiàn)該實例不存在時SDK會重新注冊。

      測試結(jié)果

      通過異步注冊,提升了注冊速度,降低了mongo DB的消耗,SC(8u16g*2)+Mongo DB(16u32g*2)的規(guī)格下異步注冊實例接口TPS由3w,上升到9w,性能提高三倍。

      Service-Center 整體性能測試

      測試方法

      我們進行了模擬真實場景進行測試,按1:1部署provider和consumer服務(wù)實例,consumer向SC訂閱若干個服務(wù),然后調(diào)用provider。

      部署模式,如下圖所示:

      Client端部署

      一文為你介紹ServiceComb Service-Center三大高性能優(yōu)化點

      通過K8S集群部署provider deployment和consumer deployment,來模擬實例上下線,通過修改deployment的副本數(shù)來增加pod個數(shù),每個Pod里面部署200個實例進程,可以通過部署100、200、400個pod來模擬2w、4w、8w實例的注冊。

      Service-Center部署

      總資源為24u48g,兩臺4u8g虛機,兩臺8u16g虛機。

      SC采用雙節(jié)點部署,部署在4u8g節(jié)點。

      Mongo DB采用副本集模式,主從節(jié)點分別部署在兩臺8u16g節(jié)點上, 因為mongo DB的仲裁節(jié)點,資源消耗較低,所以跟SC其中一個節(jié)點部署在一起。

      測試方法:

      provider和consumer, 按1:1的比例部署,先創(chuàng)建provider,再部署consumer,分別測試每個consumer訂閱2、5、10個provider服務(wù)的情況。

      性能測試報告

      在24u48g的資源下,測試報告如下表:

      24u48g規(guī)格下Service-Center能支持的最大實例數(shù)量為8w。此時SC內(nèi)存達到了80%,繼續(xù)往上注冊實例SC節(jié)點在注冊階段容易出現(xiàn)OOM,導(dǎo)致節(jié)點崩潰。

      當(dāng)consumer訂閱數(shù)量上漲的時候,最大能支撐的服務(wù)數(shù)量略有下降,訂閱2個服務(wù)時,最大能穩(wěn)定支撐8w實例,而訂閱5個和10個服務(wù)的時候,分別最大能支撐到7w、6w實例。

      把資源擴大到32u64g后,Service-Center最大能支撐16w實例。

      相比其他注冊中心性能

      同樣在24u48g的資源下,我們測試了國內(nèi)某流行開源注冊中心的性能,結(jié)果如下表:

      24u48g規(guī)格下,該注冊中心最大支撐實例數(shù)為4w, 當(dāng)測試注冊5w、6w實例注冊的時候系統(tǒng)就不穩(wěn)定了,該注冊中心注冊階段的CPU使用率接近100%,會出現(xiàn)集群節(jié)點崩潰的情況。

      隨著訂閱數(shù)量上漲,最大支持的服務(wù)數(shù)量也會下降,性能瓶頸主要在于注冊接的階段和穩(wěn)定階段的CPU,實例數(shù)量上去CPU壓力太大導(dǎo)致注冊時候系統(tǒng)無法達到穩(wěn)定狀態(tài),系統(tǒng)會崩潰。

      測試過程中也參考了該注冊中心官方的測試方法和數(shù)據(jù),如下:

      https://nacos.io/zh-cn/blog/performance-compare.html

      Service-Center 性能測試結(jié)論

      Service-Center在24u48g的規(guī)格下能穩(wěn)定支撐8w實例,32u64g規(guī)格下,能穩(wěn)定支撐16w實例;當(dāng)前主要瓶頸在于SC(4u8g)內(nèi)存不夠, 橫向擴展SC,或者擴大SC內(nèi)存規(guī)格,支持實例的數(shù)量還有進一步上漲的空間。

      跟某開源注冊中心產(chǎn)品相比性能稍有優(yōu)勢,同等規(guī)格下能穩(wěn)定支持的實例數(shù)量更多,注冊階段系統(tǒng)更加穩(wěn)定。

      ServiceComb Service-Center未來規(guī)劃

      通過持續(xù)的分析優(yōu)化,我們也發(fā)現(xiàn)了當(dāng)前架構(gòu)還存在的一些問題,識別到可以持續(xù)改進的優(yōu)化點,抽象復(fù)用:如Mongo/etcd代碼持續(xù)抽象,保證只有數(shù)據(jù)庫對接層代碼不同,其他流程都能共用;架構(gòu)設(shè)計:如緩存結(jié)構(gòu)優(yōu)化、心跳更新批量處理、長連接優(yōu)化、Mongo DB分片、SDK親和性調(diào)度優(yōu)化等等;文檔方面也可以逐步更新、細(xì)化官方文檔細(xì)節(jié)內(nèi)容,促進討論與貢獻。爭取在持續(xù)優(yōu)化后,在真實場景下,能支持百萬級別實例管理。

      傅紫葉:目前就職于華為云HCS實驗室,從事云計算PaaS領(lǐng)域異地多活、注冊中心等方向的研究與開發(fā)

      羅健文:目前就職于華為云HCS實驗室,從事云計算PaaS領(lǐng)域微服務(wù)架構(gòu)、微服務(wù)治理等方向的研究與開發(fā)

      ServiceComb 開源 微服務(wù)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:KindEditor是一套很方便的html編譯器插件
      下一篇:使用websocket實時顯示后臺日志
      相關(guān)文章
      中文字幕专区在线亚洲| 亚洲精品国产suv一区88| 性色av极品无码专区亚洲 | 亚洲精品国产肉丝袜久久| 亚洲午夜久久久影院| 久久久久久亚洲精品不卡| 亚洲精品无码专区2| 亚洲国产精品成人久久蜜臀 | 在线综合亚洲欧洲综合网站| 亚洲va成无码人在线观看| 亚洲最大黄色网址| 亚洲午夜成激人情在线影院| 亚洲性无码av在线| 亚洲成aⅴ人在线观看| 亚洲精品国产成人| 亚洲女人初试黑人巨高清| 亚洲一欧洲中文字幕在线| 亚洲校园春色另类激情| 男人天堂2018亚洲男人天堂| 亚洲日韩AV一区二区三区四区| 亚洲精品成a人在线观看☆| 亚洲av成人无码网站…| 亚洲av再在线观看| 久久综合亚洲色HEZYO国产| 亚洲成色WWW久久网站| 亚洲国产一区二区a毛片| 亚洲色偷偷av男人的天堂| 亚洲人成网站日本片| 在线a亚洲老鸭窝天堂av高清| 亚洲国产欧美日韩精品一区二区三区 | 亚洲精品tv久久久久| 亚洲综合在线另类色区奇米| 亚洲AV无码一区二区乱子伦 | 亚洲国产成人久久综合一区| 日韩亚洲国产综合高清| 国产综合成人亚洲区| 不卡精品国产_亚洲人成在线| 久久亚洲一区二区| 亚洲国产中文在线二区三区免| 一本色道久久综合亚洲精品蜜桃冫 | 日韩色日韩视频亚洲网站|