1. 什么服務注冊中心
所謂服務注冊中心就是在整個的微服務架構中單獨提出一個服務,這個服務不完成系統的任何的業務功能,僅僅用來完成對整個微服務系統的服務注冊和服務發現,以及對服務健康狀態的監控和管理功能。
服務注冊中心
- 可以對所有的微服務的信息進行存儲,如微服務的名稱、IP、端口等
- 可以在進行服務調用時通過服務發現查詢可用的微服務列表及網絡地址進行服務調用
- 可以對所有的微服務進行心跳檢測,如發現某實例長時間無法訪問,就會從服務注冊表移除該實例。
2. 常用的注冊中心
springcloud支持的多種注冊中心Eureka(netflix)、Consul、Zookeeper、以及阿里巴巴推出Nacos組件。
這些注冊中心在本質上都是用來管理服務的注冊和發現以及服務狀態的檢查的。
3.Eureka
# 0.簡介
- https://github.com/Netflix/eureka/wiki
- Eureka是Netflix開發的服務發現框架,本身是一個基於REST的服務。SpringCloud將它集成在其子項目spring-cloud-netflix中,以實現SpringCloud的服務注冊和發現功能。
Eureka包含兩個組件:Eureka Server和Eureka Client。
單體應用 ------> 分類服務 商品服務 訂單服務 用戶服務......
Eureka Server 組件 : 服務注冊中心組件 管理所有服務 支持所有服務注冊
Eureka Client 組件 : 分類服務 商品服務 訂單服務(微服務)
開發Eureka Server
1.創建項目並引入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 https://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.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>02-eurekaserver8761</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>02-eurekaserver8761</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<!--定義springcloud使用版本號-->
<spring-cloud.version>Hoxton.SR6</spring-cloud.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>
<!--引入 eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<!--全局管理springcloud版本,並不會引入具體依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</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>
</project>
2.編寫配置application.properties
server.port=8761 #執行服務端口
spring.application.name=eurekaserver #指定服務名稱 唯一標識
eureka.client.service-url.defaultZone=http://localhost:8761/eureka #指定服務注冊中心的地址
3.開啟Eureka Server,入口類加入注解
@SpringBootApplication
@EnableEurekaServer
public class Eurekaserver8761Application {
public static void main(String[] args) {
SpringApplication.run(Eurekaserver8761Application.class, args);
}
}
4.訪問Eureka的服務注冊頁面
5.雖然能看到管理界面為什么項目啟動控制台報錯?
eureka server 服務注冊中心 & client 微服務
- 出現上述問題原因:eureka組件包含 eurekaserver 和 eurekaclient。server是一個服務注冊中心,用來接受客戶端的注冊。client的特性會讓當前啟動的服務把自己作為eureka的客戶端進行服務中心的注冊,當項目啟動時服務注冊中心還沒有創建好,所以找不到服務的客戶端組件就直接報錯了,當啟動成功服務注冊中心創建好了,日后client也能進行注冊,就不再報錯啦!
6.關閉Eureka自己注冊自己
還是在application.properties
server.port=8761
spring.application.name=eurekaserver
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.client.register-with-eureka=false #不再將自己同時作為客戶端進行注冊
eureka.client.fetch-registry=false #關閉作為客戶端時從eureka server獲取服務信息
7.再次啟動,當前應用就是一個單純Eureka Server,控制器也不再報錯
開發Eureka Client
項目拆分出來的一個個微服務
1.創建新的boot項目並引入eureka client依賴
<?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 https://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.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>02-eurekaserver8888</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>02-eurekaserver8888</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<!--定義springcloud使用版本號-->
<spring-cloud.version>Hoxton.SR6</spring-cloud.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>
<!--引入eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<!--全局管理springcloud版本,並不會引入具體依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</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>
</project>
2.編寫配置application.properties
server.port=8888
spring.application.name=eurekaclient8888 #服務名稱唯一標識
eureka.client.service-url.defaultZone=http://localhost:8761/eureka #eureka注冊中心地址
3.開啟eureka客戶端加入注解
@SpringBootApplication
@EnableEurekaClient
public class Eurekaclient8888Application {
public static void main(String[] args) {
SpringApplication.run(Eurekaclient8888Application.class, args);
}
}
4.啟動之前的8761的服務注冊中心,再啟動eureka客戶端服務
5.查看eureka server的服務注冊情況
6.eureka自我保護機制
# 0.服務頻繁啟動時 EurekaServer出現警告
- EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
1.自我保護機制
- 官網地址: https://github.com/Netflix/eureka/wiki/Server-Self-Preservation-Mode
- 默認情況下,如果Eureka Server在一定時間內(默認90秒)沒有接收到某個微服務實例的心跳,Eureka Server將會移除該實例。但是當網絡分區故障發生時,微服務與Eureka Server之間無法正常通信,而微服務本身是正常運行的,此時不應該移除這個微服務,所以引入了自我保護機制。
- Eureka Server在運行期間會去統計心跳失敗比例在 15 分鍾之內是否低於 85%,如果低於 85%,Eureka Server 會將這些實例保護起來,讓這些實例不會過期。這種設計的哲學原理就是"寧可信其有不可信其無!"。自我保護模式正是一種針對網絡異常波動的安全保護措施,使用自我保護模式能使Eureka集群更加的健壯、穩定的運行。
2.在eureka server端關閉自我保護機制
eureka.server.enable-self-preservation=false #關閉自我保護
eureka.server.eviction-interval-timer-in-ms=3000 #超時3s自動清除
3.微服務修改減短服務心跳的時間
eureka.instance.lease-expiration-duration-in-seconds=10 #用來修改eureka server默認接受心跳的最大時間 默認是90s
eureka.instance.lease-renewal-interval-in-seconds=5 #指定客戶端多久向eureka server發送一次心跳 默認是30s
4.盡管如此關閉自我保護機制還是會出現警告
- THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
- `官方並不建議在生產情況下關閉
7.eureka 停止更新
# 1.官方停止更新說明
- https://github.com/Netflix/eureka/wiki
- 在1.x版本項目還是活躍的,但是在2.x版本中停止維護,出現問題后果自負!!!
4.Consul
consul 服務注冊中心 啟動consul服務注冊中心 運行
consul 客戶端 將springcloud 客戶端(微服務)
consul 簡介
- https://www.consul.io
- consul是一個可以提供服務發現,健康檢查,多數據中心,Key/Value存儲等功能的分布式服務框架,用於實現分布式系統的服務發現與配置。與其他分布式服務注冊與發現的方案,使用起來也較為簡單。Consul用Golang實現,因此具有天然可移植性(支持Linux、Windows和Mac OS X);安裝包僅包含一個可執行文件,方便部署。
1.安裝consul
windows下啟動consul
- 下載並且解壓https://www.consul.io/downloads
- 找到有exe文件那個地址(不要雙擊!!!不要雙擊!!!不要雙擊!!!)
- 在路徑的地方輸出cmd,也就是這個文件所在的地址欄輸入cmd
- 在cmd窗口里面輸入consul.exe(這會兒只是安裝完畢了,並沒有啟動,或許沒反應直接下一步)
- 還是在安裝好consul的cmd窗口里面輸入:consul agent -dev
- 啟動完畢,在瀏覽器輸入http://localhost:8500/
- 完成啦
consul的服務端
2.開發consul 客戶端即微服務
# 1.創建boot項目並引入consul客戶端依賴
<?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 https://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.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>03-consulclient8889</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>03-consulclient8889</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<!--定義springcloud使用版本號-->
<spring-cloud.version>Hoxton.SR6</spring-cloud.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-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入consul依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies>
<!--全局管理springcloud版本,並不會引入具體依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</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>
</project>
# 2.編寫properties配置
server.port=8889
spring.application.name=consulclient8889
spring.cloud.consul.host=localhost #注冊consul服務的主機
spring.cloud.consul.port=8500 #注冊consul服務的端口號
# 3.啟動服務查看consul界面服務信息
3.consul 開啟健康監控檢查
# 1.開啟consul健康監控
- 默認情況加consul監控健康是開啟的,但是必須依賴健康監控依賴才能正確監控健康狀態所以直接啟動會顯示錯誤,引入健康監控依賴之后服務正常
<!-- 這個包是用做健康度監控的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
4.consul 關閉健康監控檢查
server.port=8889
spring.application.name=consulclient8889
spring.cloud.consul.host=localhost #注冊consul服務的主機
spring.cloud.consul.port=8500 #注冊consul服務的端口號
spring.cloud.consul.discovery.register-health-check=false #關閉consu了服務的健康檢查[不推薦]
spring.cloud.consul.discovery.service-name=${spring.application.name} #指定注冊的服務名稱 默認就是應用名
5.不同注冊中心區別
1.CAP定理
服務注冊中心集群 node1 node2 node3 ... eureka(AP) consul zk(CP)
- CAP定理:CAP定理又稱CAP原則,指的是在一個分布式系統中,一致性(Consistency)、可用性(Availability)、分區容錯性(Partition tolerance)。CAP 原則指的是,這三個要素最多只能同時實現兩點,不可能三者兼顧。
- 一致性(C):在分布式系統中的所有數據備份,在同一時刻是否同樣的值。(等同於所有節點訪問同一份最新的數據副本)
- 可用性(A):在集群中一部分節點故障后,集群整體是否還能響應客戶端的讀寫請求。(對數據更新具備高可用性)
- 分區容忍性(P),就是高可用性,一個節點崩了,並不影響其它的節點(100個節點,掛了幾個,不影響服務,越多機器越好)
2.Eureka特點
- Eureka中沒有使用任何的數據強一致性算法保證不同集群間的Server的數據一致,僅通過數據拷貝的方式爭取注冊中心數據的最終一致性,雖然放棄數據強一致性但是換來了Server的可用性,降低了注冊的代價,提高了集群運行的健壯性。
3.Consul特點
- 基於Raft算法,Consul提供強一致性的注冊中心服務,但是由於Leader節點承擔了所有的處理工作,勢必加大了注冊和發現的代價,降低了服務的可用性。通過Gossip協議,Consul可以很好地監控Consul集群的運行,同時可以方便通知各類事件,如Leader選擇發生、Server地址變更等。
4.zookeeper特點
- 基於Zab協議,Zookeeper可以用於構建具備數據強一致性的服務注冊與發現中心,而與此相對地犧牲了服務的可用性和提高了注冊需要的時間。