SpringCloud筆記(四)使用Consul代替Eureka作為註冊中心
目錄
1、Consul簡介
Consul 是 HashiCorp 公司推出的開源工具,用於實現分散式系統的服務發現與配置。與其它分散式服務註冊與發現的方案,Consul 的方案更“一站式”,內建了服務註冊與發現框架、分佈一致性協議實現、健康檢查、Key/Value 儲存、多資料中心方案,不再需要依賴其它工具(比如 ZooKeeper 等)。使用起來也較為簡單。Consul 使用 Go 語言編寫,因此具有天然可移植性(支援Linux、windows和Mac OS X);安裝包僅包含一個可執行檔案,方便部署,與 Docker 等輕量級容器可無縫配合。
2、下載
下載地址:https://www.consul.io/downloads.html
我這裡下載的是windows版本,下載後之後就只是一個exe檔案
將其所在路徑配置在windows的環境變數中
啟動consul的命令:
consul agent -dev -ui -node=cy
-dev開發伺服器模式啟動,-node結點名為cy,-ui可以用介面訪問,預設能訪問。
開啟命令列視窗輸入命令
consul預設埠是8500,因此在瀏覽器輸入http://localhost:8500 出現如下介面,則表示consul啟動成功:
3、搭建環境
在這裡搭建consul-order和consul-member兩個專案,並且在consul-order專案中遠端呼叫consul-member中的服務。
3.1 consul-member專案搭建
pom.xml:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- consul依賴的核心包 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <!--健康檢查依賴於此包 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
application.yml:
##服務名稱
spring:
application:
name: consul-member
#連線consul
cloud:
consul:
host: localhost
port: 8500
discovery:
hostname: 127.0.0.1
##本服務在tomcat中執行的埠號
server:
port: 8100
主類:
@SpringBootApplication
@RestController
@EnableDiscoveryClient //適用於zk consul
public class ConsulMemberApplication {
@RequestMapping("/getMember")
public String getMember() {
return "呼叫會員服務";
}
public static void main(String[] args) {
SpringApplication.run(ConsulMemberApplication.class, args);
}
}
@EnableDiscoveryClient 與@EnableEurekaClient區別
1、@EnableDiscoveryClient註解是基於spring-cloud-commons依賴,並且在classpath中實現; 適合於consul、zookeeper註冊中心
2,@EnableEurekaClient註解是基於spring-cloud-netflix依賴,只能為eureka作用;
3.2 consul-order專案搭建
pom.xml與上面相同
application.yml
spring:
application:
name: consul-order
cloud:
consul:
host: localhost
port: 8500
discovery:
hostname: 127.0.0.1
server:
port: 8200
主類:
第一種遠端呼叫方法
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class ConsulOrderApplication {
@Autowired
private RestTemplate restTemplate;
//兩種呼叫方式:一種是採用服務別名方式呼叫,另一種是直接呼叫,使用別名去註冊中心上獲取對應的服務呼叫地址
@RequestMapping("/getOrder01")
public String getOrder01() {
String serviceUrl = "http://consul-member/getMember";
return restTemplate.getForObject(serviceUrl, String.class);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsulOrderApplication.class, args);
}
}
第二種遠端呼叫方法:
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class ConsulOrderApplication {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("/getOrder02")
public String getOrder02() {
//根據名稱,在註冊中心查詢到具體url
String serviceUrl = getServiceURL("consul-member") + "/getMember";
String result = restTemplate.getForObject(serviceUrl, String.class);
return result;
}
private String getServiceURL(String appName) {
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances(appName);
if(serviceInstanceList != null && !serviceInstanceList.isEmpty()) {
return serviceInstanceList.get(0).getUri().toString();
}
return null;
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsulOrderApplication.class, args);
}
}
當兩個專案搭建完畢後,將這兩個專案同時啟動,在consul註冊中心檢視服務列表資訊:訪問http://localhost:8500
可以看到,已經將consul-member和consul-order服務全都註冊到cosul註冊中心了。
現在進行測試:通過瀏覽器訪問consul-order暴露出的介面,之後通過RPC呼叫consul-order的服務。
訪問:http://localhost:8200/getOrder01
由圖可知,遠端呼叫成功!
4、consul註冊中心原理
- 1、當 Producer 啟動的時候,會向 Consul 傳送一個 post 請求,告訴 Consul 自己的 IP 和 Port
- 2、Consul 接收到 Producer 的註冊後,每隔10s(預設)會向 Producer 傳送一個健康檢查的請求,檢驗Producer是否健康
- 3、當 Consumer 傳送 GET 方式請求 /api/address 到 Producer 時,會先從 Consul 中拿到一個儲存服務 IP 和 Port 的臨時表,從表中拿到 Producer 的 IP 和 Port 後再發送 GET 方式請求 /api/address
- 4、該臨時表每隔10s會更新,只包含有通過了健康檢查的 Producer
專案原始碼:https://github.com/liuzhoujian/springcloud-consul