搭建和配置一個服務提供者
我們知道,SpringCloud構建微服務是基于SpringBoot開發的。
1、 創建一個SpringBoot工程,并且添加SpringBoot的相關依賴;
2、 創建服務提供者的訪問方法,也就是后續消費者如何訪問提供者;
Spring Cloud是基于rest的訪問,所以我們添加一個Controller,在該Controller中提供一個訪問入口:
@RestController
public class HelloController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
return "Hello Spring Cloud";
}
}
3、 啟動運行該SpringBoot程序,訪問該controller;
服務消費者也是一個SpringBoot項目,服務消費者主要用來消費服務提供者提供的服務;
1、 創建一個SpringBoot工程,并且添加SpringBoot的相關依賴;
2、開發一個消費者方法,去消費服務提供者提供的服務,這個消費者方法也是一個Controller:
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value="/cloud/hello")
public String helloController() {
return restTemplate.getForEntity("http://localhost:9100/hello", String.class).getBody();
}
}
3、啟動該SpringBoot程序,測試服務消費者調用服務提供者;
在微服務架構中,服務注冊與發現是核心組件之一,手動指定每個服務是很低效的,Spring Cloud提供了多種服務注冊與發現的實現方式,例如:Eureka、Consul、Zookeeper。
Spring Cloud支持得最好的是Eureka,其次是Consul,再次是Zookeeper。
服務注冊:將服務所在主機、端口、版本號、通信協議等信息登記到注冊中心上;
服務發現:服務消費者向注冊中心請求已經登記的服務列表,然后得到某個服務的主機、端口、版本號、通信協議等信息,從而實現對具體服務的調用;
Eureka是一個服務治理組件,它主要包括服務注冊和服務發現,主要用來搭建服務注冊中心。
Eureka 是一個基于 REST 的服務,用來定位服務,進行中間層服務器的負載均衡和故障轉移;
Eureka是Netflix 公司開發的,Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務注冊和發現,也就是說Spring Cloud對Netflix Eureka 做了二次封裝;
Eureka 采用了C-S(客戶端/服務端)的設計架構,也就是Eureka由兩個組件組成:Eureka服務端和Eureka客戶端。Eureka Server 作為服務注冊的服務端,它是服務注冊中心,而系統中的其他微服務,使用 Eureka 的客戶端連接到 Eureka Server服務端,并維持心跳連接,Eureka客戶端是一個Java客戶端,用來簡化與服務器的交互、負載均衡,服務的故障切換等;
有了Eureka注冊中心,系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常運行。
著名的CAP理論指出,一個分布式系統不可能同時滿足C(一致性)、A(可用性)和P(分區容錯性)。
由于分區容錯性在是分布式系統中必須要保證的,因此我們只能在A和C之間進行權衡,在此Zookeeper保證的是CP, 而Eureka則是AP。
在ZooKeeper中,當master節點因為網絡故障與其他節點失去聯系時,剩余節點會重新進行leader選舉,但是問題在于,選舉leader需要一定時間, 且選舉期間整個ZooKeeper集群都是不可用的,這就導致在選舉期間注冊服務癱瘓。在云部署的環境下,因網絡問題使得ZooKeeper集群失去master節點是大概率事件,雖然服務最終能夠恢復,但是在選舉時間內導致服務注冊長期不可用是難以容忍的。
Eureka優先保證可用性,Eureka各個節點是平等的,某幾個節點掛掉不會影響正常節點的工作,剩余的節點依然可以提供注冊和查詢服務。而Eureka的客戶端在向某個Eureka注冊或時如果發現連接失敗,則會自動切換至其它節點,只要有一臺Eureka還在,就能保證注冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。
所以Eureka在網絡故障導致部分節點失去聯系的情況下,只要有一個節點可用,那么注冊和查詢服務就可以正常使用,而不會像zookeeper那樣使整個注冊服務癱瘓,Eureka優先保證了可用性。
Spring Cloud要使用Eureka注冊中心非常簡單和方便,Spring Cloud中的Eureka服務注冊中心實際上也是一個Spring Boot工程,我們只需通過引入相關依賴和注解配置就能讓Spring Boot構建的微服務應用輕松地與Eureka進行整合。
具體步驟如下:
1、 創建一個SpringBoot項目,并且添加SpringBoot的相關依賴;
03-springcloud-eureka-server
2、 添加eureka的依賴:
<!--Spring Cloud的eureka-server起步依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
3、 在Spring Boot的入口類上添加一個@EnableEurekaServer注解,用于
開啟Eureka注冊中心服務端
4、 在application.properties文件中配置Eureka服務注冊中心信息:
#內嵌定時tomcat的端口
server.port=8761
#設置該服務注冊中心的hostname
eureka.instance.hostname=localhost
#由于我們目前創建的應用是一個服務注冊中心,而不是普通的應用,默認情況下,這個應用會向注冊中心(也是它自己)注冊它自己,設置為false表示禁止這種自己向自己注冊的默認行為
eureka.client.register-with-eureka=false
#表示不去檢索其他的服務,因為服務注冊中心本身的職責就是維護服務實例,它不需要去檢索其他服務
eureka.client.fetch-registry=false
#指定服務注冊中心的位置
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka
啟動與測試Eureka服務注冊中心
1、完成上面的項目搭建后,我們就可以啟動SpringBoot程序,main方法運行;
2、啟動成功之后,通過在瀏覽器地址欄訪問我們的注冊中心;
我們前面搭建了服務提供者項目,接下來我們就可以將該服務提供者注冊到Eureke注冊中心,步驟如下:
1、在該服務提供者中添加eureka的依賴,因為服務提供者向注冊中心注冊服務,需要連接eureka,所以需要eureka客戶端的支持;
<!--SpringCloud集成eureka客戶端的起步依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、激活Eureka中的EnableEurekaClient功能:
在Spring Boot的入口函數處,通過添加@EnableEurekaClient注解來表明自己是一個eureka客戶端,讓我的服務提供者可以連接eureka注冊中心;
3、配置服務名稱和注冊中心地址
spring.application.name=02-springcloud-service-provider
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
4、啟動服務提供者SpringBoot程序的main方法運行;
5、啟動運行之后,通過在瀏覽器地址欄訪問我們之前搭建好的eureka注冊中心,就可以看到有一個服務已經注冊成功了;
我們已經搭建一個服務注冊中心,同時也向這個服務注冊中心注冊了服務,接下來我們就可以發現和消費服務了,這其中服務的發現由eureka客戶端實現,而服務的消費由Ribbon實現,也就是說服務的調用需要eureka客戶端和Ribbon兩者配合起來才能實現;
Eureka客戶端是一個Java客戶端,用來連接Eureka服務端,與服務端進行交互、負載均衡,服務的故障切換等;
Ribbon是一個基于HTTP 和 TCP 的客戶端負載均衡器,當使用Ribbon對服務進行訪問的時候,它會擴展Eureka客戶端的服務發現功能,實現從Eureka注冊中心中獲取服務端列表,并通過Eureka客戶端來確定服務端是否己經啟動。Ribbon在Eureka客戶端服務發現的基礎上,實現了對服務實例的選擇策略,從而實現對服務的負載均衡消費。
接下來我們來讓服務消費者去消費服務:
我們前面搭建了服務消費者項目,接下來我們就可以使用該服務消費者通過注冊中心去調用服務提供者,步驟如下:
1、在該消費者項目中添加eureka的依賴,因為服務消費者從注冊中心獲取服務,需要連接eureka,所以需要eureka客戶端的支持;
<!--SpringCloud集成eureka客戶端的起步依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、激活Eureka中的EnableEurekaClient功能:
在Spring Boot的入口函數處,通過添加@EnableEurekaClient注解來表明自己是一個eureka客戶端,讓我的服務消費者可以使用eureka注冊中心;
3、配置服務的名稱和注冊中心的地址:
spring.application.name=03-springcloud-web-consumer
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
4、前面我介紹了服務的發現由eureka客戶端實現,而服務的真正調用由ribbon實現,所以我們需要在調用服務提供者時使用ribbon來調用:
@LoadBalanced
@Bean
public RestTemplate restTemplate () {
return new RestTemplate();
}
加入了ribbon的支持,那么在調用時,即可改為使用服務名稱來訪問:
restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/cloud/hello", String.class).getBody();
5、完成上面的步驟后,我們就可以啟動消費者的SpringBoot程序,main方法運行;
6、啟動成功之后,通過在瀏覽器地址欄訪問我們的消費者,看是否可以正常調用遠程服務提供者提供的服務;