前言
所謂服務治理,就是管理服務之間相互依賴調用的混亂。
沒有註冊中心前,服務之間調用其實是通過配置文件指定需要訪問服務的ip、端口等訪問信息的,
這樣一旦被調用方地址信息發生變化,調用者需及時修改其配置,再重新發布,流程繁瑣。
有了註冊中心後,服務啓動的時候將自己的地址信息以別名的方式註冊至註冊中心上,想要調用其他服務時,通過
別名的方式去註冊中心找到對應的值(地址是支持集羣的),進行調用即可
springcloud支持多種註冊中心,常用的有eureka,zookeeper和consul
euraka作爲註冊中心
服務註冊
消費者啓動的時候,使用服務別名,會發送一個rest請求到服務註冊中心獲取對應的服務信息,讓後會緩存到本地jvm客戶端中,
同時客戶端每隔30秒從服務器上更新一次。可以通過 fetch-inte vall-seconds=30參數進行修以通過
eureka.client.registry該參數默認值爲30, 單位爲秒。
服務下線
在系統運行過程中必然會面臨關閉或重啓服務的某個實例的情況,在服務關閉期有我們自然不希望客戶端會繼續調用關閉了的實例。
所以在客戶端程序中,當服務實例過正常的關閉操作時,它會觸發一個服務下線的REST請求給Eureka Server, 告訴服務中心:
“我要下線了”。服務端在接收到請求之後,將該服務狀態置爲下線(DOWN),井該下線事件傳播出去。
失效剔除
有些時候,我們的服務實例並不一定會正常下線,可能由於內存溢出、網絡故障氣因使得服務不能正常工作,而服務註冊中心
並未收到“服務下線”的請求。爲了從服務表中將這些無法提供服務的實例剔除,Eureka Server 在啓動的時候會創建一個
定時任多默認每隔一一段時間(默認爲60秒)將當前清單中超時(默認爲90秒)沒有續約的服務除出去
自我保護
服務註冊到Eureka Server之後,會維護個心跳連接, 告訴Eureka Server自己還活着。Eureka Server在運行期間,會統計心跳
失敗的比例在15分鐘之內是否低於85%(如果出現低於的情況單機調試的時候很容易滿足,實際在生產環境上通常是由於網絡不穩定
導致),EuServer會將當前的實例註冊信息保護起來,讓這些實例不會過期,儘可能保護這些註冊信息。但是,在這段保護期間內
實例若出現問題,那麼客戶端很容易拿到實際已經不存服務實例,會出現調用失敗的情況,所以客戶端必須要有容錯機制,比如可以
使用請使用重試、斷路器等機制。
###服務端口號
server:
port: 8100
##定義服務名稱
spring:
application:
name: yanxiaohui-order-service
eureka:
instance:
###註冊中心ip地址
hostname: 127.0.0.1
client:
serviceUrl:
##註冊地址
defaultZone: http://${eureka.instance.hostname}:8100/eureka/
####因爲自己是註冊中心,是否需要將自己註冊給自己的註冊中心(集羣的時候是需要是爲true)
register-with-eureka: false
###因爲自己是註冊中心, 不需要去檢索服務信息
fetch-registry: false
server:
# 測試時關閉自我保護機制,保證不可用服務及時踢出
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000
核心配置
server:
# 測試時關閉自我保護機制,保證不可用服務及時踢出
enable-self-preservation: false
##剔除失效服務間隔
eviction-interval-timer-in-ms: 2000
maven
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--SpringCloud eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<!-- 注意: 這裏必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
配置文件application.yml
###服務端口號
server:
port: 8100
###eureka 基本信息配置
eureka:
instance:
###註冊到eurekaip地址
hostname: 127.0.0.1
client:
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
###因爲自己是爲註冊中心,不需要自己註冊自己
register-with-eureka: false
###因爲自己是爲註冊中心,不需要檢索服務
fetch-registry: false
啓動Eureka服務
@EnableEurekaServer
@SpringBootApplication
public class AppEureka {
public static void main(String[] args) {
SpringApplication.run(AppEureka.class, args);
}
}
微服務註冊
maven
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringBoot整合Web組件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot整合eureka客戶端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<!-- 注意: 這裏必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
配置文件application.yml
###服務啓動端口號
server:
port: 8000
###服務名稱(服務註冊到eureka名稱)
spring:
application:
name: yanxiaohui-order-service
###服務註冊到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
###因爲該應用爲註冊中心,不會註冊自己
register-with-eureka: true
###是否需要從eureka上獲取註冊信息
fetch-registry: true
registry-fetch-interval-seconds: 30
# 心跳檢測檢測與續約時間
# 測試時將值設置設置小些,保證服務關閉後註冊中心能及時踢出服務
instance:
###Eureka客戶端向服務端發送心跳的時間間隔,單位爲秒(客戶端告訴服務端自己會按照該規則)
lease-renewal-interval-in-seconds: 1
####Eureka服務端在收到最後一次心跳之後等待的時間上限,單位爲秒,超過則剔除(客戶端告訴服務端按照此規則等待自己)
lease-expiration-duration-in-seconds: 2
服務接口
@RestController
public class OrderController {
@RequestMapping("/index")
public String index() {
return "微服務訂單接口首頁";
}
}
微服務註冊
@SpringBootApplication
@EnableEurekaClient
public class OrderServiceApp {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApp.class, args);
}
}
同理,將用戶服務也註冊至eureka
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/getOrder")
public String getOrder() {
// order 使用rpc 遠程調用技術 調用 訂單服務
String url = "http://yanxiaohui-order-service/index";
String result = restTemplate.getForObject(url, String.class);
System.out.println("result:" + result);
return result;
}
}
@SpringBootApplication
@EnableEurekaClient
public class UserrServiceApp {
public static void main(String[] args) {
SpringApplication.run(UserrServiceApp.class, args);
}
@Bean
@LoadBalanced // 以別名方式從註冊中心獲取對應服務地址列表(可實現本地負載均衡)
RestTemplate restTemplate() {
return new RestTemplate();
}
}
eureka高可用原理
Eureka高可用實際上將自己作爲服務向其他服務註冊中心註冊自己,這樣就可以形成一組相互註冊的服務註冊
中心,從而實現服務清單的互相同步,達到高可用效果。
Eureka集羣環境搭建
-------------------------------eureka1配置信息---------------------------------
###服務端口號
server:
port: 8100
###eureka 基本信息配置
spring:
application:
name: eureka-server
eureka:
instance:
###註冊到eurekaip地址
hostname: 127.0.0.1
client:
serviceUrl:
defaultZone: http://127.0.0.1:8200/eureka/
###因爲自己是爲註冊中心,不需要自己註冊自己
register-with-eureka: true
###因爲自己是爲註冊中心,不需要檢索服務
fetch-registry: true
-------------------------------eureka2配置信息-------------------------------
###服務端口號
server:
port: 8200
###eureka 基本信息配置
spring:
application:
name: eureka-server
eureka:
instance:
###註冊到eurekaip地址
hostname: 127.0.0.1
client:
serviceUrl:
defaultZone: http://127.0.0.1:8100/eureka/
###因爲自己是爲註冊中心,不需要自己註冊自己
register-with-eureka: true
###因爲自己是爲註冊中心,不需要檢索服務
fetch-registry: true
-------------------------------客戶端集成Eureka集羣-------------------------------
server:
port: 8000
spring:
application:
name: yanxiaohui-order-service
###集羣地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka,http://localhost:8200/eureka
register-with-eureka: true
fetch-registry: true
Consul用作註冊中心
Consul環境搭建
官方下載地址下載window版,解壓得到一個可執行文件。 (https://www.consul.io/downloads.html)
設置環境變量,讓我們直接在cmd裏可直接使用consul使命。在path後面添加consul所在目錄
例如D:\consul_1.1.0_windows_amd64
啓動consul命
consul agent -dev -ui -node=cy
-dev開發服務器模式啓動,-node結點名爲cy,-ui可以用界面訪問,默認能訪問。
測試訪問地址:http://localhost:8500
客戶端註冊
maven
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringBoot整合Web組件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringCloud consul-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies>
<!-- 注意: 這裏必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
配置文件
###eureka 服務端口號
server:
port: 8502
spring:
application:
name: consul-order
####consul註冊中心地址
cloud:
consul:
host: localhost
port: 8500
discovery:
hostname: 192.168.1.240
DiscoveryClient用法
@SpringBootApplication
@EnableDiscoveryClient
// @EnableDiscoveryClient 開啓其他註冊中心 比如consul、zookeeper
public class OrderServiceApp {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApp.class, args);
}
}
// discoveryClient接口 可以獲取註冊中心上的實例信息。
@RequestMapping("/getServiceUrl")
public List<String> getServiceUrl() {
List<ServiceInstance> list = discoveryClient.getInstances("yanxiaohui-order-service");
List<String> services = new ArrayList<>();
for (ServiceInstance serviceInstance : list) {
if (serviceInstance != null) {
services.add(serviceInstance.getUri().toString());
}
}
return services;
}
// @EnableDiscoveryClient註解是基於spring-cloud-commons依賴,並且在classpath中實現;
// 適合於consul、zookeeper註冊中心
// @EnableEurekaClient註解是基於spring-cloud-netflix依賴,只能爲eureka作用;
zookeeper用作註冊中心
Maven
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringBoot整合Web組件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot整合eureka客戶端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
</dependencies>
<!-- 注意: 這裏必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
application.yml
###訂單服務的端口號
server:
port: 8002
###服務別名----服務註冊到註冊中心名稱
spring:
application:
name: yanxiaohui-order-service
cloud:
zookeeper:
connect-string: 127.0.0.1:2181
###訂單服務的端口號
server:
port: 8003
###服務別名----服務註冊到註冊中心名稱
spring:
application:
name: yanxiaohui-user-service
cloud:
zookeeper:
connect-string: 127.0.0.1:2181
啓動zk-member服務和zk-order服務,可以發現在Zk服務器端上有對應的節點信息(臨時節點)