偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

我的天,你們公司的“微服務(wù)”簡直就是反人類…

開發(fā) 架構(gòu)
轉(zhuǎn)眼已經(jīng) 2020,距離微服務(wù)這個詞落地已經(jīng)過去好多年!(我記得 2017 年就聽過這個詞)。然而今天我想想什么是微服務(wù),其實并沒有一個很好的定義。

轉(zhuǎn)眼已經(jīng) 2020,距離微服務(wù)這個詞落地已經(jīng)過去好多年!(我記得 2017 年就聽過這個詞)。然而今天我想想什么是微服務(wù),其實并沒有一個很好的定義。

[[311997]] 

圖片來自 Pexels

為什么這樣說?按照微服務(wù)的定義:

微服務(wù)架構(gòu)就是將一個龐大的業(yè)務(wù)系統(tǒng)按照業(yè)務(wù)模塊拆分成若干個獨立的子系統(tǒng),每個子系統(tǒng)都是一個獨立的應(yīng)用,它是一種將應(yīng)用構(gòu)建成一系列按業(yè)務(wù)領(lǐng)域劃分模塊的,小的自治服務(wù)的軟件架構(gòu)方式,倡導(dǎo)將復(fù)雜的單體應(yīng)用拆分成若干個功能單一、松偶合的服務(wù),這樣可以降低開發(fā)難度、增強擴展性、便于敏捷開發(fā),及持續(xù)集成與交付活動。

根據(jù)這個定義,不難看出其實就是對復(fù)雜的業(yè)務(wù)系統(tǒng)統(tǒng)一做邏輯拆分,保持邏輯上的獨立。

那么邏輯上獨立,一個服務(wù)這樣做真的就好嗎,如何界定:小、獨,還有要做一個事情,完成單一的業(yè)務(wù),單一的功能要拆分出來,為了獨立而獨立會不會導(dǎo)致拆的過細?

不同人有不同的見解,我們今天一起探討微服務(wù)的過去和未來。

微服務(wù)緣起

在沒有微服務(wù)之前,我們最早的架構(gòu)模式就是 MVC 模式,把業(yè)務(wù)邏輯分為:

  • 表示層
  • 業(yè)務(wù)邏輯層
  • 數(shù)據(jù)訪問層

MVC 模式隨著大前端的發(fā)展,從一開始的前后端不分離,到現(xiàn)在的前后端分離逐漸演進。

這種演進好的一點是剝離了不同開發(fā)語言的開發(fā)環(huán)境和部署環(huán)境,使得開發(fā)較為便利,部署更直接。

然而問題是:這種模式仍然是單體應(yīng)用模式,如果有一個改動需要上線,你不得不因為這個改動去考慮更多,因為你無法估量在這么大體量的代碼中你的一個改動會不會引發(fā)蝴蝶效應(yīng)。

另外很重要的一點就是移動互聯(lián)網(wǎng)時代的到來,引發(fā)了用戶數(shù)幾何倍數(shù)暴增,傳統(tǒng)的單體應(yīng)用模式已經(jīng)無法支撐用戶量暴漲的流量沖擊,互聯(lián)網(wǎng)人不得不做出加機器的無奈之舉。

然而發(fā)現(xiàn)有的時候加機器都無法搞定問題,因為邏輯調(diào)用過于耦合導(dǎo)致調(diào)用鏈復(fù)雜。

繼而出現(xiàn)精簡調(diào)用流程,梳理調(diào)用路徑的舉措,于是演變出微服務(wù)這個概念。

其實在沒有微服務(wù)這個詞出現(xiàn)之前, 我們也是這樣干的,只是干的不徹底而已。

比如說有一個信貸系統(tǒng),分為貸前,貸中,貸后三步:

 

在微服務(wù)未出現(xiàn)之前,我們大多是單體應(yīng)用,基本上一個工程包含所有,無所不能,所以很臃腫。上述這些模塊應(yīng)該都是在一個工程中,但是按照業(yè)務(wù)做了代碼上的拆分。

另外就是 RPC 框架橫空出世,如果有服務(wù)上的拆分,比如不同部門之間調(diào)用對方提供的服務(wù),那么八九不離十肯定定義的是 HTTP 接口,因為通用。但是某些時候大家又怕 HTTP 接口性能差,關(guān)鍵服務(wù)不敢用。

微服務(wù)出現(xiàn)之后,大家覺得按照模塊分別部署好像是這么回事,同時默默在心里嘀咕,以前我只用發(fā)布一個工程,現(xiàn)在倒好,可能有個改動涉及 3 個服務(wù),我一個小小的改動就要發(fā)布 3 次,是不是增加了工作量。

另外我以前都不用調(diào)接口的,現(xiàn)在依賴了一堆別的系統(tǒng),系統(tǒng)調(diào)用這么復(fù)雜,萬一別的系統(tǒng)有問題,我豈不是就被耽擱了!

在這種質(zhì)疑中大家雖有抱怨但是也沒有放棄趕時髦,微服務(wù)開展的如火如荼,用戶中心獨立部署,風(fēng)控系統(tǒng)單獨成型,支付中心全公司統(tǒng)一獨立,財務(wù)系統(tǒng)不再各個業(yè)務(wù)各自為戰(zhàn)而是統(tǒng)籌公司各個業(yè)務(wù)線統(tǒng)一規(guī)劃。

按照業(yè)務(wù)抽象獨立之后,大家發(fā)現(xiàn)好像是這么回事,用起來真香。雖然每次需要別的模塊的時候就需要找對應(yīng)模塊進行接入,但是業(yè)務(wù)邏輯上清晰了呀,如果出了問題,不是自己的,那就是別人的,甩鍋很方便的(笑)。

如何做微服務(wù)

因為微服務(wù)是功能粒度上的拆分,必然導(dǎo)致拆分之后的模塊變多。

針對模塊與模塊之間的通信與維護,又演變出如下問題:

  • 模塊與模塊之間如何通信
  • 每個被拆分的微服務(wù)如何做負載均衡
  • 服務(wù)如何做注冊,如何做發(fā)現(xiàn)
  • 服務(wù)之間調(diào)用如何做限流,服務(wù)調(diào)用失敗如何做降級,流量異常如何做熔斷
  • 服務(wù)調(diào)用是否可以做統(tǒng)一的訪問控制

針對這些問題,業(yè)界也在發(fā)展中慢慢演進出幾套通用的框架。

理想中微服務(wù)框架應(yīng)該具備這樣的能力:

基于上述微服務(wù)框架應(yīng)該具備的能力,我們來分析目前可以落地的微服務(wù)框架的具體實現(xiàn)。

目前國內(nèi)用的最多的無外乎是兩套框架:

  • Dubbo
  • Spring Cloud

Dubbo 大家都很熟悉,從開源到無人維護再到重新沖擊 Apache 頂級項目。

但是 Dubbo 更加準確來說是一個分布式服務(wù)框架,致力于提供高效的 RPC 遠程服務(wù)調(diào)用方案以及 SOA 服務(wù)治理方案。說白了就是個分布式遠程服務(wù)調(diào)用框架。

Dubbo

從 Dubbo 官網(wǎng)給的圖來看 Dubbo 的整體架構(gòu):

模塊注解: 

  • Provider:暴露服務(wù)的服務(wù)提供方。
  • Consumer:調(diào)用遠程服務(wù)的服務(wù)消費方。
  • Registry:服務(wù)注冊與發(fā)現(xiàn)的注冊中心。
  • Monitor:統(tǒng)計服務(wù)的調(diào)用次數(shù)和調(diào)用時間的監(jiān)控中心。
  • Container:服務(wù)運行容器。

從上圖中不難看出 Dubbo 功能還是很明確的:服務(wù)注冊于發(fā)現(xiàn),服務(wù)監(jiān)控。

另外 Dubbo 也提供服務(wù)治理功能: 

Dubbo 提供了集群容錯的能力,在管理后臺可以快速的摘除失敗的服務(wù)。 

從我們上面提到的一整套微服務(wù)應(yīng)該提供的功能看,Dubbo 只是提供了服務(wù)注冊與服務(wù)發(fā)現(xiàn)的功能。不可否認在這一項功能中,Dubbo 做的是非常優(yōu)秀的。

Spring Cloud

Spring Cloud 基于 Spring Boot,為微服務(wù)體系開發(fā)中的架構(gòu)問題,提供了一整套的解決方案:服務(wù)注冊與發(fā)現(xiàn),服務(wù)消費,服務(wù)保護與熔斷,網(wǎng)關(guān),分布式調(diào)用追蹤,分布式配置管理等。

 

①服務(wù)注冊與發(fā)現(xiàn)

目前 Spring Cloud 支持的服務(wù)注冊組件有:

  • Consul
  • Eureka

Consul 不是 Spring 官方的項目,需要單獨部署,Eureka 被 Spring 官方收錄,本身屬于 Spring Cloud 體系中。

下面列出可以被用作注冊中心的組件,他們的特性對比:

Consul 官網(wǎng)中介紹了 Consul 的以下幾個核心功能: 

  • 服務(wù)發(fā)現(xiàn)(Service Discovery):提供 HTTP 與DNS 兩種方式。
  • 健康檢查(Health Checking):提供多種健康檢查方式,比如 HTTP 狀態(tài)碼、內(nèi)存使用情況、硬盤等等。
  • 鍵值存儲(KV Store):可以作為服務(wù)配置中心使用,類似 Spring Cloud Config。
  • 加密服務(wù)通信(Secure Service Communication)。
  • 多數(shù)據(jù)中心(Multi Datacenter):Consul 通過 WAN 的 Gossip 協(xié)議,完成跨數(shù)據(jù)中心的同步。

Consul 需要單獨部署,而不是與 Spring 集成的組件。

Eureka 是 Spring Cloud NetFlix 默認的服務(wù)發(fā)現(xiàn)框架,但目前 2.0 版本已閉源,只剩下 1.9 版本的處于維護狀態(tài)。

Eureka 使用盡力而為同步的方式提供弱一致的服務(wù)列表。當一個服務(wù)注冊時,Eureka 會嘗試將其同步到其他節(jié)點上,但不提供一致性的保證。

因此,Eureka 可以提供過時的或是已不存在的服務(wù)列表(在服務(wù)發(fā)現(xiàn)場景下,返回舊的總比什么也不返回好)。

如果在 15 分鐘內(nèi)超過 85% 的客戶端節(jié)點都沒有正常的心跳,那么 Eureka 就會認為客戶端與注冊中心出現(xiàn)了網(wǎng)絡(luò)故障(出現(xiàn)網(wǎng)絡(luò)分區(qū)),進入自我保護機制。

此時:

  • Eureka Server 會保護服務(wù)注冊表中的信息,不再刪除服務(wù)。這是由于如果出現(xiàn)網(wǎng)絡(luò)分區(qū)導(dǎo)致其他微服務(wù)和該 Eureka Server 無法通信,Eureka Server 就會判定這些微服務(wù)失效,但很可能這些微服務(wù)都是健康的。
  • Eureka Server 仍能接受新服務(wù)的注冊和查詢請求,但這些數(shù)據(jù)不會被同步到其他節(jié)點。
  • 當網(wǎng)絡(luò)恢復(fù)時,這個 Eureka Server 節(jié)點的數(shù)據(jù)會被同步到其他節(jié)點中。

優(yōu)點:Eureka Server 可以很好的應(yīng)對因網(wǎng)絡(luò)故障導(dǎo)致部分節(jié)點失聯(lián)的情況,而不會像 ZK 那樣如果有一半不可用的情況會導(dǎo)致整個集群不可用。

②服務(wù)網(wǎng)關(guān)

微服務(wù)的拆分導(dǎo)致服務(wù)分散,如果一個大的業(yè)務(wù)要對外提供輸出,每個服務(wù)單獨對外提供調(diào)用對接入方不友好并且調(diào)用也會很復(fù)雜。

所以出現(xiàn)了網(wǎng)關(guān),網(wǎng)關(guān)主要實現(xiàn)請求的路由轉(zhuǎn)發(fā),負載均衡,統(tǒng)一校驗,請求過濾等功能。

目前社區(qū)主流的網(wǎng)關(guān)有三個:

  • Zuul
  • Kong
  • Spring Cloud GateWay

Zuul:是 Netflix 公司的開源項目,Spring Cloud 在 Netflix 項目中也已經(jīng)集成了 Zuul,依賴名叫:spring-cloud-starter-netflix-zuul。

Zuul 構(gòu)建于 Servlet 2.5,兼容 3.x,使用的是阻塞式的 API,不支持長連接,比如 Websockets。

我們現(xiàn)在說的 Zuul 指 Zuul 1.x,Netflix 最新的 Zuul 2.x一直跳票,所以 Spring Cloud 在 Zuul 2.x 沒有出的時候依靠社區(qū)的力量發(fā)展出了新的網(wǎng)關(guān)組件:Spring Cloud Gateway。

Zuul 的核心功能就是基于 Servlet 提供了一系列的過濾器:

  • 身份認證與安全:識別每個資源的驗證要求,并拒絕那些與要求不符的請求。
  • 審查與監(jiān)控:在邊緣位置追蹤有意義的數(shù)據(jù)和統(tǒng)計結(jié)果,從而帶來精確的生產(chǎn)視圖。
  • 動態(tài)路由:動態(tài)地將請求路由到不同的后端集群。
  • 壓力測試:逐漸增加指向集群的流量,以了解性能。
  • 負載分配:為每一種負載類型分配對應(yīng)容量,并啟用超出限定值的請求。
  • 靜態(tài)響應(yīng)處理:在邊緣位置直接建立部分響應(yīng),從而避免其轉(zhuǎn)發(fā)到內(nèi)部集群。

Spring Cloud Gateway:構(gòu)建于 Spring 5+,基于 Spring Boot 2.x 響應(yīng)式的、非阻塞式的 API。

同時,它支持 Websockets,和 Spring 框架緊密集成,開發(fā)體驗相對來說十分不錯。

Spring Cloud Gateway 是基于 WebFlux 框架實現(xiàn)的,而 WebFlux 框架底層則使用了高性能的 Reactor 模式通信框架 Netty。

總體來說,Spring Cloud Gateway 與 Zuul 功能差別不大,最大的出入是在底層性能的提升上。

Zuul 本身是基于 Servlet 容器來實現(xiàn)的過濾,Servlet 采用的是單實例多線程的處理方案,Servlet 會為每一個 Request 分配一個線程。

如果當前線程比較耗時那么會一直等到線程處理完畢才會返回。所以說 Zuul 是基于 Servlet 之上的一個阻塞式處理模型。

同步阻塞模型對于網(wǎng)關(guān)這種比較在意響應(yīng)耗時和調(diào)用頻繁的組件來說,必然會引發(fā)一些性能問題,所以 Zuul 2 已經(jīng)做出了改良,從 Zuul 2 開始已經(jīng)使用 Netty。

但是不幸的是 Spring 官方已經(jīng)對它的更新頻率感到失望,所以縱然更新了也沒有被選用。

Spring Cloud Gateway 底層基于 Webflux。Webflux 模式替換了舊的 Servlet 線程模型。

用少量的線程處理 request 和 response io 操作,這些線程稱為 Loop 線程。

Webflux 的 Loop 線程,正好就是著名的 Reactor 模式 IO 處理模型的 Reactor 線程,如果使用的是高性能的通信框架 Netty,這就是 Netty 的 EventLoop 線程。

所以整體來看,Spring Cloud Gateway 的性能要比目前在用的 Zuul 高。但是 Webflux 的編程方式可能大家不是很能接收。

③服務(wù)降級

降級限流在微服務(wù)中屬于銀彈,一般不用,一旦用上那就是拯救宇宙般存在。

目前業(yè)界通用的降級限流工具主要有三款:

  • Hystrix
  • Sentinel
  • Resilience4j

Hystrix 的關(guān)注點在于以隔離和熔斷為主的容錯機制,超時或被熔斷的調(diào)用將會快速失敗,并可以提供 Fallback 機制。

Hystrix 是元老級別的存在,但是在 2018 年 11 月 Netflix 官方宣布停止更新(就是這么不靠譜,說跳票就跳票)。雖然停止更新,但是社區(qū)又推出了新的替代工具:Resilience4j。

Resilience4j 的模塊化做的比較好,將每個功能點(如熔斷、限速器、自動重試)都拆成了單獨的模塊。

這樣整體結(jié)構(gòu)很清晰,用戶也只需要引入相應(yīng)功能的依賴即可;另外 Resilience4j 是針對 Java 8 和函數(shù)式編程設(shè)計的,API 比較簡潔優(yōu)雅。

同時與 Hystrix 相比,Resilience4j 增加了簡單的限速器和自動重試特性,使用場景更加豐富。

相比 Hystrix , Resilience4j 的優(yōu)勢在于:

  • 針對 Java 8 和函數(shù)式編程設(shè)計,提供函數(shù)式和響應(yīng)式風(fēng)格的 API。
  • 增加了 rate limiting 和 automatic retrying 兩個模塊。其中 rate limiting 引入了簡單的速率控制實現(xiàn),補充了流量控制這一塊的功能。
  • 而 automatic retrying 則是封裝了自動重試的邏輯,簡化了異?;謴?fù)的流程。

Resilience4j 屬于一個新興項目,社區(qū)也在蓬勃發(fā)展??偟膩碚f,Resilience4j 是比較輕量的庫,在較小較新的項目中使用還是比較方便的。

但是 Resilience4j 只包含限流降級的基本場景,對于非常復(fù)雜的企業(yè)級服務(wù)架構(gòu)可能無法很好地 cover 住。

同時 Resilience4j 缺乏生產(chǎn)級別的配套設(shè)施(如提供規(guī)則管理和實時監(jiān)控能力的控制臺)。

Sentinel 是一款面向分布式服務(wù)架構(gòu)的輕量級流量控制組件,主要以流量為切入點,從流量控制、熔斷降級、系統(tǒng)自適應(yīng)保護等多個維度來幫助用戶保障服務(wù)的穩(wěn)定性。

Sentinel 的核心思想:根據(jù)對應(yīng)資源配置的規(guī)則來為資源執(zhí)行相應(yīng)的流控/降級/系統(tǒng)保護策略。在 Sentinel 中資源定義和規(guī)則配置是分離的。

用戶先通過 Sentinel API 給對應(yīng)的業(yè)務(wù)邏輯定義資源,然后可以在需要的時候動態(tài)配置規(guī)則。

整體功能對比:

 

從上面的參照看,Sentinel 的功能相對要多一些,但是多并不意味著所有,合適的才是最好的,對于你用不到的功能,簡單才是美麗。

④統(tǒng)一配置中心

統(tǒng)一配置中心概念的提出也是伴隨著微服務(wù)架構(gòu)出現(xiàn)才出現(xiàn),單體應(yīng)用的時候所有的配置都可以集成在服務(wù)之中,多應(yīng)用的時候如果每個應(yīng)用都持有一份配置可能會有相同配置冗余的情況。

如果一共有 2000 臺機器,其中一個配置發(fā)生更改,是否要登錄每一臺機器重新更改配置呢。

另外,更多的配置必然會帶來管理上的混亂,如果沒有集中管理的地方必然會越來越亂。

分布式配置管理的本質(zhì)基本上就是一種推送-訂閱模式的運用。配置的應(yīng)用方是訂閱者,配置管理服務(wù)則是推送方。

其中,客戶端包括管理人員 Publish 數(shù)據(jù)到配置管理服務(wù),可以理解為添加/更新數(shù)據(jù);配置管理服務(wù) Notify 數(shù)據(jù)到訂閱者,可以理解為推送。

配置管理服務(wù)往往會封裝一個客戶端庫,應(yīng)用方則是基于該庫與配置管理服務(wù)進行交互。

在實際實現(xiàn)時,客戶端庫可能是主動拉取(pull)數(shù)據(jù),但對于應(yīng)用方而言,一般是一種事件通知方式。

選型一個合格的配置中心,至少需要滿足如下四個核心需求:

  • 非開發(fā)環(huán)境下應(yīng)用配置的保密性,避免將關(guān)鍵配置寫入源代碼。
  • 不同部署環(huán)境下應(yīng)用配置的隔離性,比如非生產(chǎn)環(huán)境的配置不能用于生產(chǎn)環(huán)境。
  • 同一部署環(huán)境下的服務(wù)器應(yīng)用配置的一致性,即所有服務(wù)器使用同一份配置。
  • 分布式環(huán)境下應(yīng)用配置的可管理性,即提供遠程管理配置的能力。

Diamond:最開始我接觸過的配置中心是淘寶的 Diamond,Diamond 中的數(shù)據(jù)是簡單的 Key-Value 結(jié)構(gòu)。應(yīng)用方訂閱數(shù)據(jù)則是基于 Key 來訂閱,未訂閱的數(shù)據(jù)當然不會被推送。

Diamond 是無單點架構(gòu),在做更新配置的時候只做三件事:

  • 寫數(shù)據(jù)庫
  • 寫本地
  • 通知其他機器到數(shù)據(jù)庫拉更新

本地的設(shè)計就是為了緩存,減少對數(shù)據(jù)庫的壓力。作為一個配置中心,高可用是最主要的需求。

如何保持高可用,Diamond 持有多層的數(shù)據(jù)存儲,數(shù)據(jù)被存儲在:數(shù)據(jù)庫,服務(wù)端磁盤,客戶端緩存目錄,以及可以手工干預(yù)的容災(zāi)目錄。

客戶端通過 API 獲取配置數(shù)據(jù),按照固定的順序去不同的數(shù)據(jù)源獲取數(shù)據(jù):容災(zāi)目錄,服務(wù)端磁盤,客戶端緩存。

Diamond 除了在容災(zāi)上做了很多方案,在數(shù)據(jù)讀取方面也有很多特點。客戶端采用推拉結(jié)合的策略在長連接和短連接之間取得一個平衡,讓服務(wù)端不用太關(guān)注連接的管理,又可以獲得長連接的及時性。

使用 Diamond 的流程如下:

 

發(fā)布配置  

 

讀取配置

Diamond Server 是無中心節(jié)點的邏輯集群,這樣就能避免單點故障。

Diamond 的同質(zhì)節(jié)點之間會相互通信以保證數(shù)據(jù)的一致性,每個節(jié)點都有其他節(jié)點的地址信息,其中一個節(jié)點發(fā)生數(shù)據(jù)變更后會響應(yīng)的通知其他節(jié)點,保證數(shù)據(jù)的一致性。

為了保證高可用,Client 還會在 App 端緩存一個本地文件,這樣即使 Server 不可用也能保證 App 可用。

Client 不斷長輪詢 Server,獲取最新的配置推送,盡量保證本地數(shù)據(jù)的時效性。

Client 默認啟動周期任務(wù)對 Server 進行長輪詢感知 Server 的配置變化,Server 感知到配置變化就發(fā)送變更的數(shù)據(jù)編號,客戶端通過數(shù)據(jù)編號再去拉取最新配置數(shù)據(jù);否則超時結(jié)束請求(默認 10 秒)。

拉取到新配置后,Client 會通知監(jiān)聽者(Message Listener)做相應(yīng)處理,用戶可以通過 Diamond#addListener 監(jiān)聽。

但是 Diamond 一般用途是做 KV 存儲,如果用來做配置中心,他提供的能力不是太符合。

可以看到早期的配置中心處理的東西還是比較簡單,那個時候業(yè)務(wù)沒有那么復(fù)雜,讀取配置和更新配置沒有那么多花樣,持久化存儲和本地緩存,長連接更新就可以。但是現(xiàn)在的配置中心隨著技術(shù)的發(fā)展承擔的作用可能更多。

Spring Cloud Config:作為 Spring 官方提供的配置中心可能比較符合外國人的習(xí)慣。

Spring Cloud Config 將不同環(huán)境的所有配置存放在 Git 倉庫中,服務(wù)啟動時通過接口拉取配置。

遵循 {ServiceID}-{profile}.properties 的結(jié)構(gòu),按照 Profile 拉取自己所需的配置。

當開發(fā)者修改了配置項之后,需要結(jié)合 Spring Config Bus 將配置通知到對應(yīng)的服務(wù),實現(xiàn)配置的動態(tài)更新。

可以看到,Spring Cloud Config 已經(jīng)具備了一個配置中心的雛形,可以滿足小型項目對配置的管理,但仍然有著很多局限性。

配置使用 Git 庫進行管理,那么 Git 庫的權(quán)限如何來判斷?不同環(huán)境的安全性也得不到保障。

配置的添加和刪除,配置項的匯總,也只能通過 Git 命令來實現(xiàn),對運維人員也并不友好。

Apollo(阿波羅):是攜程框架部門研發(fā)的開源配置管理中心,能夠集中化管理應(yīng)用不同環(huán)境、不同集群的配置,配置修改后能夠?qū)崟r推送到應(yīng)用端,并且具備規(guī)范的權(quán)限、流程治理等特性。

Apollo 支持四個維度管理 Key-Value 格式的配置:

  • Application(應(yīng)用):實際使用配置的應(yīng)用,Apollo 客戶端在運行時需要知道當前應(yīng)用是誰,從而可以去獲取對應(yīng)的配置;每個應(yīng)用都需要有唯一的身份標識 – appId,應(yīng)用身份是跟著代碼走的,所以需要在代碼中配置。
  • Environment(環(huán)境):配置對應(yīng)的環(huán)境,Apollo 客戶端在運行時需要知道當前應(yīng)用處于哪個環(huán)境,從而可以去獲取應(yīng)用的配置。
  • Cluster(集群):一個應(yīng)用下不同實例的分組,比如典型的可以按照數(shù)據(jù)中心分,把上海機房的應(yīng)用實例分為一個集群,把北京機房的應(yīng)用實例分為另一個集群。

對不同的 Cluster,同一個配置可以有不一樣的值,如 ZooKeeper 地址。

  • Namespace(命名空間):一個應(yīng)用下不同配置的分組,可以簡單地把 Namespace 類比為文件,不同類型的配置存放在不同的文件中,如數(shù)據(jù)庫配置文件,RPC 配置文件,應(yīng)用自身的配置文件等。

應(yīng)用可以直接讀取到公共組件的配置 Namespace,如 DAL,RPC 等;應(yīng)用也可以通過繼承公共組件的配置 Namespace 來對公共組件的配置做調(diào)整,如 DAL 的初始數(shù)據(jù)庫連接數(shù)。

Apollo 配置中心包括:

  • Config Service:提供配置獲取接口、配置推送接口,服務(wù)于 Apollo 客戶端。
  • Admin Service:提供配置管理接口、配置修改發(fā)布接口,服務(wù)于管理界面 Portal。
  • Portal:配置管理界面,通過 MetaServer 獲取 Admin Service 的服務(wù)列表,并使用客戶端軟負載 SLB 方式調(diào)用 Admin Service。

上圖簡要描述了 Apollo 的總體設(shè)計,我們可以從下往上看: 

  • Config Service 提供配置的讀取、推送等功能,服務(wù)對象是 Apollo 客戶端。
  • Admin Service 提供配置的修改、發(fā)布等功能,服務(wù)對象是 Apollo Portal(管理界面)。
  • Config Service 和 Admin Service 都是多實例、無狀態(tài)部署,所以需要將自己注冊到 Eureka 中并保持心跳。
  • 在 Eureka 之上我們架了一層 Meta Server 用于封裝 Eureka 的服務(wù)發(fā)現(xiàn)接口。
  • Client 通過域名訪問 Meta Server 獲取 Config Service 服務(wù)列表(IP+Port),而后直接通過 IP+Port 訪問服務(wù),同時在 Client 側(cè)會做 Load Balance、錯誤重試。
  • Portal 通過域名訪問 Meta Server 獲取 Admin Service 服務(wù)列表(IP+Port),而后直接通過 IP+Port 訪問服務(wù),同時在 Portal 側(cè)會做Load Balance、錯誤重試。
  • 為了簡化部署,我們實際上會把 Config Service、Eureka 和 Meta Server 三個邏輯角色部署在同一個 JVM 進程中。

客戶端設(shè)計:

上圖簡要描述了 Apollo 客戶端的實現(xiàn)原理:

  • 客戶端和服務(wù)端保持了一個長連接,從而能第一時間獲得配置更新的推送。
  • 客戶端還會定時從 Apollo 配置中心服務(wù)端拉取應(yīng)用的最新配置。這是一個 Fallback 機制,為了防止推送機制失效導(dǎo)致配置不更新。

客戶端定時拉取會上報本地版本,所以一般情況下,對于定時拉取的操作,服務(wù)端都會返回 304 - Not Modified。

定時頻率默認為每 5 分鐘拉取一次,客戶端也可以通過在運行時指定 System Property: apollo.refreshInterval 來覆蓋,單位為分鐘。

  • 客戶端從 Apollo 配置中心服務(wù)端獲取到應(yīng)用的最新配置后,會保存在內(nèi)存中。
  • 客戶端會把從服務(wù)端獲取到的配置在本地文件系統(tǒng)緩存一份,在遇到服務(wù)不可用,或網(wǎng)絡(luò)不通的時候,依然能從本地恢復(fù)配置。
  • 應(yīng)用程序從 Apollo 客戶端獲取最新的配置、訂閱配置更新通知。

配置更新:前面提到了 Apollo 客戶端和服務(wù)端保持了一個長連接,從而能第一時間獲得配置更新的推送。

長連接實際上是通過 Http Long Polling 實現(xiàn)的,具體而言:

  • 客戶端發(fā)起一個 Http 請求到服務(wù)端。
  • 服務(wù)端會保持住這個連接 60 秒,如果在 60 秒內(nèi)有客戶端關(guān)心的配置變化,被保持住的客戶端請求會立即返回,并告知客戶端有配置變化的 Namespace 信息,客戶端會據(jù)此拉取對應(yīng) Namespace 的最新配置。

如果在 60 秒內(nèi)沒有客戶端關(guān)心的配置變化,那么會返回 Http 狀態(tài)碼 304 給客戶端。

  • 客戶端在收到服務(wù)端請求后會立即重新發(fā)起連接,回到第一步。

考慮到會有數(shù)萬客戶端向服務(wù)端發(fā)起長連,在服務(wù)端使用了 async servlet(Spring DeferredResult)來服務(wù) Http Long Polling 請求。

⑤調(diào)用鏈路分析

服務(wù)調(diào)用鏈路分析在微服務(wù)中是幕后至關(guān)重要的使者,試想幾百個服務(wù)摻雜在一起,你想捋出誰先調(diào)用了誰,誰被誰調(diào)用,如果沒有一個可監(jiān)控的路徑,光憑腦子跟蹤那得多累。

基于這種需求,各路大神們集中腦汁展開遐想弄出一套分布式鏈路追蹤神器來。

在介紹調(diào)用鏈監(jiān)控工具之前,我們首先需要知道在微服務(wù)架構(gòu)系統(tǒng)中經(jīng)常會遇到兩個問題:

  • 跨服務(wù)調(diào)用發(fā)生異常,要求快速定位當前這次調(diào)用出問題在哪一步。
  • 跨服務(wù)的調(diào)用發(fā)生性能瓶頸,要求迅速定位出系統(tǒng)瓶頸應(yīng)該如何做。

打個比方說我們有兩個服務(wù):訂單中心,庫存中心。用戶下單,先去查詢庫存系統(tǒng),那么調(diào)用鏈路分析系統(tǒng)對于一個下單查詢服務(wù)應(yīng)該記錄什么呢?

我們造出如下一張調(diào)用鏈路請求記錄表,表字段如下:

表字段說明:

  • id:自增 id
  • span_id:唯一 id
  • pspan_id:父級 span_id
  • service_name:服務(wù)名稱
  • api:api 路徑
  • stage:階段/狀態(tài)
  • timestamp:插入數(shù)據(jù)時的時間戳

上表中的 stage 中的狀態(tài)解釋為:

  • CS(Client Sent 客戶端發(fā)送):客戶端發(fā)送一個請求,表示 Span 的開始。
  • SR(Server Received 服務(wù)端接收):服務(wù)端接收請求并開始處理它。(SR - CS)等于網(wǎng)絡(luò)的延遲。
  • SS(Server Sent 服務(wù)端發(fā)送):服務(wù)端處理請求完成,開始返回結(jié)束給服務(wù)端。(SR - SS)表示服務(wù)端處理請求的時間。
  • CR(Client Received 客戶端接收):客戶端完成接受返回結(jié)果,此時 Span 結(jié)束。(CR - CS)表示客戶端接收服務(wù)端數(shù)據(jù)的時間。

根據(jù)這個表我們就能很快的分析上面提到的兩個問題:

如果以上任何一步有問題,那么當前調(diào)用就不是完整的,我們必然能追蹤出來。

通過每一步的調(diào)用時間進行分析,我們也必然知道阻塞在哪一步,從而對調(diào)用慢的地方進行優(yōu)化。

現(xiàn)有的分布式 Trace 基本都是采用了 Google 的 Dapper 標準。

Dapper 的思想很簡單,就是在每一次調(diào)用棧中,使用同一個 TraceId 將不同的 Server 聯(lián)系起來。

一次單獨的調(diào)用鏈也可以稱為一個 Span,Dapper 記錄的是 Span 的名稱,以及每個 Span 的 ID 和父 ID,以重建在一次追蹤過程中不同 Span 之間的關(guān)系。

對于一個特定的 Span,記錄從 Start 到 End,首先經(jīng)歷了客戶端發(fā)送數(shù)據(jù),然后 Server 接收數(shù)據(jù),然后 Server 執(zhí)行內(nèi)部邏輯,這中間可能去訪問另一個應(yīng)用。執(zhí)行完了 Server 將數(shù)據(jù)返回,然后客戶端接收到數(shù)據(jù)。

在整個過程中,TraceId 和 ParentId 的生成至關(guān)重要。首先解釋下 TraceId 和 ParentId。

TraceId 是標識這個調(diào)用鏈的 Id,整個調(diào)用鏈,從瀏覽器開始放完,到 A 到 B 到 C,一直到調(diào)用結(jié)束,所有應(yīng)用在這次調(diào)用中擁有同一個 TraceId,所以才能把這次調(diào)用鏈在一起。

既然知道了這次調(diào)用鏈的整個 Id,那么每次查找問題的時候,只要知道某一個調(diào)用的 TraceId,就能把所有這個 Id 的調(diào)用全部查找出來,能夠清楚的知道本地調(diào)用鏈經(jīng)過了哪些應(yīng)用,產(chǎn)生了哪些調(diào)用。但是還缺一點,那就是鏈。

基于這種需求,目前各大廠商都做出了自己的分布式追蹤系統(tǒng):

  • 目前國內(nèi)開源的有:阿里的鷹眼,美團的 CAT,京東的 Hydra,還有廣為人知的個人開源 Apache 頂級項目 SkyWalking。
  • 國外的有:Zipkin,Pinpoint。

Spring Cloud Sleuth+Zipkin:Spring Cloud Sleuth 實現(xiàn)了一種分布式的服務(wù)鏈路跟蹤解決方案,通過使用 Sleuth 可以讓我們快速定位某個服務(wù)的問題。

簡單來說,Sleuth 相當于調(diào)用鏈監(jiān)控工具的客戶端,集成在各個微服務(wù)上,負責(zé)產(chǎn)生調(diào)用鏈監(jiān)控數(shù)據(jù)。

通過 Sleuth 產(chǎn)生的調(diào)用鏈監(jiān)控信息,讓我們可以得知微服務(wù)之間的調(diào)用鏈路,但是監(jiān)控信息只輸出到控制臺始終不太方便查看。

所以我們需要一個圖形化的工具,這時候就輪到 Zipkin 出場了。Zipkin 是 Twitter 開源的分布式跟蹤系統(tǒng),主要用來收集系統(tǒng)的時序數(shù)據(jù),從而追蹤系統(tǒng)的調(diào)用問題。

Spring Cloud Slueth 聚焦在鏈路追蹤和分析,將信息發(fā)送到 Zipkin,利用 Zipkin 的存儲來存儲信息。

當然,Zipkin 也可以使用 ELK 來記錄日志和展示,再通過收集服務(wù)器性能的腳本把數(shù)據(jù)存儲到 ELK,則可以展示服務(wù)器狀況信息。

Pinpoint:數(shù)據(jù)分析非常完備。提供代碼級別的可見性以便輕松定位失敗點和瓶頸,對于執(zhí)行的 SQL 語句,都進行了記錄。

還可以配置報警規(guī)則等,設(shè)置每個應(yīng)用對應(yīng)的負責(zé)人,根據(jù)配置的規(guī)則報警,支持的中間件和框架也比較完備。

Pinpoint 是一個完整的性能監(jiān)控解決方案:有從探針、收集器、存儲到 Web 界面等全套體系。

Pinpoint 提供有 Java Agent 探針,通過字節(jié)碼注入的方式實現(xiàn)調(diào)用攔截和數(shù)據(jù)收集,可以做到真正的代碼無侵入,只需要在啟動服務(wù)器的時候添加一些參數(shù),就可以完成探針的部署。

對于這一點,Zipkin 使用修改過的類庫和它自己的容器(Finagle)來提供分布式事務(wù)跟蹤的功能。

但是,它要求在需要時修改代碼。Pinpoint 是基于字節(jié)碼增強的方式,開發(fā)人員不需要修改代碼,并且可以收集到更多精確的數(shù)據(jù)因為有字節(jié)碼中的更多信息。

相對來說,Pinpoint 界面顯示的更加豐富,具體到調(diào)用的 DB 名,Zipkin 的拓撲局限于服務(wù)于服務(wù)之間。

SkyWalking:和 Pinpoint 有一種既生瑜何生亮的感嘆。

SkyWalking 邏輯上分為四部分:

  • 探針(SkyWalking-agent)
  • 平臺后端(oap-server)
  • 存儲(es)
  • 用戶界面(apm-webapp)

探針基于不同的來源可能是不一樣的(原生代理,SDK 以及 Zipkin,Jaeger 和 OpenCensus ),但作用都是收集數(shù)據(jù)、將數(shù)據(jù)格式化為 SkyWalking 適用的格式。

平臺后端是一個支持集群模式運行的后臺、用于數(shù)據(jù)聚合、數(shù)據(jù)分析以及驅(qū)動數(shù)據(jù)流從探針到用戶界面的流程。

平臺后端還提供了各種可插拔的能力,如不同來源數(shù)據(jù)(如來自 Zipkin)格式化、不同存儲系統(tǒng)以及集群管理,你甚至還可以使用觀測分析語言來進行自定義聚合分析。

存儲是開放式的,你可以選擇一個既有的存儲系統(tǒng),如 ElasticSearch,H2 或 MySQL 集群(Sharding-Sphere 管理)、也可以選擇自己實現(xiàn)一個存儲系統(tǒng)。

用戶界面對于 SkyWalking 的最終用戶來說非常炫酷且強大、同樣它也是可定制以匹配你已存在的后端的。

總結(jié)

以上是微服務(wù)全鏈路過程中需要經(jīng)歷的階段,當然還不包括發(fā)布系統(tǒng)的搭建,底層數(shù)據(jù)治理能力。

所以提倡微服務(wù)可以,但是真的做起來不是所有公司都能做得到。小公司能做到服務(wù)拆分但是相應(yīng)的配套設(shè)施不一定能跟上,大公司有人有錢有時間,才能提供這些基礎(chǔ)設(shè)施。

微服務(wù)的路任重道遠,搭起來一套完整的設(shè)施并用于生產(chǎn)環(huán)境還是挺有挑戰(zhàn),新的一年希望我能夠在踐行微服務(wù)的路上走下去,只有走的完整才是微服務(wù),走的不完整對于開發(fā)人員來說,那就是過度開發(fā),就是災(zāi)難。

 

責(zé)任編輯:武曉燕 來源: 博客園
相關(guān)推薦

2018-03-22 14:59:20

2019-10-30 17:17:35

區(qū)塊鏈物聯(lián)網(wǎng)技術(shù)

2023-12-22 14:27:30

2013-08-26 09:31:47

技術(shù)面試

2025-05-23 08:30:00

系統(tǒng)監(jiān)控告警架構(gòu)告警

2020-12-03 06:34:34

分支策略SIT

2020-09-19 17:54:04

Netflix

2014-01-02 14:04:42

2015-04-21 14:04:35

iOS

2021-03-14 07:11:24

剪映剪視頻

2014-04-21 16:40:39

創(chuàng)業(yè)創(chuàng)業(yè)文化

2023-06-12 13:13:26

2020-04-14 10:06:20

微服務(wù)Netflix語言

2023-12-07 12:43:33

2023-09-22 08:27:59

2023-07-13 09:00:00

人工智能GPT模型

2018-01-31 09:55:28

Docker公司微服務(wù)預(yù)言

2013-10-09 13:25:42

產(chǎn)品經(jīng)理產(chǎn)品

2020-07-25 20:20:06

瀏覽器 Chrome Google
點贊
收藏

51CTO技術(shù)棧公眾號