成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

線上SpringCloud網(wǎng)關調(diào)用微服務跨機房了,咋整?

yankeys / 2633人閱讀

摘要:微服務也同樣在這兩個機房之間都有部署。但是,大家看粉紅色粗體的線條,仍然存在跨機房調(diào)用,天津網(wǎng)關調(diào)用到北京微服務。相當于網(wǎng)關以及微服務兩側(cè)都是通過基于權(quán)重的負載均衡算法來盡量減少跨機房調(diào)用的,但是無法避免跨機房調(diào)用。

1、前言

公司內(nèi)考慮到服務器資源成本的問題,目前業(yè)務上還在進行服務的容器化改造和遷移,計劃將容器化后的服務,以及一些中間件(MQ、DB、ES、Redis等)盡量都遷移到其他機房。

那你們?yōu)槭裁床挥冒⒗镌瓢。v訊云啊,還用自己的機房?

的確是這樣,公司內(nèi)部目前還是有專門的運維團隊。也是因為歷史原因,當時業(yè)務發(fā)展比較迅猛,考慮到數(shù)據(jù)的安全性也是自建機房的。對于中小型公司這樣做,顯然成本太高了,所以一般都用阿里云。對于中大型企業(yè)或者對數(shù)據(jù)安全性要求高的公司,自建機房維護的也不再少數(shù)。

對于中間件來說,比如 Redis 緩存,有的業(yè)務也是因為歷史原因,當時上線后都是多帶帶申請,并部署的一套集群,但是量并不是很大,所以類似這種情況的,可以考慮跟其他項目使用的集群合并為一個,這樣就可能節(jié)省了一部分服務器資源。

現(xiàn)在大多數(shù)企業(yè)都已經(jīng)微服務化,容器化了。

所以,將非容器化的業(yè)務要求都遷移到容器中,這里的容器基本都是指 Kubernetes 平臺了,通過容器發(fā)布調(diào)度服務,對于運維來說,維護變得更加便捷,高效。

對于研發(fā)來說,業(yè)務需要部署服務,不再需要重新提 JIRA 工單,走一系列審核流程,最后給到你的可能還是一臺虛擬機,依賴的軟件多帶帶安裝部署。用了容器,只要在 集裝箱 中提前安裝好所需軟件環(huán)境,按照發(fā)布規(guī)范打好鏡像,發(fā)布服務的過程一路就是 點點點...。

2、線上業(yè)務場景介紹

繼續(xù)來說今天的主題。

有一個項目是 SpringCloud 架構(gòu)的,其中使用到了 網(wǎng)關 Zuul,并且也使用了到了 Eureka 作為注冊中心。

因為該項目提前已經(jīng)遷移到北京機房節(jié)點部署的容器環(huán)境,我們最終目標是遷移到其他機房(如:天津機房)。

北京有兩個機房:A機房、B機房,因為都在北京,所以兩個機房之間的 網(wǎng)絡延時 是可以接受的。

微服務也同樣在這兩個機房之間都有部署。

此時,如果只是將微服務部署到 天津機房,會變成如下圖所示的關系:

問題很明顯,就是網(wǎng)關服務只有北京的,而微服務新增了天津機房的,此時會導致 跨機房調(diào)用,即北京網(wǎng)關調(diào)用到了天津微服務。

盡管北京到天津 ping 的網(wǎng)絡延時僅有 3 毫秒 之差,但是服務與服務之間的調(diào)用,可就不止這 3 毫秒了。

其中包括服務器與服務器之間 TCP連接的建立、數(shù)據(jù)傳輸?shù)木W(wǎng)絡開銷,如果數(shù)據(jù)包過大,跨機房訪問耗時就會很明顯了。

所以呢,盡量避免跨機房訪問,當然要將網(wǎng)關也要遷移到天津機房。

但是,大家看 粉紅色粗體 的線條,仍然存在跨機房調(diào)用,天津網(wǎng)關調(diào)用到北京微服務。

對于線上并發(fā)訪問量稍微大點,或者有些接口響應體大的,又或者網(wǎng)絡抖動等場景下,可能就會導致接口響應時間變長了。

如何解決呢?

因大部分業(yè)務都部署到天津,可以將天津機房的服務權(quán)重調(diào)高

SLB配置 (類Nginx):

upstream {    server 北京機房網(wǎng)關IP  20;    server 天津機房網(wǎng)關IP  80;}

網(wǎng)關與微服務之間,都是通過 Eureka 注冊中心媒介來溝通,即 注冊服務 拉取服務。

僅僅在網(wǎng)關層配置好權(quán)重還不夠,此時還會存在天津網(wǎng)關路由到北京微服務上。

Eureka 內(nèi)部是基于 Ribbon 實現(xiàn)負載均衡的,自行實現(xiàn)按權(quán)重的負載均衡策略,Eureka做一點改造,界面上支持權(quán)重的修改。

下圖截圖了部分示例:

IP后面的就是權(quán)重值,可以在界面上輸入權(quán)重值進行調(diào)整。

我們可以將北京微服務權(quán)重調(diào)低,天津微服務權(quán)重調(diào)高。

相當于網(wǎng)關以及微服務兩側(cè)都是通過基于 權(quán)重 的負載均衡算法來盡量減少跨機房調(diào)用的,但是無法避免跨機房調(diào)用。

使用 Eureka 的分區(qū)改進

上面描述的方案對于 20% 的流量仍然存在跨機房訪問,我們能不能做到先訪問同一機房的服務,如果同一機房的服務都不可用了,再訪問其他機房的呢?

答案是 可以的。

我們可以借助于 Eureka 注冊中心里提供了 regionzone 的概念來實現(xiàn)。

regionzone 兩個概念均來自亞馬遜的 AWS:

region:簡單理解為地理上的分區(qū),比如亞洲地區(qū),或者華北地區(qū)等等,沒有具體大小的限制。根據(jù)項目情況,自行合理劃分 region。

zone:簡單理解為 region 內(nèi)的具體機房,比如說 zone 劃分為北京、天津,且北京有兩個機房,就可以在 region 內(nèi)劃分為三個zone,北京劃分為zone1、zone2,天津為zone3。

結(jié)合上面的示例,假設僅設置一個 region 為京津地區(qū)。

然后我們給這個區(qū)域下的網(wǎng)關服務、微服務打上 zone 機房標簽,在系統(tǒng)運維上將機房也稱作 IDC 數(shù)據(jù)中心。

網(wǎng)關服務打上zone標簽:

微服務打上zone標簽:

這個功能都是在 Eureka注冊中心 上實現(xiàn)的,在給服務配置 zone 前,調(diào)用路徑如下所示:

給服務配置 zone 之后,框架內(nèi)部的路由機制的實現(xiàn)下,調(diào)用路徑如下所示:

當前使用的 Eureka 是部署在北京,如果想讓服務在注冊、續(xù)約、拉取 動作時也能實現(xiàn) 就近機房訪問,部署架構(gòu)就變成如下這個樣子:

北京區(qū)域不同機房假設認為網(wǎng)絡延時小,所以北京兩個機房可以使用同一個 Eureka 集群;天津可以多帶帶再部署一套 Eureka 集群,這樣就可以實現(xiàn)優(yōu)先路由到同機房訪問。

服務注冊的關鍵配置

基本原理就是這樣,貼上一段 Eureka 使用 regionzone 的配置供大家參考:

spring:  application:    name: manangerserver:  port: ${EUREKA_SERVER_PORT:8011}eureka:  instance:     # 全網(wǎng)服務實例唯一標識    instance-id: ${EUREKA_SERVER_IP:127.0.0.1}:${server.port}    # 服務實例的meta數(shù)據(jù)鍵值對集合,可由注冊中心進行服務實例間傳遞    metadata-map:      # [HA-P配置]-當前服務實例的zone      zone: ${EUREKA_SERVER_ZONE:tz-1}      profiles: ${spring.profiles.active}    # 開啟ip,默認為false=》hostname    prefer-ip-address: true    ip-address: ${EUREKA_SERVER_IP:127.0.0.1}    # [HA-P配置]-當前服務實例的regionclient:    region: ${EUREKA_SERVER_REGION:cn-bj}    # [HA-P配置]-開啟當前服務實例優(yōu)先發(fā)現(xiàn)同zone的注冊中心,默認為true    prefer-same-zone-eureka: true    # [服務注冊]-允許當前服務實例注冊,默認為true    register-with-eureka: true    # [服務續(xù)約]-允許當前服務實例獲取注冊信息,默認為true    fetch-registry: true    # [HA-P配置]-可用region下zone集合        availability-zones:      cn-bj: ${eureka.instance.metadata-map.zone},zone-bj,zone-tj   service-url:        # [HA-P配置]-各zone下注冊中心地址列表       zone-bj: http://BJIP1:8011/eureka,http://BJIP2:8012/eureka       zone-tj: http://TJIP1:8013/eureka,http://TJIP2:8014/eureka

prefer-same-zone-eureka :

默認就為true,首先會通過 region 找到 availability-zones 內(nèi)的第一個 zone,然后通過這個 zone 找到 service-url 對應該機房的注冊中心地址列表,并向該列表內(nèi)的 第一個URL 地址發(fā)起注冊和心跳,不會再向其它的URL地址發(fā)起操作。只有當?shù)谝粋€URL地址注冊失敗的情況下,才會依次向其它的URL發(fā)起操作,重試一定次數(shù)仍然失敗,會間隔一段心跳時間繼續(xù)重試。

eureka.instance.metadata-map.zone:

服務提供者和消費者都要配置該參數(shù),表示自己屬于哪一個機房的。網(wǎng)關服務也屬于消費者,從注冊中心拉取到注冊表之后會根據(jù)這個參數(shù)中指定的 zone 進行過濾,過濾后向同 zone 內(nèi)的服務會有多個實例 ,通過 Ribbon 來實現(xiàn)負載均衡調(diào)用。如果同一 zone內(nèi)的所有服務都不可用時,會其他 zone 的服務發(fā)起調(diào)用。

另外注意一點 availability-zones 下 region 的配置是 ${eureka.instance.metadata-map.zone},... 這樣配置的好處是,你只要指定好了 eureka.instance.metadata-map.zone,優(yōu)先會將這個參數(shù)放到可用分區(qū)下作為第一個 zone 來訪問。

Zuul 網(wǎng)關路由分區(qū)源碼分析

網(wǎng)關使用的 zuul,其內(nèi)部也是通過 ribboneureka 的結(jié)合來實現(xiàn)服務之間的調(diào)用,因為網(wǎng)關實際也是個服務消費者,同樣會注冊到 eureka 上,被網(wǎng)關拉取過來的注冊表里的服務,作為服務提供者,同樣會注冊到eureka上。

通過一張圖把控整個請求的大致脈絡:

上述圖示中部分核心源碼如下所示:

PollServerListUpdater#start(final UpdateAction action) 啟動后會每隔30秒(默認)去Eureka注冊中心拉取一次注冊表信息,更新本地緩存的數(shù)據(jù)結(jié)構(gòu)。

調(diào)用到了DyamicServerListLoadBalancer匿名實現(xiàn)類中。

通過DyamicServerListLoadBalancer類調(diào)用了 updateListOfServer() 方法更新服務列表,serverListImpl的實現(xiàn)是DiscoveryEnabledNIWSServerList類

在DiscoveryEnabledNIWSServerList類內(nèi)部會調(diào)用 obtainServersViaDiscovery() 方法,其內(nèi)部通過 EurekaClient 來實現(xiàn)從 Eureka 注冊中心拉取服務列表。

過濾器內(nèi)部獲取同一機房(zone)的服務列表,先后會調(diào)用 ZonePreferenceServerListFilterZoneAffinityServerListFilter 兩個過濾器實現(xiàn) zone 的過濾。

最開始獲取的Servers一共是有4條記錄,根據(jù)調(diào)試的代碼看,我們是為了獲取 zone 為2的服務,所以得到的結(jié)果是一條,即 zone = "2",說明找到了同 zone 服務。

請求接口后會調(diào)用到 LoadBalancerContext#getServerFromLoadBalancer(...),內(nèi)部會調(diào)用到ILoadBalancer 具體實現(xiàn)的 chooseServer() 方法,最終會獲取到 zone="2" 里的一個Server。

那么這里是如何選擇的Server呢?

本地調(diào)試時,只配置了已給可用的zone,所以這里條件滿足會直接調(diào)用 super.chooseServer(key) 父類的方法:

BaseLoadBalancer#chooseServer(…) 父類的選擇Server的方法,其內(nèi)部通過 IRule#choose(key) 會調(diào)用到具體的負載均衡器的實現(xiàn):

上述截圖中,能看到 MetadataWeightedRule ,這個類是我們自行基于權(quán)重負載均衡實現(xiàn)。

該實現(xiàn)類是繼承了 ZoneAviodanceRule ,目的就是利用了 zone 的概念,所重寫的 choose(Object key) 方法,調(diào)用了 this.getPredicate().getEligibleServers(...) 會走同樣的過濾規(guī)則獲取到同一機房(zone)下的所有服務列表,然后在基于每個服務配置的權(quán)重篩選一個Server。

獲取到 Server 后,拼接接口的URI請求地址 http://IP:PORT/api/.../xxx.json ,通過底層的 OkHttp 實現(xiàn)完成 Http 接口的調(diào)用過程。

好了,到此基本就分析完了,從網(wǎng)關請求,通過 ribbon 組件從 eureka 注冊中心拉取服務列表,如何基于 zone 分區(qū)來實現(xiàn)多數(shù)據(jù)中心的訪問。

對于 服務注冊,要保證服務能注冊到同一個 zone 內(nèi)的注冊中心,如果跨 zone 注冊,會導致網(wǎng)絡延時較大,出現(xiàn)拉取注冊表,心跳超時等問題。

對于 服務調(diào)用,要保證優(yōu)先調(diào)用同一個 zone 內(nèi)的服務,當無法找到同 zone 或者 同 zone 內(nèi)的服務不可用時,才會轉(zhuǎn)向調(diào)用其他 zone 里的服務。

本文提到的只是網(wǎng)關到微服務之間的調(diào)用,實際項目中,微服務還會調(diào)用其他第三方的服務,也要同時考慮到跨機房調(diào)用的問題,盡量都讓各服務之間在同機房調(diào)用,減少網(wǎng)絡延時,提高服務的穩(wěn)定性。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/119539.html

相關文章

  • 為什么 kubernetes 天然適合服務 (2)

    摘要:有了分布式數(shù)據(jù)庫可以使數(shù)據(jù)庫的性能可以隨著節(jié)點增加線性地增加。分布式數(shù)據(jù)庫最最下面是,是主備的,通過的內(nèi)核開發(fā)能力,我們能夠?qū)崿F(xiàn)主備切換數(shù)據(jù)零丟失,所以數(shù)據(jù)落在這個里面,是非常放心的,哪怕是掛了一個節(jié)點,切換完了以后,你的數(shù)據(jù)也是不會丟的。 此文已由作者劉超授權(quán)網(wǎng)易云社區(qū)發(fā)布。 歡迎訪問網(wǎng)易云社區(qū),了解更多網(wǎng)易技術(shù)產(chǎn)品運營經(jīng)驗 三、微服務化的十個設計要點 微服務有哪些要點呢?第一張圖是...

    lentrue 評論0 收藏0
  • 架構(gòu)~服務

    摘要:接下來繼續(xù)介紹三種架構(gòu)模式,分別是查詢分離模式微服務模式多級緩存模式。分布式應用程序可以基于實現(xiàn)諸如數(shù)據(jù)發(fā)布訂閱負載均衡命名服務分布式協(xié)調(diào)通知集群管理選舉分布式鎖和分布式隊列等功能。 SpringCloud 分布式配置 SpringCloud 分布式配置 史上最簡單的 SpringCloud 教程 | 第九篇: 服務鏈路追蹤 (Spring Cloud Sleuth) 史上最簡單的 S...

    xinhaip 評論0 收藏0
  • 服務的接入層設計與動靜資源隔離

    摘要:接入層作用一的聚合。接入層作用二服務發(fā)現(xiàn)與動態(tài)負載均衡既然統(tǒng)一的入口變?yōu)榱私尤雽?,則接入層就有責任自動的發(fā)現(xiàn)后端拆分,聚合,擴容,縮容的服務集群,當后端服務有所變化的時候,能夠?qū)崿F(xiàn)健康檢查和動態(tài)的負載均衡。 此文已由作者劉超授權(quán)網(wǎng)易云社區(qū)發(fā)布。 歡迎訪問網(wǎng)易云社區(qū),了解更多網(wǎng)易技術(shù)產(chǎn)品運營經(jīng)驗。 這個系列是微服務高并發(fā)設計,所以我們先從最外層的接入層入手,看都有什么樣的策略保證高并發(fā)。...

    jindong 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<