一、場景引入
本人所在的項目由於直接面向消費者,迭代周期迅速,所以服務端框架一直采用Springboot+dubbo的組合模式,每個服務由service模塊+web模塊構成,service模塊通過公司API網關向安卓端暴
露restful接口,web模塊通過dubbo服務向service模塊獲取數據渲染頁面。測試環境dubbo的注冊中心采用的單實例的zookeeper,隨着時間的發現注冊在zookeeper上的生產者和消費者越來越多,測試
人員經常在大規模的壓測后發現zookeeper掛掉的現象。因為自己用過springcloud,所以想由此談一下springcloud是如何對注冊中心集群化以及如何應對高並發場景的。
二、Spring Cloud的注冊中心 Eureka
首先看一下Spring Cloud的架構,整個架構圖在抽象之后大概就是這個樣子。Spring cloud Eureka是Spring Cloud Netflix 微服務套件中的一部分,它基於 Netflix做了二次封裝,主要負責完成
微服務架構中的服務治理功能。不同於dubbo注冊中心的是:dubbo的注冊中心是第三方組件,可以是zookeeper、可以是Redis。而Spring Cloud的注冊中心不是第三方組件,而是自身二次封裝專門用於服
務注冊與服務發現的注冊中心,在使用時只需要依賴相應的jar包即可。
三、注冊中心集群化
在微服務這樣的分布式架構中,我們要考慮故障發生的場景,所以在生產環境中要對各組件進行高可用部署,即集群化。故springcloud的注冊中心也一樣,生產環境中單節點的注冊中心顯然是十
分不安全的,我們需要構建高可用的服務注冊中心以增強系統的可用性。
EurekaServer在設計之初就考慮到了高可用問題,在Eureka的服務治理設計中,所有節點既是服務提供者同時也是服務消費者。Eureka Server的高可用實際上就是將自己作為服務向其他服務注
冊中心注冊自己,從而形成一組互相注冊的服務注冊中心,因此能夠實現服務清單的互相同步,達到服務高可用的效果,例如構建一個雙節點的注冊中心:
• 創建application-dev1.properties作為注冊中心1的配置,並將serviceUrl指向注冊中心2(dev2):
• 創建application-dev2.properties作為注冊中心2的配置,並將serviceUrl指向注冊中心1(dev1):
然后分別啟動兩個服務即可組成雙節點的注冊中心,若集群不止兩個實例,只需要在eureka.client.serviceUrl.defaultZone配置項后面用","隔開然后啟動項目即可。此時啟動服務提供者與服務消費
者,客戶端是分別注冊到每一個注冊中心的實例上的,若此時斷開一個或者幾個注冊中心實例,只要集群中還有實例存活就依然可以提供正常服務,從而實現了服務注冊中心的高可用。
四、注冊中心與高並發
Spring Cloud的架構體系中,Eureka扮演着一個至關重要的角色,所有的服務注冊與服務發現都是依賴着Eureka。上面介紹了注冊中心的集群化,那真正的生產環境中注冊中心到底要部署多少台?Eureka能不能抗住系統中大量的並發訪問?想要弄清楚這個,先從注冊中心與客戶端的工作原理說起。
首先,各個服務內的Eureka Client在默認情況下每隔30s發送一個請求到Eureka Server來拉取最近有變化的服務信息。
舉個栗子~
電商的支付模塊原本是部署在1台機器上,現在增加部署實例,部署到3台機器上,並且都已經注冊到Eureka Server上,然后Eureka Client會每隔30s去Eureka Server拉取注冊表信息的變化,看
服務的地址有沒有變化。
其次,Eureka有一個心跳機制,各個Eureka Client每隔30s會發送一次心跳數據到Eureka Server,告訴注冊中心自己還活着。如果某個Eureka Client很長時間沒有發送心跳數據給Eureka
Server,那么就說明這個實例已經掛了!
在另一方面,服務注冊中心這種組件在一開始設計的時候,它的拉取頻率及心跳發送機制就已經兼顧到了一個大型系統的各個服務請求的壓力,每秒能夠承受多大的請求量。默認的30s時間間隔
其實是經過理論上研究后得出的。一個上百個服務,幾千台機器的服務系統,按照這個體量請求Eureka Server,日請求量大概在千萬級,每秒的訪問量大概在160次左右,再加上一些其他的請求操
作,每秒在200次左右。所以通過設置一個拉取注冊表及心跳發送機制來保證高並發下場景下Eureka Server的壓力不會太大。
那么問題來了,Eureka Server是如何抗住每秒200次的請求的呢?
這個問題其實看源碼即可一目了然,Eureka Server注冊表的核心是一個CocurrentHashMap,也就是說整個注冊表的數據時完全存儲在內存里的,各個服務的注冊、下線、故障、全部會在內存中維護
和更新。也就是說,Eureka Client每隔30s拉取注冊信息和發送心跳數據也是完全基於內存,這個是能抗住每秒200次並發重要原因之一!
通過以上分析,Eureka通過設置適當的請求頻率(拉取注冊信息30s間隔,發送心跳數據30s間隔)可以保證一個大規模的系統每秒的請求在200次左右,同時通過內存維護注冊表信息,保證了所
有的請求都在內存中處理,確保了性能。所以在生產環境中到底需要部署多少台注冊中心的實例,還是要根據自身系統的訪問體量大小決定。