服務治理:Spring Could Eureka
目錄:
1 服務治理
2 服務註冊中心搭建(管理服務,提供註冊與發現)
3 註冊服務提供者(提供服務)
4 高可用註冊中心
5 註冊服務消費者(消費服務)
6 總結
介紹:
Spring Could Eureka是Spring Could Netfix(核心組件)中的一部分,主要負責微服務框架的服務治理功能。註冊中心主要提供註冊與發現功能,服務提供者提供服務,服務消費者消費服務。其具有Spring Boot風格的自動化配置。該節主要爲服務治理的簡單搭建。相關配置詳情見"Eureka配置詳解"。
服務端:註冊中心註解:@EnableEurekaServer
客戶端:消費,提供註解:@EnableDiscoveryClient
主要環境配置:jdk1.8、maven3.3.9、Spring Boot2.0、IDEA2017
1 服務治理
服務治理主要分爲服務註冊於服務發現,是微服務架構的核心與基礎。用以保證服務間的正常運行,降低維護成本。(服務多的時候尤爲重要)。
1.1 服務註冊
服務單元向註冊中心登記自己提供的服務。包含主機、端口號、版本號、通信協議等。註冊中心將根據服務名稱分類組織服務清單,當進程啓動時,註冊中心會維護該清單。除此之外服務註冊中心需要以心跳的方式監測服務是否可用,不可用需要從清單剔除,達到排查故障服務的效果。 --(怎麼監控到,怎麼剔除,缺少的服務(服務發現)怎麼解決?)
註冊中心會維護該清單如:
服務A: 192.168.0.100:8081;192.168.0.101:8082
服務B: 192.168.0.100:8080;192.168.0.104:8082;192.168.0.100:8081
1.2 服務發現
在服務治理框架下,服務間調用是通過服務名發起調用請求。如服務A:192.168.0.100:8081,192.168.0.101:8082位置可用。當調用服務 A時將採取輪詢調用(需要負載均衡)。但是爲了性能等,不會採用每次都向服務註冊中心獲取服務的方式。
2 服務註冊中心搭建
作用:該註冊中心用於管理服務提供者的基本運行狀況。註冊中心重啓,維護的服務表將清空。
主要環境配置:jdk1.8、maven3.3.9、Spring Boot 2.0
2.1 pom.xml
添加spring-cloud-starter-netflix-eureka-server
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<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>
<!--euraka 2.0註冊中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<!--@EnableEurekaServer註解報錯的一種解決方式-->
<!--<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.BUILD-SNAPSHOT</version><!--spring boot 2.0 與1.0 配置時需要選擇對應版本-->
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>compile</scope>
<version>19.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2 application.properties
#端口
server.port= 1111
#項目名稱
#server.servlet.context-path=/eureka11
#ip 註冊中心ip地址
eureka.instance.hostname=localhost
# 不向註冊中心註冊自己,,默認true
eureka.client.registerWithEureka=false
# 註冊中心不需要檢索服務,職責是維護服務是維護實例,默認true
eureka.client.fetchRegistry=false
eureka.instance.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
#本地關閉自我保護機制進行測試,默認true(未關閉)
eureka.server.enableSelfPreservation=false
2.3 Spring Boot啓動類
使用@EnableEurekaServer註解開啓註冊服務中心。
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
System.out.println("args = [" + args + "]");
}
}
配置完成後,啓動EurekaApplication類main()方法。瀏覽器輸入http://localhost:1111/,結果如下圖。 Instances currently registered with Eureka欄無數據。如下圖:
3 註冊服務提供者
搭建服務,並將服務註冊當上面創建的註冊中心中。讓註冊中心統一管理服務。當服務在請求時,該服務會註冊到註冊中心,但是服務死亡時,註冊中心並不是馬上不知道, Eureka server和client之間每隔30秒會進行一次心跳通信,告訴server,client還活着。由此引出兩個名詞:
Renews threshold:server期望在每分鐘中收到的心跳次數
Renews (last min):上一分鐘內收到的心跳次數。
3.1 pom.xml (pom.xml與2.1中xml相同)
3.2 application.properties
將服務註冊到上面的註冊中心 http://localhost:8888/eureka/
# 端口
server.port= 8888
# 服務名稱
spring.application.name=hello-service
#將服務hello-service 註冊到 http://localhost:1111/eureka/
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
3.3 Spring Boot啓動類
@EnableDiscoveryClient
@SpringBootApplication
public class ProvideApplication {
public static void main(String[] args) {
SpringApplication.run(ProvideApplication.class, args);
System.out.println("args = [" + args + "]");
}
}
測試接口
@RestController
@RequestMapping("/user")
public class UserController {
/**獲取logger實例*/
private final Logger logger = Logger.getLogger(getClass().toString());
@Value("${server.port}")
private String port;
@Value("${spring.application.name}")
private String hostname;
@RequestMapping("/login")
public String login(){
logger.info("服務host:"+port+",service_id:"+hostname);
return 服務host:"+port+",service_id:"+hostname;
}
}
配置完成後,啓動DemoApplication類main()方法。瀏覽器輸入http://localhost:8888/user/login,請求完成後,出現"這是一個服務提供者!"。
刷新註冊中心http://localhost:1111/ ; Instances currently registered with Eureka欄出現數據。如下圖:
此時如果關閉服務hello-service,註冊中心顯示服務還存在。當心跳時間達到時,加入自我保護模式,說明此時有服務掛掉。如下圖:
4 高可用註冊中心
將註冊中心相互註冊,它既是註冊中心,也是服務提供者。考慮發生故障時。主要實現: application-peer1.properties :註冊中心peer1的serviceUr2
# 服務名稱
spring.application.name=eureka-service
#端口
server.port= 1111
#ip 註冊中心ip地址
eureka.instance.hostname=peer1
eureka.client.serviceUrl.defaultZone=http://peer2:2222/eureka/
application-peer2.properties註冊中心peer2的serviceUr1
# 服務名稱
spring.application.name=eureka-service
#端口
server.port= 2222
#ip 註冊中心ip地址=主機名稱
eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/
application.properties
# 服務名稱
spring.application.name=eureka-service
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/;
http://peer2:2222/eureka/
/etc/hosts 加入
127.0.0.1 peer1
127.0.0.1 peer2
啓動:java -jar eureka-server-1.0.0.jar --spring.profiles-active=peer1(或者peer2)
注:peer1、peer2爲主機名稱,可以直接使用主機ip。需要配置參數eureka.instance.preferIpAddressTrue=true,默認爲flase。
5 服務消費者(服務發現與消費)
服務消費前準備:啓動註冊中心,啓動服務提供(端口8888,端口8800),
啓動命令:java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8888 (或者8800)
服務消費者:服務發現由Eureka的客戶端完成,服務消費的任務由Ribbon(http和tcp的客戶端負載均衡器)完成,
接下來創建服務消費者:
5.1 pom.xml
添加:spring-cloud-starter-netflix-eureka-server;spring-cloud-starter-netflix-ribbon
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>customer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>customer_server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<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>
<!--euraka 2.0註冊客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--ribbon 用於服務消費-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.BUILD-SNAPSHOT</version><!--spring boot 2.0 與1.0 配置時需要選擇對應版本-->
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>compile</scope>
<version>19.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
5.2 application.properties
# 端口
server.port= 8089
# 服務名稱
spring.application.name=ribbon-customer
#將服務hello-service 註冊到 http://localhost:1111/eureka/
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
5.3 Spring Boot啓動類
配置RestTemplate,註解@EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class CustomerApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(CustomerApplication.class, args);
}
}
測試類:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/login")
public String login()
{
//hello-service爲服務提供者的服務名稱
return "我是一個消費者去調用==》"+restTemplate.getForEntity("http://hello-service/user/login",String.class);
}
}
啓動後,進入測試。 註冊中心顯示如下圖:
測試接口輸入:http://localhost:8089/user/login。結果將輪番調用hello-service服務的8888與8800端口。
6 總結
-
服務統一交由註冊中管理:eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
-
消費者調用服務時,直接調用服務名稱。spring.application.name=ribbon-customer
參考:
1 《Spring Could 微服務實戰》 翟永超 電子工業出版社 2017.5
參考網站:http://blog.didispace.com/Spring-Cloud基礎教程/
源碼地址:
https://github.com/zlk19921105/spring_cloud
其中:註冊中心eureka-server;服務提供provide-services;服務消費customer-server