思維導圖:
引言
Spring Cloud Eureka是Spring Cloud Netflix微服務套件中的一部分,它基於Netflix Eureka做了二次封裝,主要負責完成微服務架構中的服務治理功能.
服務治理是微服務架構中最爲核心和基礎的模塊,他主要實現微服務實例的註冊與發現.爲什麼我們需要服務治理來管理微服務實例呢?當微服務實例較少時,我們可以通過某些靜態配置來進行服務的聲明和調用,隨着業務的發展,微服務實例個數增加時,再使用靜態申明就會導致極大的維護成本.
本文會通過 使用部分:環境搭建 ,原理部分:功能體系 來介紹Eureka的簡單使用.
一.環境搭建
Eureka的環境主要分爲服務端和客戶端.服務端也稱爲註冊中心.每個微服務都需要向註冊中心註冊自己能提供的服務.客戶端則會將自己的服務向註冊中心註冊,並向註冊中心獲取可以調用的服務.
1.1 搭建註冊中心
我們將以單節點和雙節點的方式來搭建註冊中心.
1.1.1 單節點註冊中心
首先使用Spring Boot搭建一個基礎環境,以下是Maven引用:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
隨後,在Application.class處使用@EnableEurekaServer啓用EurekaServer
@SpringBootApplication
@EnableEurekaServer
public class SpringCloudServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudServerApplication.class,args);
}
}
最後,配置Eureka相關參數
## 服務名稱
spring.application.name=eureka-server
##服務端口號
server.port=1111
## 是否向註冊中心註冊自己.單節點的註冊中心不需要此功能
eureka.client.register-with-eureka=false
## 是否需要檢索可用微服務.單節點的註冊中心不需要此功能
eureka.client.fetch-registry=false
## Eureka服務URL
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
啓動服務,進入http://localhost:1111/ 可以看到註冊中心的相關信息
1.1.2 雙節點註冊中心
對於分佈式架構來說,單節點註冊中心如果出現錯誤將是致命性的.所以,註冊中心至少 得有兩個.使用多節點的註冊中心式,每個註冊中心會向其他註冊中心註冊,所以兩臺註冊中心的配置如下:
peer1:
## 服務名稱
spring.application.name=eureka-server
##服務端口號
server.port=1111
## 實例主機地址
eureka.instance.hostname=peer1
## 服務URL
eureka.client.service-url.defaultZone=http://peer2:1112/eureka/
peer2:
spring.application.name=eureka-server
server.port=1112
eureka.instance.hostname=peer2
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/
可以看到,兩臺服務註冊中心會互相註冊,所以需要將一下參數設置爲true
- eureka.client.register-with-eureka
- eureka.client.fetch-registry
然後,在配置中,我們看到微服務實例地址爲peer1和peer2,即eureka.instance.hostname.這是因爲我在本地測試,所以還需要再host文件中做 相關映射.Window hosts文件地址:C:\Windows\System32\drivers\etc\hosts,在文件中添加兩行:
127.0.0.1 peer1
127.0.0.1 peer2
我們分別啓動配置不同的兩個註冊中心服務.進入http://localhost:1111/ 或者http://localhost:1112/可以看到如下界面:
至此,雙節點註冊中心搭建完畢.
1.2 服務提供者
接下來,我們嘗試向註冊中心註冊服務.當然,Eureka客戶端的Maven引用稍稍不同於Eureka服務端:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
需要使用@EnableDiscoveryClient開啓Eureka客戶端服務
@SpringBootApplication
@EnableDiscoveryClient
public class SpringCloudClientApplication {
public static void main(String[] args){
SpringApplication.run(SpringCloudClientApplication.class,args);
}
}
最後,相關配置爲:
spring.application.name=hello-client-service
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/,http://localhost:1112/eureka/
至現在位置,我們這個服務提供者還沒有一個可供調用的服務.所以添加一個簡單的Controller,用於打印當前註冊中心信息的接口.
@RestController
public class HelloController {
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String index(){
ServiceInstance serviceInstance = discoveryClient.getLocalServiceInstance();
System.out.println("host:" + serviceInstance.getHost() + ",serviceId:" + serviceInstance.getServiceId());
return "hello world";
}
}
啓動服務,可以看到Eureka的管理頁面中有這一服務的信息了.
手動調用此接口http://localhost:8080/hello,可以看到hello world.
最後,將此producer服務提供者打包後,我們使用命令用不同的端口後再次啓動此服務.
java -jar eureka-client-1.0-SNAPSHOT.jar --server.port=8081
java -jar eureka-client-1.0-SNAPSHOT.jar --server.port=8082
可以看到,頁面上已有三個同名的服務了,他們的端口號分別是8080,8081,8082
1.3 服務消費者
現在,我們有了雙節點的服務註冊中心,和三個一樣的服務提供者.接下來,我們構建具有簡單的負載均衡的服務消費者來獲取並調用服務.
消費者配置:
spring.application.name=consumer-service
server.port=9000
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/,http://localhost:1112/eureka/
服務消費者和服務提供者的配置完全一樣.只是因爲我們希望在這個消費者進行負載均衡,所以需要引入Ribbon.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
接下來,我們需要調用服務了.,這個HELLO-CLIENT-SERVICE是我服務提供者的spring.application.name=hello-client-service
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consume",method = RequestMethod.GET)
public String consume(){
return restTemplate.getForEntity("http://HELLO-CLIENT-SERVICE/hello",String.class).getBody();
}
}
接下來,多次調用http://localhost:9000/consume,可以看到,多臺服務提供者都會打印以下信息.
至此,一個簡單的微服務治理體系搭建完成.
二.功能體系
第一小節完成的一個簡單的微服務治理體系.接下來,我們看看以上三者的功能和作用分別是什麼.
在實際使用中一個微服務實例一般即是消費者也是提供者.
2.1 服務註冊中心
- 服務維護:儲存服務提供者註冊的服務元數據
- 失效剔除:當服務提供者失效時,剔除出可用服務列表
- 服務同步:接收到一個服務提供者註冊的服務時,會將此信息同步給其他註冊中心
- 自我保護:服務提供者在服務註冊中心註冊成功後,會維護一個心跳連接,告訴註冊中心自己還活着.如果統計的心跳連接失敗的比例在15分鐘內地域85%,註冊中心將會把當前實例的信息保護起來,讓其不會過期.我們將三個服務提供者關掉一個,等一會就會出現如下提示,就表示已有服務進入自我保護機制了.
2.2 服務提供者
- 服務註冊:服務在啓動時向註冊中心註冊服務
- 服務續約:註冊成功後維護一個心跳連接告訴註冊中心服務正常,防止被剔除.
2.3 服務消費者
- 服務獲取:服務啓動時,向註冊中心獲取服務清單,此清單沒30秒更新一次.
- 服務調用:服務消費者可以根據服務信息自己選擇合適的服務調用方式.註冊中心有Region和Zone的概念.一個Region可能具有多個Zone,一個Zone下可能具有多個服務實例.進行服務調用時,會優先訪問同一個Zone下的服務實例
- 服務下線:當服務面臨重啓或關閉的情況下,告訴註冊中心我要下下線了.