微服務架構中服務註冊與發現

 

https://blog.csdn.net/u011537073/article/details/69663858php

 

想象一下,若是你在寫代碼調用一個有REST API或Thrift API的服務,你的代碼須要知道一個服務實例的網絡地址(IP地址和端口)。運行在物理硬件上的傳統應用中,服務實例的網絡地址是相對靜態的,你的代碼能夠從一個不多更新的配置文件中讀取網絡地址。nginx

在一個現代的,基於雲的微服務應用中,這個問題就變得復雜多了,以下圖所示: 
Microservices 
服務實例的網絡地址是動態分配的。並且,因爲自動擴展,失敗和更新,服務實例的配置也常常變化。這樣一來,你的客戶端代碼須要一套更精細的服務發現機制。算法

有兩種主要的服務發現模式:客戶端服務發現(client-side discovery)和服務器端服務發現(server-side discovery)。咱們首先來看下客戶端服務發現。shell

客戶端服務發現模式

當使用客戶端服務發現的時候,客戶端負責決定可用的服務實例的網絡地址,以及圍繞他們的負載均衡。客戶端向服務註冊表(service registry)發送一個請求,服務註冊表是一個可用服務實例的數據庫。客戶端使用一個負載均衡算法,去選擇一個可用的服務實例,來響應這個請求,下圖展現了這種模式的架構: 
Microservices 
一個服務實例被啓動時,它的網絡地址會被寫到註冊表上;當服務實例終止時,再從註冊表中刪除。這個服務實例的註冊表經過心跳機制動態刷新。數據庫

Netflix OSS提供了一個客戶端服務發現的好例子。Netflix Eureka是一個服務註冊表,提供了REST API用來管理服務實例的註冊和查詢可用的實例。Netflix Ribbon是一個IPC客戶端,和Eureka一塊兒處理可用服務實例的負載均衡。下面會深刻討論Eureka。編程

客戶端的服務發現模式有優點也有缺點。這種模式相對直接,可是除了服務註冊表,沒有其它動態的部分了。並且,因爲客戶端知道可用的服務實例,能夠作到智能的,應用明確的負載均衡決策,好比一直用hash算法。這種模式的一個重大缺陷在於,客戶端和服務註冊表是一一對應的,必須爲服務客戶端用到的每一種編程語言和框架實現客戶端服務發現邏輯。緩存

服務器端服務發現模式

下圖展現了這種模式的架構 
Microservices 
客戶端經過負載均衡器向一個服務發送請求,這個負載均衡器會查詢服務註冊表,並將請求路由到可用的服務實例上。經過客戶端的服務發現,服務實例在服務註冊表上被註冊和註銷服務器

AWS的ELB(Elastic Load Blancer)就是一個服務器端服務發現路由器。一個ELB一般被用來均衡來自互聯網的外部流量,也能夠用ELB去均衡流向VPC(Virtual Private Cloud)的流量。一個客戶端經過ELB發送請求(HTTP或TCP)時,使用的是DNS,ELB會均衡這些註冊的EC2實例或ECS(EC2 Container Service)容器的流量。沒有另外的服務註冊表,EC2實例和ECS容器也只會在ELB上註冊。網絡

HTTP服務器和相似Nginx、Nginx Plus的負載均衡器也能夠被用作服務器端服務發現負載均衡器。例如,Consul Template能夠用來動態配置Nginx的反向代理。架構

Consul Template按期從存儲在Consul服務註冊表的數據中,生成任意的配置文件。每當文件變化時,會運行一個shell命令。好比,Consul Template能夠生成一個配置反向代理的nginx.conf文件,而後運行一個命令告訴Nginx去從新加載配置。還有一個更復雜的實現,經過HTTP API或DNS去動態地從新配置Nginx Plus。

有些部署環境,好比Kubernetes和Marathon會在集羣中的每一個host上運行一個代理。這個代理承擔了服務器端服務發現負載均衡器的角色。爲了向一個服務發送一個請求,一個客戶端使用host的IP地址和服務分配的端口,經過代理路由這個請求。這個代理會直接將請求發送到集羣上可用的服務實例。

服務器端服務發現模式也是優點和缺陷並存。最大的好處在於服務發現的細節被從客戶端中抽象出來,客戶端只須要向負載均衡器發送請求,不須要爲服務客戶端使用的每一種語言和框架,實現服務發現邏輯;另外,這種模式也有一些問題,除非這個負載均衡器是由部署環境提供的,又是另外一個高須要啓動和管理的可用的系統組件。

服務註冊表(Service Registry)

服務註冊表是服務發現的關鍵部分,是一個包含了服務實例的網絡地址的數據庫,必須是高可用和最新的。客戶端能夠緩存從服務註冊表處得到的網絡地址。可是,這些信息最終會失效,客戶端會找不到服務實例。因此,服務註冊表由一個服務器集羣組成,經過應用協議來保持一致性。

正如上面提到的,Netflix Eureka是一個服務註冊表的好例子。它提供了一個REST API用來註冊和查詢服務實例。一個服務實例經過POST請求來註冊本身的網絡位置,每隔30秒要經過一個PUT請求從新註冊。註冊表中的一個條目會由於一個HTTP DELETE請求或實例註冊超時而被刪除,客戶端經過一個HTTP GET請求來檢索註冊的服務實例。

Netflix經過在每一個EC2的可用區中,運行一個或多個Eureka服務器實現高可用。每一個運行在EC2實例上的Eureka服務器都有一個彈性的IP地址。DNS TEXT records用來存儲Eureka集羣配置,其實是從可用區到Eureka服務器網絡地址的列表的映射。當一個Eureka服務器啓動時,會向DNS發送請求,檢索Eureka集羣的配置,定位節點,併爲本身分配一個未佔用的彈性IP地址。

Eureka客戶端(服務和服務客戶端)查詢DNS去尋找Eureka服務器的網絡地址。客戶端更想使用這個可用區內的Eureka服務器,若是沒有可用的Eureka服務器,客戶端會用另外一個可用區內的Eureka服務器。

其它服務註冊的例子包括:

  • Etcd:一個高可用,分佈式,一致的key-value存儲,用來共享配置和服務發現。Kubernetes和Cloudfoundry都使用了etcd;
  • Consul:一個發現和配置服務的工具。客戶端能夠利用它提供的API,註冊和發現服務。Consul能夠執行監控檢測來實現服務的高可用;
  • Apache Zookeeper:一個經常使用的,爲分佈式應用設計的高可用協調服務,最開始Zookeeper是Hadoop的子項目,如今已經頂級項目了。

一些系統,好比Kubernetes,Marathon和AWS沒有一個明確的服務註冊組件,這項功能是內置在基礎設置中的。

下面咱們來看看服務實例如何在註冊表中註冊。

服務註冊(Service Registration)

前面提到了,服務實例必需要從註冊表中註冊和註銷,有不少種方式來處理註冊和註銷的過程。一個選擇是服務實例本身註冊,即self-registration模式。另外一種選擇是其它的系統組件管理服務實例的註冊,即第third-party registration模式。

自注冊模式(The Self-Registration Pattern)

在self-registration模式中,服務實例負責從服務註冊表中註冊和註銷。若是須要的話,一個服務實例發送心跳請求防止註冊過時。下圖展現了這種模式的架構: 
Microservices 
Netflix OSS Eureka客戶端是這種方式的一個好例子。Eureka客戶端處理服務實例註冊和註銷的全部問題。Spring Cloud實現包括服務發如今內的多種模式,簡化了Eureka的服務實例自動註冊。僅僅經過@EnableEurekaClient註釋就能夠註釋Java的配置類

self-registration模式一樣也是優劣並存。優點之一在於簡單,不須要其它組件。缺點是服務實例和服務註冊表相對應,必需要爲服務中用到的每種編程語言和框架實現註冊代碼。

第三方註冊模式(The Third-Party Registration Pattern)

在third-party registration模式中,服務實例不會本身在服務註冊表中註冊,由另外一個系統組件service registrar負責。service registrar經過輪詢部署環境或訂閱事件去跟蹤運行中的實例的變化。當它注意到一個新的可用的服務實例時,就會到註冊表中去註冊。service registrar也會將中止的服務實例註銷,下圖展現了這種模式的架構。 
Microservices 
service registrar的一個例子是開源的Registrator項目。它會自動註冊和註銷像Docker容器同樣部署的服務。Registrator支持etcd和Consul等服務註冊。

另外一個service registrar的例子是NetflixOSS Prana。主要用於非JVM語言編寫的服務,它是一個和服務實例配合的『雙輪』應用。Prana會在Netflix Eureka上註冊和註銷實例。

service registrar是一個部署環境的內置組件,由Autoscaling Group建立的EC2實例能夠被ELB自動註冊。Kubernetes服務也能夠自動註冊。

third-party registration模式主要的優點在於解耦了服務和服務註冊表。不須要爲每一個語言和框架都實現服務註冊邏輯。服務實例註冊由一個專用的服務集中實現。缺點是除了被內置到部署環境中,它自己也是一個高可用的系統組件,須要被啓動和管理。

總結

在一個微服務應用中,服務實例在運行時的配置也會動態變化,包括他們的網絡地址。爲了知足客戶端向服務發送請求的須要,必需要實現服務發現機制。

服務發現的關鍵部分是服務註冊表。服務註冊表是一個可用的服務實例的數據庫。服務註冊表提供了一個管理API和一個查詢API。服務實例的註冊和註銷經過管理API實現,查詢API用來尋找可用的服務實例。

有兩種主要的服務發現模式:客戶端服務發現和服務器端服務發現。客戶端服務發現系統中,客戶端查詢服務註冊表,選擇一個可用的實例,響應一個請求;在服務器端服務發現系統中,客戶端經過一個路由器發送請求,這個路由器會去查詢服務註冊表,並將請求發送給可用的實例。

有兩種形式能夠實現服務實例的註冊和註銷,一種是self-registration模式,一種是third-party registration模式。

一些部署環境中,須要經過相似Netflix Eureka,etcd或Apache Zookeeper的組件,啓動本身的服務發現基礎設施。其它的部署環境中,服務發現是內置的。好比,Kubernetes和Marathon處理服務實例的註冊和註銷,還會在每一個集羣host上運行一個代理,做爲服務器端服務發現路由器的角色。

一個HTTP反向代理和Nginx也能夠被用作服務器端服務發現負載均衡器。服務註冊表能夠推送路由信息到Nginx,引發配置更新,好比能夠用Consul Template。Nginx Plus支持動態的重配置機制,能夠從註冊表中拉取服務實例相關的信息,還提供了遠程配置的API。

 

微服務與微服務間分佈式調用最主要的概念即是: protocol-aware heterogeneous interoperability; 各微服務可各自擁有自身的 platform (Java,C#, Scala…等等), 但, 各微服務間卻只能藉由單一共同的協議 (protocol); 如: REST; 進行分佈式的調用 

 

微服務架構的產品或許會有數百甚至數千個微服務所構成。因此, 部署微服務時, 便很難經由手工來完成, 而必須至關程度的依賴自動化的 DevOps 工具。

 

 服務註冊與發現  部署  監控
Zookeeper
Doozer
Etcd
SmartStack
Eureka
NSQ
Serf
Spotify
DNS
SkyDNS
Consul
 Cloud Foundry
Gradle
Docker
Docker Hub
Docker Machine
Kitematic
Docker Compose
Docker Swarm
AWS
Jenkins
Continuum
Hudson
Artifactory
Terraform
Grunt
OpenShift
SonarCube
Logstash
New Relic
Graphite
Mesosphere / DCOS
Winston
Hystrix

 

原文:微服務架構

轉自:http://blog.csdn.net/jiaolongdy/article/details/51188798

相關文章
相關標籤/搜索