微服務(wù)架構(gòu)之服務(wù)注冊(cè)與發(fā)現(xiàn)實(shí)踐示例詳解
微服務(wù)系列前篇
微服務(wù)架構(gòu)之服務(wù)注冊(cè)與發(fā)現(xiàn)功能詳解
1 服務(wù)注冊(cè)中心
前面我們對(duì)業(yè)內(nèi)幾種比較常見的注冊(cè)中心做了介紹:Eureka、Zookeeper、Consul、Etcd。
并且在各個(gè)指標(biāo)上做了對(duì)比:注冊(cè)方式(watch\polling)、健康檢查、雪崩保護(hù)、安全與權(quán)限,以及在Spring Cloud、Dubbo、Kubernets上的支持程度。方便我們?cè)诓煌膱?chǎng)景下做正確的技術(shù)選型。
4種注冊(cè)中心技術(shù)對(duì)比
指標(biāo) | Eureka | Zookeeper | Consul | Etcd |
一致性協(xié)議 | AP | CP(Paxos算法) | CP(Raft算法) | CP(Raft算法) |
健康檢查 | TTL(Time To Live) | TCP Keep Alive | TTL\HTTP\TCP\Script | Lease TTL KeepAlive |
watch/long polling | 不支持 | watch | long polling | watch |
雪崩保護(hù) | 支持 | 不支持 | 不支持 | 不支持 |
安全與權(quán)限 | 不支持 | ACL | ACL | RBAC |
是否支持多數(shù)據(jù)中心 | 是 | 否 | 是 | 否 |
是否有管理界面 | 是 | 否(可用第三方ZkTools) | 是 | 否 |
Spring Cloud 集成 | 支持 | 支持 | 支持 | 支持 |
Dubbo 集成 | 不支持 | 支持 | 支持 | 不支持 |
K8S 集成 | 不支持 | 不支持 | 支持 | 支持 |
我們可以看出,四種技術(shù)類型對(duì)Spring Cloud的支持度都很高。Spring Cloud是微服務(wù)架構(gòu)的一站式解決方案,我們平時(shí)構(gòu)建微服務(wù)的過程中需要做的的如 配置管理、服務(wù)發(fā)現(xiàn)、負(fù)載均衡、斷路器、智能路由、控制總線、全局鎖、決策競(jìng)選、分布式會(huì)話和集群狀態(tài)管理等操作。Spring Cloud 為我們提供了一套簡(jiǎn)易的編程模型,使我們能在 Spring Boot 的基礎(chǔ)上輕松地實(shí)現(xiàn)微服務(wù)項(xiàng)目的構(gòu)建。
Spring Cloud包含了多個(gè)不同開源產(chǎn)品,來保證一站式的微服務(wù)解決方案,如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud Security、Spring Cloud Commons、Spring Cloud Zookeeper、Spring Cloud CLI等項(xiàng)目。
2 Spring Cloud 框架下實(shí)現(xiàn)
Spring Cloud為服務(wù)治理做了一層抽象,這樣能夠支持多種不同的服務(wù)治理框架,比如:Netflix Eureka、Consul。我們這邊就以這兩個(gè)為例子,看看服務(wù)治理是如何實(shí)現(xiàn)。
在Spring Cloud服務(wù)治理抽象層的作用下,可以無縫地切換服務(wù)治理實(shí)現(xiàn),且不影響任何其他的服務(wù)注冊(cè)、發(fā)現(xiàn)、調(diào)用邏輯。
所以,下面我們通過介紹這兩種服務(wù)治理的實(shí)現(xiàn)來體會(huì)Spring Cloud這一層抽象所帶來的好處。
2.1 Spring Cloud Eureka
Spring Cloud Eureka是Spring Cloud Netflix項(xiàng)目下的服務(wù)治理模塊。而Spring Cloud Netflix項(xiàng)目是Spring Cloud的子項(xiàng)目之一,主要內(nèi)容是對(duì)Netflix公司一系列開源產(chǎn)品的包裝,它為Spring Boot應(yīng)用提供了自配置的Netflix OSS整合。
通過一些簡(jiǎn)單的注解,開發(fā)者就可以快速的在應(yīng)用中配置一下常用模塊并構(gòu)建龐大的分布式系統(tǒng)。它主要提供的模塊包括:服務(wù)發(fā)現(xiàn)(Eureka),斷路器(Hystrix),智能路由(Zuul),客戶端負(fù)載均衡(Ribbon)等。
下面,就來具體看看如何使用Spring Cloud Eureka實(shí)現(xiàn)服務(wù)治理。
2.1.1 創(chuàng)建注冊(cè)中心
創(chuàng)建一個(gè)Spring Cloud項(xiàng)目,我們命名為micro-service-center,并在pom.xml
中引入需要的依賴內(nèi)容:
<packaging>pom</packaging>
表明這個(gè)項(xiàng)目中可以沒有Java代碼,也不執(zhí)行任何代碼,只是為了聚合工程或者傳遞依賴,所以可以把src文件夾刪了。這是一個(gè)父級(jí)項(xiàng)目,因?yàn)槲覀冞€要在下面建立Eureka的注冊(cè)中心、客戶端等多個(gè)子項(xiàng)目 。
在micro-service-center下,新建一個(gè)命名為 eureka-service 的Module,依舊是Spring Cloud 項(xiàng)目,建完之后,pom.xml做如下改動(dòng):
<!-- 在子工程中添加父工程名稱--> <parent> <groupId>com.microservice</groupId> <artifactId>center</artifactId> <version>1.0.0</version> </parent> <dependencies> <!-- 加入 eureka 服務(wù) --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-eureka-server</artifactId> </dependency> </dependencies>
改完之后,回到父項(xiàng)目micro-service-center,修改pom中的信息:
<groupId>com.microservice</groupId> <artifactId>center</artifactId> <packaging>pom</packaging> <version>1.0.0</version> <name>center</name> <description>Demo project for Spring Boot</description> <!-- 在父工程添加子工程名稱--> <modules> <module>eureka-service</module> <module>eureka-client</module> </modules>
對(duì)兩個(gè)項(xiàng)目進(jìn)行clean + install,應(yīng)該是成功的。
eureka-service我們是作為注冊(cè)中心來用的,所以在它的主類Application中加入@EnableEurekaServer
注解,就能開啟注冊(cè)中心功能。
@SpringBootApplication @EnableEurekaServer public class ServiceApplication { public static void main(String[] args) { SpringApplication.run(ServiceApplication.class, args); System.out.println("Start Eureka Service"); }
但是默認(rèn)情況下,該注冊(cè)中心也會(huì)把自己當(dāng)做客戶端,那就變成自己注冊(cè)自己了,這個(gè)是可以剔除的,我們看一下它的YAML中的詳細(xì)配置,注釋比較清楚:
server: port: 1000 spring: application: name: eureka-server eureka: instance: hostname: localhost client: register-with-eureka: false # 不作為客戶端進(jìn)行注冊(cè) fetch-registry: false # 不獲取注冊(cè)列表 service-url: # 注冊(cè)地址,客戶端需要注冊(cè)到該地址中 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
文中的注釋還是比較清楚的。 這邊可以看到,端口號(hào)是1000,所以當(dāng)工程啟動(dòng)之后,訪問 http://localhost:1000/ 是可以看到Eureka注冊(cè)中心頁面的。其中還沒有發(fā)現(xiàn)任何服務(wù)。
2.1.2 創(chuàng)建客戶端
目前服務(wù)中心還是空的,所以我們創(chuàng)建一個(gè)能夠提供服務(wù)的客戶端,并將其注冊(cè)到注冊(cè)中心去。
同樣的,我們創(chuàng)建一個(gè)Spring Cloud的子項(xiàng)目,命名為eureka-client
,pom.xml
中的配置如下:
<!-- 在子工程中添加父工程名稱--> <parent> <groupId>com.microservice</groupId> <artifactId>center</artifactId> <version>1.0.0</version> </parent> <dependencies> <!-- 加入 eureka 服務(wù) --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
在應(yīng)用主類Application文件中通過加上@EnableDiscoveryClient
注解,該注解保證當(dāng)前服務(wù)被Eureka當(dāng)成provider發(fā)現(xiàn)。
@SpringBootApplication @EnableDiscoveryClient public class ClientApplication { public static void main(String[] args) { SpringApplication.run(ClientApplication.class, args); System.out.println("start client!"); }
在YAML文件上加上如下配置:
server: port: 1001 spring: application: name: eureka-client eureka: client: service-url: # 這邊就保證了注冊(cè)到 eureka-service 這個(gè)注冊(cè)中心去 defaultZone: http://localhost:1000/eureka
spring.application.name
屬性,指定了微服務(wù)的名稱,在調(diào)用的時(shí)候可以通過該名稱進(jìn)行服務(wù)訪問。eureka.client.serviceUrl.defaultZone
屬性對(duì)應(yīng)服務(wù)注冊(cè)中心的配置內(nèi)容,指定服務(wù)注冊(cè)中心的位置。
大家看到,這邊端口設(shè)置為1001,那是因?yàn)橐诒緳C(jī)上測(cè)試 服務(wù)提供方 和 服務(wù)注冊(cè)中心,所以server的port
屬性需設(shè)置不同的端口。
最后,我們?cè)賹懸粋€(gè)接口,通過DiscoveryClient對(duì)象,在客戶端中獲取注冊(cè)中心的所有服務(wù)信息。
@Controller @RequestMapping("/eurekacenter") public class EuServiceController { @Autowired DiscoveryClient discoveryClient; /** * 獲取注冊(cè)服務(wù)信息 */ @RequestMapping(value = "/service", method = {RequestMethod.GET}) @ResponseBody public String getServiceInfo() { return "service:"+discoveryClient.getServices()+" , memo:"+discoveryClient.description(); }
這時(shí)候跑一下試試看,繼續(xù)訪問之前的地址:http://localhost:1000/ ,可以看到Eureka注冊(cè)中心頁面已經(jīng)包含一個(gè)我們定義的服務(wù)了,就是上面新建的 1001 端口的服務(wù)。
同樣,我們可以調(diào)用上面的那個(gè)獲取注冊(cè)服務(wù)信息的接口,從服務(wù)發(fā)現(xiàn)的角度看看有多少個(gè)服務(wù)被注冊(cè)到注冊(cè)中心去。 http://localhost:1001/eurekacenter/service
如上圖所示,方括號(hào)中的eureka-client
通過Spring Cloud定義的 getServiceInfo 接口在eureka的實(shí)現(xiàn)中獲取到的所有服務(wù)清單,他是一個(gè)String的List,如果注冊(cè)了多個(gè)提供者,就會(huì)全部顯示。
2.2 Spring Cloud Consul
Consul 用于實(shí)現(xiàn)分布式系統(tǒng)的服務(wù)發(fā)現(xiàn)與配置。與其它分布式服務(wù)注冊(cè)與發(fā)現(xiàn)的方案,Consul 的方案更具“一站式”特征,內(nèi)置了服務(wù)注冊(cè)與發(fā)現(xiàn)框 架、分布一致性協(xié)議實(shí)現(xiàn)、健康檢查、Key/Value 存儲(chǔ)、多數(shù)據(jù)中心方案,不再需要依賴其它工具(比如 ZooKeeper 之類的)。
而Spring Cloud Consul ,是將其作為一個(gè)整體,在微服務(wù)架構(gòu)中為我們的基礎(chǔ)設(shè)施提供服務(wù)發(fā)現(xiàn)和服務(wù)配置的工具。
2.2.1 Consul 的優(yōu)勢(shì)
- 1、使用 Raft 算法來保證一致性, 比復(fù)雜的 Paxos 算法更直接。
- 2、支持多數(shù)據(jù)中心,內(nèi)外網(wǎng)的服務(wù)采用不同的端口進(jìn)行監(jiān)聽。 多數(shù)據(jù)中心集群可以避免單數(shù)據(jù)中心的單點(diǎn)故障,而其部署則需要考慮網(wǎng)絡(luò)延遲, 分片等情況等。 zookeeper 和 etcd 均不提供多數(shù)據(jù)中心功能的支持,上面表格中有體現(xiàn)。
- 3、支持健康檢查。
- 4、支持 http 和 dns 協(xié)議接口。 zookeeper 的集成較為復(fù)雜, etcd 只支持 http 協(xié)議。
- 5、官方提供 web 管理界面, etcd 無此功能。
2.2.2 Consul的特性
- 1、服務(wù)發(fā)現(xiàn)
- 2、健康檢查
- 3、Key/Value存儲(chǔ)
- 4、多數(shù)據(jù)中心
2.2.3 安裝Consul注冊(cè)中心
1、官方下載64版本 :https://www.consul.io/downloads.html
2、解壓后復(fù)制到目錄 /usr/local/bin 下
3、啟動(dòng)終端,先看下啥版本的
wengzhihua@B000000147796DS ~ % consul --version Consul v1.10.4 Revision 7bbad6fe Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
4、執(zhí)行安裝命令,可以看到他的 Client Addr 的端口為8500。所以訪問 8500端口站點(diǎn),http://127.0.0.1:8500/ui/dc1/services
wengzhihua@B000000147796DS ~ % consul agent -dev ==> Starting Consul agent... Version: '1.10.4' Node ID: '6db154b4-62ff-e67d-e745-1a7270fa1ce8' Node name: 'B000000147796DS' Datacenter: 'dc1' (Segment: '<all>') Server: true (Bootstrap: false) Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600) Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302) Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false
我們可以看到,現(xiàn)在沒有客戶端注冊(cè)上來,只有一個(gè)自身的實(shí)例。
2.2.4 創(chuàng)建服務(wù)提供者
由于Spring Cloud Consul項(xiàng)目的實(shí)現(xiàn),我們可以輕松的將基于Spring Boot的微服務(wù)應(yīng)用注冊(cè)到Consul上,并通過此實(shí)現(xiàn)微服務(wù)架構(gòu)中的服務(wù)治理。
我們?cè)趍icro-service-center下新建一個(gè)cloud項(xiàng)目consul-client,該項(xiàng)目pom文件添加如下:
<!-- 在子工程中添加父工程名稱--> <parent> <groupId>com.microservice</groupId> <artifactId>center</artifactId> <version>1.0.0</version> </parent> <dependencies> <!-- Consul服務(wù)發(fā)現(xiàn)--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <!-- Consul健康檢查--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies
然后修改一下application.yml的配置信息
,將consul配置寫入,注釋應(yīng)該很清楚了,如下:
spring: application: name: consul-producer # 當(dāng)前服務(wù)的名稱 cloud: consul: # 以下為Consuk注冊(cè)中心的地址,如果安裝的不是這個(gè)host和port,這邊可以調(diào)整 host: localhost port: 8500 server: port: 8501 # 當(dāng)前服務(wù)的端口
同樣的,我們要在應(yīng)用主類Application文件中通過加上@EnableDiscoveryClient
注解,該注解保證當(dāng)前服務(wù)被Consul當(dāng)成provider發(fā)現(xiàn)。
大家看到這個(gè)做法跟Eureka一樣,因?yàn)镾pring Cloud對(duì)服務(wù)治理做的一層抽象,所以可以屏蔽Eureka和Consul服務(wù)治理的實(shí)現(xiàn)細(xì)節(jié),
程序上不需要做改變,只需要引入不同的服務(wù)治理依賴,并配置相關(guān)的配置屬性 就能輕松的將微服務(wù)納入Spring Cloud的各個(gè)服務(wù)治理框架中。
@SpringBootApplication @EnableDiscoveryClient public class ConsulClientApplication { public static void main(String[] args) { SpringApplication.run(ClientApplication.class, args); } }
修改完成之后,我們就可以把這個(gè)服務(wù)提供者啟動(dòng)了,然后再去注冊(cè)中心查看服務(wù)的注冊(cè)情況,就可以看到被注冊(cè)進(jìn)來的Provider(consul-producer):
3 總結(jié)
除了 Eureka、Consul,還有其他的的注冊(cè)中心技術(shù),如Zookeeper、Nocas等。但無論何種注冊(cè)中心技術(shù),本質(zhì)上都是為了解決微服務(wù)中的如下問題:
解耦服務(wù)之間相互依賴的細(xì)節(jié)
我們知道服務(wù)之間的遠(yuǎn)程調(diào)用必須要知道對(duì)方的IP、端口信息。我們可以在調(diào)用方直接配置被調(diào)用方的IP、端口,這種調(diào)用方直接依賴IP、端口的方式存在明顯的問題,如被調(diào)用的IP、端口變化后,調(diào)用方法也要同步修改。
通過服務(wù)發(fā)現(xiàn),將服務(wù)之間IP與端口的依賴轉(zhuǎn)化為服務(wù)名的依賴,服務(wù)名可以根據(jù)具微服務(wù)業(yè)務(wù)來做標(biāo)識(shí),因此,屏蔽、解耦服務(wù)之間的依賴細(xì)節(jié)是服務(wù)發(fā)現(xiàn)與注冊(cè)解決的第一個(gè)問題。
對(duì)微服務(wù)進(jìn)行動(dòng)態(tài)管理
在微服務(wù)架構(gòu)中,服務(wù)眾多,服務(wù)之間的相互依賴也錯(cuò)綜復(fù)雜,無論是服務(wù)主動(dòng)停止,意外掛掉,還是因?yàn)榱髁吭黾訉?duì)服務(wù)實(shí)現(xiàn)進(jìn)行擴(kuò)容,這些服務(wù)數(shù)據(jù)或狀態(tài)上的動(dòng)態(tài)變化,都需要盡快的通知到被調(diào)用方,被調(diào)用方才采取相應(yīng)的措施。因此,對(duì)于服務(wù)注冊(cè)與發(fā)現(xiàn)要實(shí)時(shí)管理者服務(wù)的數(shù)據(jù)與狀態(tài),包括服務(wù)的注冊(cè)上線、服務(wù)主動(dòng)下線,異常服務(wù)的剔除。
以上就是微服務(wù)架構(gòu)之服務(wù)注冊(cè)與發(fā)現(xiàn)實(shí)踐示例詳解的詳細(xì)內(nèi)容,更多關(guān)于微服務(wù)注冊(cè)與發(fā)現(xiàn)實(shí)踐的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Cache-control使用Cache-control:private學(xué)習(xí)筆記
網(wǎng)頁緩存由 HTTP消息頭中的Cache-control控制,常見取值有private、no-cache、max-age、must- revalidate等,默認(rèn)為private2013-02-02使用?Koa?+?TS?+?ESLlint?搭建node服務(wù)器的過程詳解
這篇文章主要介紹了使用?Koa?+?TS?+?ESLlint?搭建node服務(wù)器,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05Git發(fā)現(xiàn)git push origin master 報(bào)錯(cuò)的解決方法
本篇文章主要介紹了Git發(fā)現(xiàn)git push origin master 報(bào)錯(cuò)的解決方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11碼云(gitee)通過git自動(dòng)同步到阿里云服務(wù)器
當(dāng)我們想要實(shí)現(xiàn)幾個(gè)小伙伴合作開發(fā)同一個(gè)項(xiàng)目,或者建立一個(gè)資源分享平臺(tái)的時(shí)候,GIT就是一個(gè)很好的選擇。這篇文章主要介紹了碼云(gitee)通過git自動(dòng)同步到阿里云服務(wù)器2022-12-12