一杯清茶

          統(tǒng)計(jì)

          留言簿

          Oracle SQL/PLSQL

          PowerDesigner教程系列

          Struts2.0

          web開發(fā)

          三人行

          從事RCP開發(fā)的同行

          工作流和權(quán)限設(shè)置

          閱讀排行榜

          評(píng)論排行榜

          微服務(wù)實(shí)戰(zhàn)(四):服務(wù)發(fā)現(xiàn)的可行方案以及實(shí)踐案例

          這是關(guān)于使用微服務(wù)架構(gòu)創(chuàng)建應(yīng)用系列的第四篇文章。第一篇介紹了微服務(wù)架構(gòu)的模式,討論了使用微服務(wù)架構(gòu)的優(yōu)缺點(diǎn)。第二和第三篇描述了微服務(wù)架構(gòu)內(nèi)部的通訊機(jī)制。這篇文章中,我們將會(huì)探討服務(wù)發(fā)現(xiàn)相關(guān)問題。

          為什么要使用服務(wù)發(fā)現(xiàn)?

          設(shè)想一下,我們正在寫代碼使用了提供REST API或者Thrift API的服務(wù),為了完成一次服務(wù)請(qǐng)求,代碼需要知道服務(wù)實(shí)例的網(wǎng)絡(luò)位置(IP地址和端口)。傳統(tǒng)應(yīng)用都運(yùn)行在物理硬件上,服務(wù)實(shí)例的網(wǎng)絡(luò)位置都是相對(duì)固定的。例如,代碼可以從一個(gè)經(jīng)常變更的配置文件中讀取網(wǎng)絡(luò)位置。

          而對(duì)于一個(gè)現(xiàn)代的,基于云微服務(wù)的應(yīng)用來說,這卻是一個(gè)很麻煩的問題。其架構(gòu)如圖所示:
          1.png

          服務(wù)實(shí)例的網(wǎng)絡(luò)位置都是動(dòng)態(tài)分配的,而且因?yàn)閿U(kuò)展、失效和升級(jí)等需求,服務(wù)實(shí)例會(huì)經(jīng)常動(dòng)態(tài)改變,因此,客戶端代碼需要使用一種更加復(fù)雜的服務(wù)發(fā)現(xiàn)機(jī)制。

          目前有兩大類服務(wù)發(fā)現(xiàn)模式:客戶端發(fā)現(xiàn)服務(wù)端發(fā)現(xiàn)

          我們先來來討論一下客戶端發(fā)現(xiàn)。

          客戶端發(fā)現(xiàn)模式

          當(dāng)使用客戶端發(fā)現(xiàn)模式時(shí),客戶端負(fù)責(zé)決定相應(yīng)服務(wù)實(shí)例的網(wǎng)絡(luò)位置,并且對(duì)請(qǐng)求實(shí)現(xiàn)負(fù)載均衡。客戶端從一個(gè)服務(wù)注冊(cè)服務(wù)中查詢,其中是所有可用服務(wù)實(shí)例的庫。客戶端使用負(fù)載均衡算法從多個(gè)服務(wù)實(shí)例中選擇出一個(gè),然后發(fā)出請(qǐng)求。

          下圖顯示的是這種模式的架構(gòu)圖:
          2.png

          服務(wù)實(shí)例的網(wǎng)絡(luò)位置是在啟動(dòng)時(shí)注冊(cè)到服務(wù)注冊(cè)表中,并且在服務(wù)終止時(shí)從注冊(cè)表中刪除。服務(wù)實(shí)例注冊(cè)信息一般是使用心跳機(jī)制來定期刷新的。

          Netflix OSS提供了一種非常棒的客戶端發(fā)現(xiàn)模式。Netflix Eureka是一個(gè)服務(wù)注冊(cè)表,為服務(wù)實(shí)例注冊(cè)管理和查詢可用實(shí)例提供了REST API接口。Netflix Ribbon是一種IPC客戶端,與Eureka合同工作實(shí)現(xiàn)對(duì)請(qǐng)求的負(fù)載均衡。我們會(huì)在后面詳細(xì)討論Eureka。

          客戶端發(fā)現(xiàn)模式也是優(yōu)缺點(diǎn)分明。這種模式相對(duì)比較直接,而且除了服務(wù)注冊(cè)表,沒有其它改變的因素。除此之外,因?yàn)榭蛻舳酥揽捎梅?wù)注冊(cè)表信息,因此客戶端可以通過使用哈希一致性(hashing consistently)變得更加聰明,更加有效的負(fù)載均衡。

          而這種模式一個(gè)最大的缺點(diǎn)是需要針對(duì)不同的編程語言注冊(cè)不同的服務(wù),在客戶端需要為每種語言開發(fā)不同的服務(wù)發(fā)現(xiàn)邏輯。

          我們分析過客戶端發(fā)現(xiàn)后,再看看服務(wù)端發(fā)現(xiàn)。

          服務(wù)端發(fā)現(xiàn)模式

          另外一種服務(wù)發(fā)現(xiàn)的模式是服務(wù)端發(fā)現(xiàn)模式(server-side discovery pattern),下圖展現(xiàn)了這種模式的架構(gòu)圖:
          3.png

          客戶端通過負(fù)載均衡器向某個(gè)服務(wù)提出請(qǐng)求,負(fù)載均衡器向服務(wù)注冊(cè)表發(fā)出請(qǐng)求,將每個(gè)請(qǐng)求轉(zhuǎn)發(fā)往可用的服務(wù)實(shí)例。跟客戶端發(fā)現(xiàn)一樣,服務(wù)實(shí)例在服務(wù)注冊(cè)表中注冊(cè)或者注銷。

          AWS Elastic Load Balancer(ELB)是一種服務(wù)端發(fā)現(xiàn)路由的例子,ELB一般用于均衡從網(wǎng)絡(luò)來的訪問流量,也可以使用ELB來均衡VPC內(nèi)部的流量。客戶端使用DNS,通過ELB發(fā)出請(qǐng)求(HTTP或者TCP)。ELB負(fù)載均衡器負(fù)責(zé)在注冊(cè)的EC2實(shí)例或者ECS容器之間均衡負(fù)載,并不存在一個(gè)分離的服務(wù)注冊(cè)表,而EC2實(shí)例和ECS實(shí)例也向ELB注冊(cè)。

          HTTP服務(wù)和類似NGINX和NGINX Plus的負(fù)載均衡器都可以作為服務(wù)端發(fā)現(xiàn)均衡器。例如,這篇博文就描述如何使用Consul Template來動(dòng)態(tài)配置NGINX反向代理。Consul Template是周期性從存放在Consul Template注冊(cè)表中配置數(shù)據(jù)重建配置文件的工具。當(dāng)文件發(fā)生變化時(shí),會(huì)運(yùn)行一個(gè)命令。在如上博客中,Consul Template產(chǎn)生了一個(gè)nginx.conf文件,用于配置反向代理,然后運(yùn)行一個(gè)命令,告訴NGINX重新調(diào)入配置文件。更復(fù)雜的例子可以用HTTP API或者DNS動(dòng)態(tài)重新配置NGINX Plus。

          某些部署環(huán)境,例如KubernetesMarathon在集群每個(gè)節(jié)點(diǎn)上運(yùn)行一個(gè)代理,此代理作為服務(wù)端發(fā)現(xiàn)負(fù)載均衡器。為了向服務(wù)發(fā)出請(qǐng)求,客戶端使用主機(jī)IP地址和分配的端口通過代理將請(qǐng)求路由出去。代理將次請(qǐng)求透明的轉(zhuǎn)發(fā)到集群中可用的服務(wù)實(shí)例。

          服務(wù)端發(fā)現(xiàn)模式也有優(yōu)缺點(diǎn)。最大的優(yōu)點(diǎn)是客戶端無需關(guān)注發(fā)現(xiàn)的細(xì)節(jié),客戶端只需要簡單的向負(fù)載均衡器發(fā)送請(qǐng)求,實(shí)際上減少了編程語言框架需要完成的發(fā)現(xiàn)邏輯。而且,如上說所,某些部署環(huán)境免費(fèi)提供以上功能。

          這種模式也有缺陷,除非部署環(huán)境提供負(fù)載均衡器,否則負(fù)載均衡器是另外一個(gè)需要配置管理的高可用系統(tǒng)功能。

          服務(wù)注冊(cè)表

          服務(wù)注冊(cè)表是服務(wù)發(fā)現(xiàn)很重要的部分,它是包含服務(wù)實(shí)例網(wǎng)絡(luò)地址的數(shù)據(jù)庫。服務(wù)注冊(cè)表需要高可用而且隨時(shí)更新。客戶端可以緩存從服務(wù)注冊(cè)表獲得的網(wǎng)絡(luò)地址。然而,這些信息最終會(huì)變得過時(shí),客戶端也無法發(fā)現(xiàn)服務(wù)實(shí)例。因此,服務(wù)注冊(cè)表由若干使用復(fù)制協(xié)議保持同步的服務(wù)器構(gòu)成。

          如前所述,Netflix Eureka是一個(gè)服務(wù)注冊(cè)表很好地例子,提供了REST API注冊(cè)和請(qǐng)求服務(wù)實(shí)例。 服務(wù)實(shí)例使用POST請(qǐng)求注冊(cè)網(wǎng)絡(luò)地址,每30秒必須使用PUT方法更新注冊(cè)表,使用HTTP DELETE請(qǐng)求或者實(shí)例超時(shí)來注銷。可以想見,客戶端可以使用HTTP GET請(qǐng)求接受注冊(cè)服務(wù)實(shí)例信息。

          Netflix通過在每個(gè)AWS EC2域運(yùn)行一個(gè)或者多個(gè)Eureka服務(wù)實(shí)現(xiàn)高可用性,每個(gè)Eureka服務(wù)器都運(yùn)行在擁有彈性IP地址的EC2實(shí)例上。DNS TEXT記錄用于存儲(chǔ)Eureka集群配置,其中存放從可用域到一系列Eureka服務(wù)器網(wǎng)絡(luò)地址的列表。當(dāng)Eureka服務(wù)啟動(dòng)時(shí),向DNS請(qǐng)求接受Eureka集群配置,確認(rèn)同伴位置,給自己分配一個(gè)未被使用的彈性IP地址。

          Eureka客戶端—服務(wù)和服務(wù)客戶端—向DNS請(qǐng)求發(fā)現(xiàn)Eureka服務(wù)的網(wǎng)絡(luò)地址,客戶端首選使用同一域內(nèi)的服務(wù)。然而,如果沒有可用服務(wù),客戶端會(huì)使用另外一個(gè)可用域的Eureka服務(wù)。

          另外一些服務(wù)注冊(cè)表例子包括:
          • etcd – 是一個(gè)高可用,分布式的,一致性的,鍵值表,用于共享配置和服務(wù)發(fā)現(xiàn)。兩個(gè)著名案例包括Kubernetes和Cloud Foundry。
          • consul – 是一個(gè)用于發(fā)現(xiàn)和配置的服務(wù)。提供了一個(gè)API允許客戶端注冊(cè)和發(fā)現(xiàn)服務(wù)。Consul可以用于健康檢查來判斷服務(wù)可用性。
          • Apache ZooKeeper – 是一個(gè)廣泛使用,為分布式應(yīng)用提供高性能整合的服務(wù)。Apache ZooKeeper最初是Hadoop的子項(xiàng)目,現(xiàn)在已經(jīng)變成頂級(jí)項(xiàng)目。

          另外,前面強(qiáng)調(diào)過,某些系統(tǒng),例如Kubernetes、Marathon和AWS并沒有獨(dú)立的服務(wù)注冊(cè)表,對(duì)他們來說,服務(wù)注冊(cè)表只是一個(gè)內(nèi)置的功能。

          現(xiàn)在我們來看看服務(wù)注冊(cè)表的概念,看看服務(wù)實(shí)例是如何在注冊(cè)表中注冊(cè)的。

          服務(wù)注冊(cè)選項(xiàng)

          如前所述,服務(wù)實(shí)例必須向注冊(cè)表中注冊(cè)和注銷,如何注冊(cè)和注銷也有一些不同的方式。一種方式是服務(wù)實(shí)例自己注冊(cè),也叫自注冊(cè)模式(self-registration pattern);另外一種方式是為其它系統(tǒng)提供服務(wù)實(shí)例管理的,也叫第三方注冊(cè)模式(third party registration pattern)。我們來看看自注冊(cè)模式。

          自注冊(cè)方式

          當(dāng)使用自注冊(cè)模式時(shí),服務(wù)實(shí)例負(fù)責(zé)在服務(wù)注冊(cè)表中注冊(cè)和注銷。另外,如果需要的話,一個(gè)服務(wù)實(shí)例也要發(fā)送心跳來保證注冊(cè)信息不會(huì)過時(shí)。下圖描述了這種架構(gòu):
          4.png

          一個(gè)很好地例子是 Netflix OSS Eureka client。Eureka客戶端負(fù)責(zé)處理服務(wù)實(shí)例的注冊(cè)和注銷。Spring Cloud project,實(shí)現(xiàn)了多種模式,包括服務(wù)發(fā)現(xiàn),使得向Eureka服務(wù)實(shí)例自動(dòng)注冊(cè)時(shí)更容易。可以用@EnableEurekaClient注釋Java配置類。

          自注冊(cè)模式也有優(yōu)缺點(diǎn)。一個(gè)優(yōu)點(diǎn)是,相對(duì)簡單,不需要其他系統(tǒng)功能。而一個(gè)主要缺點(diǎn)則是,把服務(wù)實(shí)例跟服務(wù)注冊(cè)表聯(lián)系起來。必須在每種編程語言和框架內(nèi)部實(shí)現(xiàn)注冊(cè)代碼。

          另外一個(gè)方法,不需要連接服務(wù)和注冊(cè)表,則是第三方注冊(cè)模式。

          第三方注冊(cè)模式

          當(dāng)使用第三方注冊(cè)模式時(shí),服務(wù)實(shí)例并不負(fù)責(zé)向服務(wù)注冊(cè)表注冊(cè),而是由另外一個(gè)系統(tǒng)模塊,叫做服務(wù)管理器,負(fù)責(zé)注冊(cè)。服務(wù)管理器通過查詢部署環(huán)境或訂閱事件來跟蹤運(yùn)行服務(wù)的改變。當(dāng)管理器發(fā)現(xiàn)一個(gè)新可用服務(wù),會(huì)向注冊(cè)表注冊(cè)此服務(wù)。服務(wù)管理器也負(fù)責(zé)注銷終止的服務(wù)實(shí)例。下圖是這種模式的架構(gòu)圖。
          5.png

          一個(gè)服務(wù)管理器的例子是開源項(xiàng)目Registrator,負(fù)責(zé)自動(dòng)注冊(cè)和注銷被部署為Docker容器的服務(wù)實(shí)例。Reistrator支持多種服務(wù)管理器,包括etcd和Consul。

          另外一個(gè)服務(wù)管理器例子是NetflixOSS Prana,主要面向非JVM語言開發(fā)的服務(wù),也稱為附帶應(yīng)用(sidecar application),Prana使用Netflix Eureka注冊(cè)和注銷服務(wù)實(shí)例。

          服務(wù)管理器是部署環(huán)境內(nèi)置的模塊。有自動(dòng)擴(kuò)充組創(chuàng)建的EC2實(shí)例可以自向ELB自動(dòng)注冊(cè),Kubernetes服務(wù)自動(dòng)注冊(cè)并且對(duì)發(fā)現(xiàn)服務(wù)可用。

          第三方注冊(cè)模式也是優(yōu)缺點(diǎn)都有。主要的優(yōu)點(diǎn)是服務(wù)跟服務(wù)注冊(cè)表是分離的,不需要為每種編程語言和架構(gòu)完成服務(wù)注冊(cè)邏輯,替代的,服務(wù)實(shí)例是通過一個(gè)集中化管理的服務(wù)進(jìn)行管理的。

          一個(gè)缺點(diǎn)是,除非這種服務(wù)被內(nèi)置于部署環(huán)境中,否則也需要配置管理一個(gè)高可用的系統(tǒng)。

          總結(jié)

          在一個(gè)微服務(wù)應(yīng)用中,服務(wù)實(shí)例運(yùn)行環(huán)境是動(dòng)態(tài)變化的。實(shí)例網(wǎng)絡(luò)地址也是動(dòng)態(tài)變化的,因此,客戶端為了訪問服務(wù)必須使用服務(wù)發(fā)現(xiàn)機(jī)制。

          服務(wù)發(fā)現(xiàn)關(guān)鍵部分是服務(wù)注冊(cè)表,也就是可用服務(wù)實(shí)例的數(shù)據(jù)庫。服務(wù)注冊(cè)表提供一種注冊(cè)管理API和請(qǐng)求API。服務(wù)實(shí)例使用注冊(cè)管理API來實(shí)現(xiàn)注冊(cè)和注銷。

          請(qǐng)求API用于發(fā)現(xiàn)可用服務(wù)實(shí)例,相對(duì)應(yīng)的,有兩種主要服務(wù)發(fā)現(xiàn)模式:客戶端發(fā)現(xiàn)服務(wù)端發(fā)現(xiàn)

          在使用客戶端發(fā)現(xiàn)的系統(tǒng)中,客戶端向服務(wù)注冊(cè)表發(fā)起請(qǐng)求,選擇可用實(shí)例,然后發(fā)出服務(wù)請(qǐng)求

          而在使用服務(wù)端發(fā)現(xiàn)的系統(tǒng)中,客戶端通過路由轉(zhuǎn)發(fā)請(qǐng)求,路由器向服務(wù)注冊(cè)表發(fā)出請(qǐng)求,轉(zhuǎn)發(fā)此請(qǐng)求到某個(gè)可用實(shí)例。

          服務(wù)實(shí)例注冊(cè)和注銷主要有兩類方式。一種是服務(wù)實(shí)例自動(dòng)注冊(cè)到服務(wù)注冊(cè)表中,也就是自注冊(cè)模式;另外一種則是某個(gè)系統(tǒng)模塊負(fù)責(zé)處理注冊(cè)和注銷,也就是第三方注冊(cè)模式。

          在某些部署環(huán)境中,需要配置自己的服務(wù)發(fā)現(xiàn)架構(gòu),例如:Netflix Eurekaetcd或者Apache ZooKeeper。而在另外一些部署環(huán)境中,則自帶了這種功能,例如Kubernetes和Marathon 負(fù)責(zé)處理服務(wù)實(shí)例的注冊(cè)和注銷。他們也在每個(gè)集群節(jié)點(diǎn)上運(yùn)行代理,來實(shí)現(xiàn)服務(wù)端發(fā)現(xiàn)路由器的功能。

          HTTP反向代理和負(fù)載據(jù)衡器(例如NGINX)可以用于服務(wù)發(fā)現(xiàn)負(fù)載均衡器。服務(wù)注冊(cè)表可以將路由信息推送到NGINX,激活一個(gè)實(shí)時(shí)配置更新;例如,可以使用 Consul Template。NGINX Plus 支持額外的動(dòng)態(tài)重新配置機(jī)制,可以使用DNS,將服務(wù)實(shí)例信息從注冊(cè)表中拉下來,并且提供遠(yuǎn)程配置的API。

          在未來的博客中,我們還將深入探討微服務(wù)其它特點(diǎn)。可以注冊(cè)NGINX郵件列表來獲得最新產(chǎn)品更新提示。

          此篇其它博客譯文參見如下地址:

          原文鏈接:Service Discovery in a Microservices Architecture (翻譯:楊峰 校對(duì):宋喻)

          posted on 2016-03-17 18:13 一杯清茶 閱讀(541) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 萍乡市| 商城县| 泰兴市| 宜城市| 郎溪县| 江孜县| 盱眙县| 乐陵市| 武定县| 嘉黎县| 阿坝县| 阆中市| 洪江市| 梧州市| 宜昌市| 武夷山市| 项城市| 泗阳县| 白银市| 台南市| 大竹县| 原阳县| 黑龙江省| 镇雄县| 开封县| 读书| 湖南省| 阿瓦提县| 新津县| 衡水市| 胶南市| 祁连县| 虹口区| 江安县| 景宁| 灵丘县| 黄浦区| 泽州县| 集安市| 乌兰察布市| 贵阳市|