您好,登錄后才能下訂單哦!
服務治理機制
我們來進一步了解一下Eureka 基礎架構中各個元素的一些通信行為, 以此來理解基于Eureka 實現的服務治理體系是如何運作起來的。以下圖為例, 其中有這樣幾個重要元素:
? "服務注冊中心-1" 和“ 服務注冊中心-2", 它們互相注冊組成了高可用集群。
? "服務提供者” 啟動了兩個實例, 一個注冊到“ 服務注冊中心-1" 上, 另外一個注冊到“ 服務注冊中心-2" 上。
? 還有兩個“ 服務消費者“, 它們也都分別只指向了一個注冊中心。
一、服務提供者
1.服務注冊
“服務提供者” 在啟動的時候會通過發送REST請求的方式將自己注冊到Eureka Server上, 同時帶上了自身服務的一些元數據信息。Eureka Server接收到這個REST請求之后,將元數據信息存儲在一個雙層結構Map中, 其中第一層的key是服務名, 第二層的key是具體服務的實例名。(我們可以回想一下之前在實現Ribbon負載均衡的例子中, Eureka信息面板中一個服務有多個實例的清況, 這些內容就是以這樣的雙層Map形式存儲的。)
在服務注冊時, 需要確認一下eureka.cli ent.register-with-eureka=true參數是否正確, 該值默認為true。若設置為false將不會啟動注冊操作。
2.服務同步
如架構圖中所示, 這里的兩個服務提供者分別注冊到了兩個不同的服務注冊中心上,也就是說, 它們的信息分別被兩個服務注冊中心所維護。此時, 由于服務注冊中心之間因互相注冊為服務, 當服務提供者發送注冊請求到一個服務注冊中心時, 它會將該請求轉發給集群中相連的其他注冊中心, 從而實現注冊中心之間的服務同步。通過服務同步,兩個服務提供者的服務信息就可以通過這兩臺服務注冊中心中的任意一臺獲取到。
3.服務續約
在注冊完服務之后,服務提供者會維護一個心跳用來持續告訴EurekaServer: "我還活著”, 以防止Eureka Server 的“ 剔除任務” 將該服務實例從服務列表中排除出去, 我們稱該操作為服務續約(Renew)。
關于服務續約有兩個重要屬性,我們可以關注并根據需要來進行調整:
eureka.instance.lease-renewal-interval-in-seconds=30
eureka.instance.lease-expiration-duration-in-seconds=90
eureka.instance.lease-renewal-interval-in-seconds 參數用于定義服務續約任務的調用間隔時間,默認為30秒。
eureka.instance.lease-expiration-duration-in-seconds參數用于定義服務失效的時間,默認為90秒。
二、服務消費者
1.獲取服務
到這里, 在服務注冊中心已經注冊了一個服務, 并且該服務有兩個實例。當我們啟動服務消費者的時候, 它會發送一個REST請求給服務注冊中心,來獲取上面注冊的服務清單。為了性能考慮, Eureka Server會維護一份只讀的服務清單來返回給客戶端,同時該緩存清單會每隔30秒更新一次。
獲取服務是服務消費者的基礎,所以必須確保eureka.client.fetch-registry=true參數沒有被修改成false, 該值默認為true。若希望修改緩存清單的更新時間,可以通過eureka.client.registry-fetch-interval-seconds=30參數進行修改,該參數默認值為30, 單位為秒。
2.服務調用
服務消費者在獲取服務清單后,通過服務名可以獲得具體提供服務的實例名和該實例的元數據信息。因為有這些服務實例的詳細信息, 所以客戶端可以根據自己的需要決定具體調用哪個實例,在ribbon中會默認采用輪詢的方式進行調用,從而實現客戶端的負載均衡。
對于訪問實例的選擇,Eureka中有Region和Zone的概念, 一個Region中可以包含多個Zone, 每個服務客戶端需要被注冊到一個Zone中, 所以每個客戶端對應一個Region和一個Zone。在進行服務調用的時候, 優先訪問同處一個Zone 中的服務提供方, 若訪問不到,就訪問其他的Zone。
3.服務下線
在系統運行過程中必然會面臨關閉或重啟服務的某個實例的情況, 在服務關閉期間,我們自然不希望客戶端會繼續調用關閉了的實例。所以在客戶端程序中, 當服務實例進行正常的關閉操作時, 它會觸發一個服務下線的REST請求給Eureka Server, 告訴服務注冊中心:“我要下線了”。服務端在接收到請求之后, 將該服務狀態置為下線(DOWN), 并把該下線事件傳播出去。
三、服務注冊中心
1.失效剔除
有些時候, 我們的服務實例并不一定會正常下線, 可能由于內存溢出、網絡故障等原因使得服務不能正常工作, 而服務注冊中心并未收到“服務下線” 的請求。為了從服務列表中將這些無法提供服務的實例剔除, Eureka Server在啟動的時候會創建一個定時任務,默認每隔一段時間(默認為60秒) 將當前清單中超時(默認為90秒)沒有續約的服務剔除出去。
2.自我保護
當我們在本地調試基于Eureka的程序時, 基本上都會碰到這樣一個問題, 在服務注冊中心的信息面板中出現類似下面的紅色警告信息:
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT.RENEWALS ARE LESSER TH邸THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPI邸D JUST TO BE SAFE.
實際上, 該警告就是觸發了EurekaServer的自我保護機制。之前我們介紹過, 服務注冊到EurekaServer之后,會維護一個心跳連接,告訴EurekaServer自己還活著。EurekaServer在運行期間,會統計心跳失敗的比例在15分鐘之內是否低于85%, 如果出現低于的情況(在單機調試的時候很容易滿足, 實際在生產環境上通常是由于網絡不穩定導致), Eureka Server會將當前的實例注冊信息保護起來, 讓這些實例不會過期, 盡可能保護這些注冊信息。但是, 在這段保護期間內實例若出現問題, 那么客戶端很容易拿到實際已經不存在的服務實例, 會出現調用失敗的清況, 所以客戶端必須要有容錯機制, 比如可以使用請求重試、斷路器等機制。
由于本地調試很容易觸發注冊中心的保護機制, 這會使得注冊中心維護的服務實例不那么準確。所以, 我們在本地進行開發的時候, 可以使用eureka.server.enableself-preservation=false 參數來關閉保護機制, 以確保注冊中心可以將不可用的實例正確剔除。
Eureka常用配置
1.Eureka服務監控
添加依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
注意:服務端已經存在該依賴,可以不用添加。
# info自定義 info.build.name=@project.name@ info.build.description=@project.description@ info.build.groupId=@project.groupId@ info.build.artifact=@project.artifactId@ info.build.version=@project.version@ # 狀態頁面自定義訪問鏈接 eureka.instance.status-page-url-path=/info
注意:
1、 服務監控依賴于 spring-boot-starter-actuator 這個 jar
2、 注意 management.context-path 的定義
3、 注意 server.servlet-path 的定義
4、 可以直接定義 eureka.instance.status-page-url=http://www.roncoo.com,這個優先級高
2.Eureka客戶端的常用配置
# server server.port=8888 # spring spring.application.name=spring-cloud-consumer # eureka eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #自定義訪問路徑 eureka.instance.status-page-url-path=/info #自定義實例ID eureka.instance.instanceId=${spring.application.name}:${random.value} #顯示IP地址 eureka.instance.prefer-ip-address=true #設置拉取服務注冊信息時間,默認60s eureka.client.registry-fetch-interval-seconds=30 #指定續約更新頻率,默認是30s eureka.instance.lease-renewal-interval-in-seconds=15 #設置過期剔除時間,默認90s eureka.instance.lease-expiration-duration-in-seconds=45
3.Eureka服務端的常用配置
# server (eureka 默認端口為:8761) server.port=8761 # spring spring.application.name=spring-cloud-server # eureka # 是否注冊到eureka eureka.client.register-with-eureka=false # 是否從eureka獲取注冊信息 eureka.client.fetch-registry=false # eureka服務器的地址(注意:地址最后面的 /eureka/ 這個是固定值) eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/ # info自定義,讀取pom文件中的內容 info.build.name=@project.name@ info.build.description=@project.description@ info.build.groupId=@project.groupId@ info.build.artifact=@project.artifactId@ info.build.version=@project.version@ # 指定環境 eureka.environment=dev #指定數據中心 eureka.datacenter=roncoo # 關閉自我保護模式 eureka.server.enable-self-preservation=false #設置清理無效節點的時間間隔,默認60000,即是60s eureka.server.eviction-interval-timer-in-ms=5000
Eureka服務認證
1.指定注冊中心
在配置文件中指定注冊中心,主要通過eureka.client.serviceUrl 參數實現。該參數的定義如下所示,它的配置值存儲在HashMap 類型中,并且設置有一組默認值, 默認值的key 為defaultZone、value 為http://localhost:8761/eureka/。
private Map<String, String> serviceUrl = new HashMap<> (); this.serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL); public static丘nal String DEFAULT_URL = "http://localhost:8761" + DEFAULT_PREFIX + "/"; public static final String DEFAULT_ZONE = "defaultZone";
所以我們做了如下配置, 來將應用注冊到對應的Eureka 服務端中。
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
當構建了高可用的服務注冊中心集群時, 我們可以為參數的value 值配置多個注冊中心的地址(通過逗號分隔)。比如下面的例子:
eureka.client.serviceUrl.defaultZone=http://peerl:8761/eureka/, http://peer2:8762/eureka/
另外, 為了服務注冊中心的安全考慮, 很多時候我們都會為服務注冊中心加入安全校驗。這個時候,在配置serviceUrl 時, 需要在value 值的URL 中加入相應的安全校驗信息, 比如http://<username>:<password>@localhost:1111/eureka。其中,<username>為安全校驗信息的用戶名, <password>為該用戶的密碼。
2.服務認證
1、服務端添加依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
2、服務端添加配置
# 服務認證 security.basic.enabled=true security.user.name=qb security.user.password=123456
3、修改服務端和客戶端的配置
eureka.client.serviceUrl.defaultZone=http://qb:123456@localhost:8761/eureka/
建議:能在內網的,盡量在內網,這樣既可以保障安全,也能降低復雜度。
Eureka高可用集群配置
說明:啟動3個注冊中心,我們將cloudtest1、cloudtest2、cloudtest3 各自都將serviceUrl 指向另外兩個節點,即是 cloudtest1、cloudtest2、cloudtest3 是兩兩互相注冊的。
步驟:
1、設置 hosts:C:\Windows\System32\drivers\etc\hosts;
# Cluster hosts 127.0.0.1 cloudtest1 127.0.0.1 cloudtest2 127.0.0.1 cloudtest3
2、修改配置
每個服務都需要相應的修改,服務-01
spring.application.name=spring-cloud-server-01 eureka.instance.hostname=cloudtest1 eureka.client.serviceUrl.defaultZone=http://qb:123456@cloudtest2:8762/eureka/,http://qb:123456@cloudtest3:8763/eureka/
同理:服務-02,服務-03 都做相對應的修改
3、配置修改
#這里是為了測試,生產應該保持默認值:30s eureka.instance.lease-renewal-interval-in-seconds=5 #剔除失效服務的檢測時間,默認值:60000,即 60s eureka.server.eviction-interval-timer-in-ms=5000
聲明:"服務治理機制"這部分是截取《springcloud微服務實戰(翟永超)》,我本人覺得他講解的很到位,也很容易理解;至于常用配置、服務認證、高可用注冊是經過實踐總結的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。