歡迎關注微信公眾號:石杉的架構筆記(id:shishan100)
周一至周五早八點半矢赁!精品技術文章準時送上!
往期文章
1.拜托妹田!面試請不要再問我Spring Cloud底層原理!
目錄:
一唬党、問題起源
二、Eureka Server設計精妙的注冊表存儲結(jié)構
三鬼佣、Eureka Server端優(yōu)秀的多級緩存機制
四驶拱、總結(jié)
一、問題起源
Spring Cloud架構體系中晶衷,Eureka是一個至關重要的組件蓝纲,它扮演著微服務注冊中心的角色,所有的服務注冊與服務發(fā)現(xiàn)晌纫,都是依賴Eureka的税迷。
不少初學Spring Cloud的朋友在落地公司生產(chǎn)環(huán)境部署時,經(jīng)常會問:
Eureka Server到底要部署幾臺機器锹漱?
我們的系統(tǒng)那么多服務箭养,到底會對Eureka Server產(chǎn)生多大的訪問壓力?
Eureka Server能不能抗住一個大型系統(tǒng)的訪問壓力凌蔬?
如果你也有這些疑問露懒,別著急闯冷!咱們這就一起去看看,Eureka作為微服務注冊中心的核心原理
下面這些問題懈词,大家先看看蛇耀,有個大概印象。帶著這些問題坎弯,來看后面的內(nèi)容纺涤,效果更佳
1、Eureka注冊中心使用什么樣的方式來儲存各個服務注冊時發(fā)送過來的機器地址和端口號抠忘?
2撩炊、各個服務找Eureka Server拉取注冊表的時候,是什么樣的頻率崎脉?
3拧咳、各個服務是如何拉取注冊表的?
4囚灼、一個幾百服務骆膝,部署上千臺機器的大型分布式系統(tǒng),會對Eureka Server造成多大的訪問壓力灶体?
5阅签、Eureka Server從技術層面是如何抗住日千萬級訪問量的?
先給大家說一個基本的知識點蝎抽,各個服務內(nèi)的Eureka Client組件政钟,默認情況下,每隔30秒會發(fā)送一個請求到Eureka Server樟结,來拉取最近有變化的服務信息
舉個例子:
庫存服務原本部署在1臺機器上养交,現(xiàn)在擴容了,部署到了3臺機器瓢宦,并且均注冊到了Eureka Server上层坠。
然后訂單服務的Eureka Client會每隔30秒去找Eureka Server拉取最近注冊表的變化,看看其他服務的地址有沒有變化刁笙。
除此之外,Eureka還有一個心跳機制谦趣,各個Eureka Client每隔30秒會發(fā)送一次心跳到Eureka Server疲吸,通知人家說,哥們前鹅,我這個服務實例還活著摘悴!
如果某個Eureka Client很長時間沒有發(fā)送心跳給Eureka Server,那么就說明這個服務實例已經(jīng)掛了舰绘。
光看上面的文字蹂喻,大家可能沒什么印象葱椭。老規(guī)矩!咱們還是來一張圖口四,一起來直觀的感受一下這個過程孵运。
二、Eureka Server設計精妙的注冊表存儲結(jié)構
現(xiàn)在咱們假設你手頭有一套大型的分布式系統(tǒng)蔓彩,這套系統(tǒng)一共有100個服務治笨,每個服務部署在20臺機器上,機器是4核8G的標準配置赤嚼。
這相當于什么呢旷赖?也就是說相當于你一共部署了100 * 20 = 2000個服務實例,有2000臺機器更卒。
而每臺機器上的服務實例內(nèi)部都有一個Eureka Client組件等孵,這個Eureka Client組件每隔30秒會請求一次Eureka Server來拉取變化的注冊表。
此外蹂空,每個服務實例上的Eureka Client都會每隔30秒發(fā)送一次心跳請求給Eureka Server俯萌。
那么大家算算,Eureka Server作為一個微服務注冊中心腌闯,每秒鐘要被請求多少次绳瘟?一天要被請求多少次?
● 很簡單姿骏,我們就按最標準的算法來算糖声,即每個服務實例每分鐘請求2次拉取注冊表,每分鐘請求2次發(fā)送心跳
● 這樣的話分瘦,一個服務實例每分鐘會請求4次蘸泻,2000個服務實例每分鐘請求8000次
● 換算到每秒鐘,則是8000 / 60 = 133次左右嘲玫,我們直接可以大概估算為Eureka Server每秒鐘會被請求150次
● 所以悦施,一天的話,應該就是8000 * 60 * 24 = 1152萬去团,也就是每天千萬級訪問量
好抡诞!經(jīng)過這么一個測算,大家是否發(fā)現(xiàn)這里的奧秘了土陪?
● 首先第一點昼汗,對于微服務注冊中心這種組件,在一開始設計他這個注冊表的拉取頻率以及心跳發(fā)送頻率的時候鬼雀,就已經(jīng)考慮到了一個大型系統(tǒng)的各個服務請求時的壓力顷窒,每秒會承載多大的請求量。
● 所以說各個服務實例每隔30秒發(fā)起一次請求拉取變化的注冊表源哩,以及每隔30秒發(fā)送一次心跳給Eureka Server鞋吉,其實這個時間安排是有他的用意的鸦做。
按照我們的測算,一個上百個服務谓着,部署幾千臺機器的大規(guī)模系統(tǒng)泼诱,按照這樣的一個頻率請求Eureka Server,日請求量在千萬級漆魔,每秒的訪問量應該是固定在150次左右坷檩,即使算上其他的一些額外操作,算到每秒鐘請求Eureka Server在200次~300次吧改抡。
所以通過設置一個適中的拉取注冊表以及發(fā)送心跳的頻率矢炼,保證大規(guī)模系統(tǒng)里對Eureka Server的請求壓力不會太大。
那么關鍵問題來了阿纤,Eureka Server是如何保證輕松抗住這每秒數(shù)百次請求句灌,每天千萬級請求的呢?
要搞清楚這個欠拾,首先得清楚人家Eureka Server到底是用什么來存儲注冊表的胰锌?三個字,看源碼藐窄!
接下來咱們就一起進入Eureka的源碼里一探究竟:
● 如上圖所示资昧,圖中名為registry的CocurrentHashMap,就是注冊表的核心結(jié)構荆忍「翊看完之后忍不住先贊嘆一下,精妙的設計刹枉!
● 從代碼中可以看到叽唱,Eureka Server的注冊表直接基于純內(nèi)存,就是在內(nèi)存里維護了一個數(shù)據(jù)結(jié)構微宝。
● 各個服務發(fā)起注冊棺亭、服務下線、服務故障蟋软,全部會在內(nèi)存里維護和更新這個注冊表镶摘。
● 各個服務每隔30秒拉取注冊表的時候,其實Eureka Server就是直接提供內(nèi)存里存儲的有變化的注冊表數(shù)據(jù)給他們就可以了岳守。
● 同樣钉稍,每隔30秒發(fā)起心跳的時候,也是在這個純內(nèi)存的CocurrentHashMap數(shù)據(jù)結(jié)構里更新心跳時間棺耍。
一句話概括:維護注冊表、拉取注冊表种樱、更新心跳時間蒙袍,全部發(fā)生在內(nèi)存里俊卤!這就是Eureka Server非常核心的一個點。
搞清楚了這一點害幅,咱們再來分析一下這個叫做registry的東西的數(shù)據(jù)結(jié)構消恍,大家千萬別被它復雜的外表唬住了,沉下心來以现,一層層的分析狠怨!
● 首先,這個ConcurrentHashMap的key就是服務名稱邑遏,比如說“inventory-service”佣赖,就是一個服務名稱。
● 而value則代表了一個服務的多個服務實例记盒。
● 舉個例子:比如說“inventory-service”是可以有3個服務實例的憎蛤,每個服務實例部署在一臺機器上
接下來咱們再來看里面這個小Map:Map<String, Lease<InstanceInfo>
● 這個Map的key就是服務實例的id
● value是一個叫做Lease<InstanceInfo>的東西。這又是什么鬼呢纪吮?
■? 首先說下InstanceInfo俩檬,其實啊,我們見名知義碾盟,這個InstanceInfo就代表了服務實例的具體信息棚辽,比如機器的ip地址、hostname以及端口號
■ 而Lease的這個Lease冰肴,里面則會維護每個服務最近一次發(fā)送心跳的時間
三屈藐、Eureka Server端優(yōu)秀的多級緩存機制
假設Eureka Server部署在4核8G的普通機器上,那么基于內(nèi)存來承載各個服務的請求嚼沿,每秒鐘最多可以處理多少請求呢估盘?
● 根據(jù)之前做過的測試,單臺4核8G的機器骡尽,處理一些純內(nèi)存的操作遣妥,哪怕加上一些網(wǎng)絡請求的開銷,每秒處理幾百請求是很輕松的攀细。哪怕是更大規(guī)模的機器和請求量箫踩,處理起來察迟,也是輕松加愉快鸟缕。
● 而且Eureka Server為了避免同時讀寫內(nèi)存數(shù)據(jù)結(jié)構造成的并發(fā)沖突問題菌仁,還采用了多級緩存機制來進一步提升服務請求的響應速度瞧掺。
● 在拉取注冊表的時候:
? ? ? ? 首先從ReadOnlyCacheMap里查緩存的注冊表淆储。
????????如果沒有雾消,就找ReadWriteCacheMap里緩存的注冊表友驮。
? ? ? ? 如果還沒有嫂沉,就從內(nèi)存中獲取實際的注冊表數(shù)據(jù)。
● 在注冊表發(fā)生變更的時候:
? ? ? ? ?會在內(nèi)存中更新變更的注冊表數(shù)據(jù)缚态,同時過期掉ReadWriteCacheMap磁椒。
? ? ? ? ?這個過程不會影響ReadOnlyCacheMap提供人家查詢注冊表。
? ? ? ? ?在一段時間內(nèi)玫芦,默認是30秒浆熔,各個服務拉取注冊表數(shù)據(jù)都會直接讀ReadOnlyCacheMap。
? ? ? ? ?30秒過后桥帆,Eureka Server的后臺線程發(fā)現(xiàn)ReadWriteCacheMap已經(jīng)清空了医增,那么也會清空ReadOnlyCacheMap中的緩存
? ? ? ? ?下次有服務拉取注冊表,又會從內(nèi)存中獲取最新的數(shù)據(jù)了老虫,同時填充各個緩存叶骨。
多級緩存機制的優(yōu)點是什么?
1.這種多級緩存機制的設計张遭,盡可能保證了內(nèi)存注冊表數(shù)據(jù)不會出現(xiàn)頻繁的讀寫沖突問題邓萨。
2.并且進一步保證對Eureka Server的大量請求,都是快速從純內(nèi)存走菊卷,性能極高缔恳。
為方便大家更好的理解,同樣來一張圖洁闰,大家跟著圖再來回顧一下這整個過程:
四歉甚、總結(jié)
● 通過上面的分析可以看到,Eureka通過設置適當?shù)恼埱箢l率(拉取注冊表30秒間隔扑眉,發(fā)送心跳30秒間隔)纸泄,可以保證一個大規(guī)模的系統(tǒng)每秒請求Eureka Server的次數(shù)在幾百次。
● 同時還通過純內(nèi)存的注冊表腰素,保證了所有的請求都可以在內(nèi)存處理聘裁,這樣確保了極高的性能,普通機器一秒鐘處理幾百請求都是輕松+愉快的弓千。
● 另外還有多級緩存機制衡便,確保說不會針對內(nèi)存數(shù)據(jù)結(jié)構發(fā)生頻繁的讀寫并發(fā)沖突操作,進一步提升性能洋访。
上述就是Spring Cloud架構中镣陕,Eureka作為微服務注冊中心可以承載大規(guī)模系統(tǒng)每天千萬級訪問量的原理。
如有收獲姻政,請幫忙轉(zhuǎn)發(fā)呆抑,您的鼓勵是作者最大的動力,謝謝汁展!
一大波微服務鹊碍、分布式厌殉、高并發(fā)、高可用的原創(chuàng)系列文章正在路上侈咕,歡迎掃描下方二維碼年枕,持續(xù)關注:
《雙11每秒上萬并發(fā)下的Spring Cloud參數(shù)優(yōu)化實戰(zhàn)》,敬請期待
《微服務架構如何保障雙11狂歡下的99.99%高可用》乎完,敬請期待
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 歡迎關注微信公眾號石杉的架構筆記(id:shishan100)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?周一至周五早八點半!精品技術文章準時送上品洛!
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 十余年BAT架構經(jīng)驗傾囊相授树姨。