0、認識Eureka
Eureka 是 Netflix 開源的服務發現組件,后來被集成到 Spring Cloud 生態中,成為 Spring Cloud Netflix 的核心模塊之一。它主要用于解決分布式系統中??服務注冊與發現??的問題。
-
Eureka Server 有必要的話,也可以做成集群
-
Eureka 包含兩個組件∶Eureka Server 和 Eureka Client(服務提供端(Provider)??和??服務消費端(Consumer))
-
Eureka Server 提供注冊服務, 各個微服務節點通過配置啟動后,會在 Eureka Server 中進行注冊,這樣 EurekaServer 中的服務注冊表中將會存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀看到。
- EurekaClient 通過注冊中心進行訪問, 是一個 Java 客戶端,用于簡化 Eureka Server 的交互,客戶端同時也具備一個內置的、使用輪詢(round-robin) 負載算法的負載均衡器。在應 用啟動后,將會向 Eureka Server 發送心跳(默認周期為 30 秒)。如果 Eureka Server 在多個心跳周期內沒有接收到某個節點的心跳,EurekaServer 將會從服務注冊表中把這個服務節點移除(默認 90 秒)
1、如何創建Eureka
?1.建議單獨的創建一個模塊,然后配置yaml文件
server:port: 9001#配置eureka-server
eureka:instance:hostname: eureka9001.com #服務實例名client:#配置不向注冊中心注冊自己register-with-eureka: false#表示自己就是注冊中心,作用就是維護注冊服務實例, 不需要去檢索服務fetch-registry: falseservice-url:#設置與eureka server 交互模塊, 查詢服務和注冊服務都需要依賴這個地址#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/#相互注冊,這里應該注冊到eureka server9002defaultZone: http://eureka9002.com:9002/eureka/
# server:
# #禁用自我保護模式
# enable-self-preservation: false
# #設置超時時間為2秒,在2秒鐘,收不到心跳包,就認為是超時
# eviction-interval-timer-in-ms: 2000
第二步再啟動代碼中加入注解,@EnableEurekaServer 表示該程序作為 EurekaServer
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication9001 {public static void main(String[] args) {SpringApplication.run(EurekaApplication9001.class, args);}
}
當然,必不可少的pom依賴
<dependencies><!--引入eureka-server 場景啟動器starter: 使用版本仲裁--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>
</dependencies>
完成后可以訪問http://localhost:9001查看儀表盤
2、將服務提供端和服務消費端作為Eureka Client注冊到Eureka Server
老規矩引入依賴,消費端和提供端都要
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
修改Client的yaml文件和啟動類
provider:
#配置eureka-client
eureka:client:register-with-eureka: true #將自己注冊到Eureka-Server#表示從Eureka-Server 抓取注冊信息#如果是單節點,是可以不配置的,但是如果是一個集群,則必須配置true,#才能配合Ribbon使用負載均衡fetch-registry: trueservice-url:#表示將自己注冊到哪個eureka-server#將本微服務注冊到多個eureka-server ,使用逗號間隔即可defaultZone: http://eureka9001.com:9001/eureka,http://eureka9002.com:9002/eureka
# instance:
# #客戶端向服務端發送心跳的時間間隔 1s(默認是30)
# lease-renewal-interval-in-seconds: 1
# #服務端收到最后一次心跳后等待的時間上限
# #時間單位(秒),默認是90s, 超時將剔除服務
# lease-expiration-duration-in-seconds: 2
?@EnableEurekaClient 將程序標識為eureka client
@EnableEurekaClient
@SpringBootApplication
public class MemberApplication10000 {public static void main(String[] args) {SpringApplication.run(MemberApplication10000.class, args);}
}
consume:
#配置eureka-client
eureka:client:register-with-eureka: true #將自己注冊到Eureka-Serverfetch-registry: trueservice-url:#表示將自己注冊到哪個eureka-server#這里我們將本微服務注冊到EurekaServer 集群,使用逗號間隔#defaultZone: http://localhost:9001/eurekadefaultZone: http://eureka9001.com:9001/eureka,http://eureka9002.com:9002/eureka
@EnableEurekaClient 將程序標識為eureka client
@EnableEurekaClient
@SpringBootApplication
public class MemberConsumerApplication {public static void main(String[] args) {SpringApplication.run(MemberConsumerApplication.class,args);}
}
啟動之后可以訪問http://localhost:9001查看,昵稱是yaml文件中的昵稱?
3.Service Consumer 、Service Provider 、EurekaServer 的維護機制
三者的協同流程??
- ??服務注冊??:
Provider(MEMBER-SERVICE:10000
)啟動 → 向 Eureka Server(9001
)注冊 - ??服務發現??:
Consumer(80
端口應用)需要調用服務時 → 從 Server 獲取 Provider 地址 - ??服務調用??:
Consumer 通過 HTTP Client(如RestTemplate/Feign)訪問 Provider - ??狀態維護??:
- Provider 持續發送心跳
- Server 定時清理失效實例
- Consumer 定期更新服務列表
Eureka Server(注冊中心)??
- ??核心職責??
- 維護所有服務的注冊信息(
服務名 → 調用地址
的映射) - 提供服務的注冊、發現、續約和剔除功能
- 維護所有服務的注冊信息(
- ??關鍵機制??
- ??服務注冊表??:存儲服務提供者的元數據(IP、端口、健康狀態等)
- ??心跳機制??:通過 Provider 的定期心跳(默認30秒)判斷服務存活,超時(默認90秒)自動剔除失效實例
- ??自我保護模式??:當超過85%實例心跳丟失時,暫停剔除操作,防止網絡分區導致誤刪
- ?定期清理任務??:默認每60秒檢查并清理過期實例
Service Provider(服務提供方)??
- ??核心職責??
- 向 Eureka Server 注冊自身服務信息
- 維持服務的可用狀態
- ??關鍵機制??
- ??啟動注冊??:啟動時提交注冊請求(包含服務名、IP、端口等),詳情參考yaml文件
?Service Consumer(服務消費方)??
- ??核心職責??
- 從 Eureka Server 獲取服務提供者地址
- 發起遠程調用(如HTTP/RPC)
- ??關鍵機制??
- ??服務發現??:
- 通過服務別名在?Eureka Server 查詢獲取真實調用地址,獲取實際的RPC(Remote Procedure Call? 遠程過程調用)遠程地址,實際上是HttpClient技術實現(通過
RestTemplate
實現的“RPC”本質是??HTTP REST調用??,底層依賴HTTPClient) - 默認每30秒更新一次遠程調用地址,提高分布式系統可用性
- 通過服務別名在?Eureka Server 查詢獲取真實調用地址,獲取實際的RPC(Remote Procedure Call? 遠程過程調用)遠程地址,實際上是HttpClient技術實現(通過
- ??本地緩存??:將服務地址緩存到JVM內存,避免每次調用都訪問 Server,直接去訪問provider端
- ??負載均衡??:結合Ribbon等組件從多個Provider實例中選擇一個(如輪詢、權重)
- ??故障恢復??:調用失敗時自動重試或切換其他實例
- ??服務發現??:
?4.自我保護模式
- 默認情況下EurekaClient定時向EurekaServer端發送心跳包
- 如果Eureka在server端在一定時間內(默認90秒)沒有收到EurekaClient發送心跳包,便會直接從服務注冊列表中剔除該服務
- 如果Eureka 開啟了自我保護模式/機制, 那么在短時間(90秒中)內丟失了大量的服務實例心跳,這時候EurekaServer會開啟自我保護機制,不會剔除該服務(該現象可能出現在如果網絡不通或者阻塞) 因為客戶端還能正常發送心跳,只是網絡延遲問題,而保護機制是為了解決此問題而產生的
- 自我保護是 屬于 CAP 里面的 AP 分支, 保證高可用和分區容錯性
- 自我保護模式是—種應對網絡異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留)也不盲目注銷任何健康的微服務(容忍你一段時間不心跳) 。 使 用 自 我 保 護 模 式 , 可 以 讓 Eureka 集 群 更 加 的 健 壯 、 穩 定 。 參 考 :https://blog.csdn.net/wangliangluang/article/details/120626014
在Eureka Server的yaml文件中添加
server:#禁用自我保護模式enable-self-preservation: false #默認是true#設置超時時間為2秒,在2秒鐘,收不到心跳包,就認為是超時eviction-interval-timer-in-ms: 2000
provider:
eureka:instance:#客戶端向服務端發送心跳的時間間隔 1s(默認是30)lease-renewal-interval-in-seconds: 1#服務端收到最后一次心跳后等待的時間上限#時間單位(秒),默認是90s, 超時將剔除服務lease-expiration-duration-in-seconds: 3
解釋一下:設置這個eviction-interval-timer-in-ms: 2000和設置lease-expiration-duration-in-seconds: 3 的意思就是等待3秒,如果3秒沒有發送心跳就標記為超時,與此同時,Eureka server端每隔兩秒就在刪除超時的服務?
出現紅字,代表自我保護機制已經出現了?