SpringCloud學習之Eureka
標簽: SpringCloud
文章目錄
Eureka
什么是Eureka
Eureka 是一個基于 REST(Representational State Transfer)的服務,主要用于 AWS cloud, 提供服務定位(locating services)、負載均衡(load balancing)、故障轉移(failover of middle-tier servers)。是 Netflix 開源的服務發現組件,包括 Server 和 Client 兩部分.在 Spring Cloud 子項目 Spring Cloud Netflix 中。
Eureka Server 和 Eureka Client:
- Eureka Server : 提供服務發現的能力,各服務啟動時,會向 Eureka Server 注冊自己的信息(IP,端口,服務信息等),Eureka Server 會存儲這些信息.
- Eureka Client : 服務提供者,簡化與Eureka Server的交互.
Eureka能做什么
微服務的注冊與發現,功能類似于 Zookeeper。
原理講解
-
Eureka 采用了 C-S 的架構設計,Eureka Server 作為服務注冊功能的服務器,提供服務發現的能力。
-
微服務啟動后,會周期性(默認30秒)的向 Eureka Server 發送心跳以續約自己的”租期”。
-
如果 Eureka Server 在一定時間內沒有收到某個微服務實例(Eureka Client)的心跳,Eureka Server 將會注銷該實例(默認90秒)。
-
默認請求下,Eureka Server 同時也是 Eureka Client。多個 Eureka Server 實例,互相之間通過復制的方式,來實現服務注冊表中的數據.(實現集群,高可用)
-
Eureka Client 會緩存注冊表中的信息.這種方式有一定的優勢。首先,微服務無需每次請求都查詢Eureka Server,從而降低了 Eureka Server 的壓力;其次,即使 Eureka Server 所有節點都宕掉,服務消費者依然可以使用緩存中的信息找到服務提供者并完成調用。這樣,Eureka通過心跳檢測,客戶端緩存等機制,提高了系統的靈活性,可伸縮性和可用性。
畫一張簡單的功能圖來展示其作用:
可以發現同 Zookeeper 功能很相似。
Eureka Server示例
1、創建一個名為 springcloud-config-eureka-7001 的普通 maven 項目
2、導入相關依賴
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<!--熱部署工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
3、resources
中添加application.yml
server:
port: 7001
#Eureka配置
eureka:
instance:
hostname: localhost #Eureka服務端的實例名稱
client:
register-with-eureka: false #表示是否向注冊中心注冊自己
fetch-registry: false #為false表示自己是注冊中心
service-url: #監控頁面
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4、編寫入口類
@EnableEurekaServer //啟動服務發現,接受注冊
@SpringBootApplication
public class EurekaServer_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7001.class, args);
}
}
5、啟動項目,訪問 http://localhost:7001/ ,頁面顯示如下:
Eureka Client示例
基于我們之前創建的 Rest 服務提供者 springcloud-provider-dept-8001 進行修改。
1、導入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2、在入口類上增加 @EnableEurekaClient
注解
@SpringBootApplication
@EnableEurekaClient
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class,args);
}
}
3、application.yml
文件中增加 Eureka 配置
#Eureka配置
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-provider-dept-8001 # 修改eureka上的默認描述信息
prefer-ip-address: true # true,可以顯示服務的IP地址
4、啟動項目,訪問 http://localhost:7001/ ,頁面結果如下:
當我們點擊 Status 標簽下的鏈接時,頁面會進行跳轉,結果如下所示:
那么我們考慮如何讓它正常顯示內容。
actuator完善監控信息
1、首先導入依賴
<!--actuator完善監控信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、application.yml
文件中增加 info 配置
#info配置
info:
app.name: hresh-springcloud
company.name: blog.csdn.net/Herishwater
3、稍等片刻,再次點擊上述鏈接,內容展示如下:
服務發現Discovery
在團隊多服務構建過程中,如果別人想獲取你所構建的微服務信息,可以通過注入 org.springframework.cloud.client.discovery.DiscoveryClient
,獲取到微服務清單,然后選擇想要的服務ID,遍歷打印具體信息。
在 DeptController 增加實現方法。
//獲取一些配置的信息,得到具體的微服務
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("/dept/discovery")
public Object getService(){
List<String> services = discoveryClient.getServices();
System.out.println("discovery=>services:"+services);
List<ServiceInstance> instances = discoveryClient.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
for (ServiceInstance instance : instances) {
System.out.println(
instance.getHost()+"\t"+
instance.getPort()+"\t"+
instance.getUri()+"\t"+
instance.getServiceId()
);
}
return discoveryClient;
}
前臺訪問 http://localhost:8001/dept/discovery ,頁面展示結果如下:
{"discoveryClients":[{"services":["springcloud-provider-dept"],"order":0},{"services":[],"order":0}],"services":["springcloud-provider-dept"],"order":0}
集群
在上文中我們新建了一個名為 springcloud-config-eureka-7001 的普通 maven 項目,參考該項目,再新建兩個僅名字不同的項目,內容基本一致,對 application.yml
稍作修改:
springcloud-config-eureka-7001
server:
port: 7001
#Eureka配置
eureka:
instance:
hostname: eureka7001 #Eureka服務端的實例名稱
client:
register-with-eureka: false #表示是否向注冊中心注冊自己
fetch-registry: false #為false表示自己是注冊中心
service-url: #監控頁面
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#集群(關聯)
defaultZone: http://eureka7002:7002/euraka/,http://eureka7003:7003/euraka/
springcloud-config-eureka-7002
server:
port: 7002
#Eureka配置
eureka:
instance:
hostname: eureka7002 #Eureka服務端的實例名稱
client:
register-with-eureka: false #表示是否向注冊中心注冊自己
fetch-registry: false #為false表示自己是注冊中心
service-url: #監控頁面
defaultZone: http://eureka7001:7001/euraka/,http://eureka7003:7003/euraka/
springcloud-config-eureka-7003
server:
port: 7003
#Eureka配置
eureka:
instance:
hostname: eureka7003 #Eureka服務端的實例名稱
client:
register-with-eureka: false #表示是否向注冊中心注冊自己
fetch-registry: false #為false表示自己是注冊中心
service-url: #監控頁面
defaultZone: http://eureka7002:7002/euraka/,http://eureka7001:7001/euraka/
因為我們本地端口默認為 localhost,實際上指向的是 127.0.0.1,為了更好地理解集群的思想,我們將修改 C:\Windows\System32\drivers\etc 下的 host 文件,內容如下:
127.0.0.1 eureka7001
127.0.0.1 eureka7002
127.0.0.1 eureka7003
注意:上述內容必須進行修改,否則沿用 localhost,無法得到正確的結果。
依次啟動這3個項目,訪問 http://eureka7001:7001/ ,頁面展示結果為:
接著修改 springcloud-provider-dept-8001 的配置文件如下:
#Eureka配置
eureka:
client:
service-url:
defaultZone: http://eureka7001:7001/eureka/,http://eureka7002:7002/eureka/,http://eureka7003:7003/eureka/
instance:
instance-id: springcloud-provider-dept-8001 # 修改eureka上的默認描述信息
prefer-ip-address: true # true,可以顯示服務的IP地址
啟動服務提供項目 springcloud-provider-dept-8001,再次訪問 http://eureka7001:7001/,頁面展示結果為:
依次再訪問 http://eureka7002:7002/ 和 http://eureka7003:7003/ 時,是看不到服務的注冊,雖然這3個注冊中心構成了一個集群,但是只有當一個垮了之后,才會去訪問下一個集群節點。 Eureka Client 在發送注冊請求時,會按照 Eureka Server 集群節點 serviceUrlList 順序逐個去嘗試,如果有一個請求成功了,那么直接返回response ,不再去向其他節點請求。
在本例中服務注冊請求在 eureka7001 中注冊成功,即 eureka7001 對應的 Eureka Server服務的狀態是UP,則不會向另外兩個節點(eureka7002,eureka7003)發送請求,相應地頁面上也就沒有顯示。一旦停止 eureka7001 服務注冊中心,則 dept-8001 服務會向 eureka7002 發送注冊請求。
關于此處的結果本人疑惑了很久,在網上一直沒有找到合適的答案,最后在 Eureka高可用之Client重試機制:RetryableEurekaHttpClient 一文中解開了自己的疑惑。
問題記錄
當集群中服務注冊中心正常使用時,控制臺會打印出以下內容:
2020-04-29 22:51:06.468 ERROR 14732 --- [t_eureka7003-16] c.n.e.cluster.ReplicationTaskProcessor : Batch update failure with HTTP status code 404; discarding 1 replication tasks
2020-04-29 22:51:06.468 ERROR 14732 --- [et_eureka7002-3] c.n.e.cluster.ReplicationTaskProcessor : Batch update failure with HTTP status code 404; discarding 1 replication tasks
2020-04-29 22:51:06.469 WARN 14732 --- [t_eureka7003-16] c.n.eureka.util.batcher.TaskExecutors : Discarding 1 tasks of TaskBatchingWorker-target_eureka7003-16 due to permanent error
2020-04-29 22:51:06.469 WARN 14732 --- [et_eureka7002-3] c.n.eureka.util.batcher.TaskExecutors : Discarding 1 tasks of TaskBatchingWorker-target_eureka7002-3 due to permanent error
2020-04-29 22:51:23.489 INFO 14732 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 0ms
在網上一番查詢之后無果,如果有大神知道此處如何解決,望不吝賜教。
安全驗證
在 springcloud-config-eureka-7001 項目中,我們訪問 http://eureka7001:7001/,該注冊中心的面板是公開訪問的。這里可以簡單加入用戶名密碼,讓訪問更安全。
1、添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2、配置 application.yml
server:
port: 7001
#Eureka配置
eureka:
instance:
hostname: eureka7001 #Eureka服務端的實例名稱
prefer-ip-address: true
client:
register-with-eureka: false #表示是否向注冊中心注冊自己
fetch-registry: false #為false表示自己是注冊中心
service-url: #監控頁面
#單機
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/
#集群(關聯)
# defaultZone: http://eureka7002:7002/euraka/,http://eureka7003:7003/euraka/
spring:
application:
name: eureka-server
security:
user:
name: admin
password: admin
3、啟動該項目,再次訪問 http://eureka7001:7001/,效果如下:
擴展
CAP原則
CAP 原則又稱CAP定理,指的是在一個分布式系統中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可得兼。
CAP原則是NOSQL數據庫的基石。
分布式系統的CAP理論:理論首先把分布式系統中的三個特性進行了如下歸納:
- 一致性(C):在分布式系統中的所有數據備份,在同一時刻是否同樣的值。(等同于所有節點訪問同一份最新的數據副本)
- 可用性(A):在集群中一部分節點故障后,集群整體是否還能響應客戶端的讀寫請求。(對數據更新具備高可用性)
- 分區容忍性(P):以實際效果而言,分區相當于對通信的時限要求。系統如果不能在時限內達成數據一致性,就意味著發生了分區的情況,必須就當前操作在C和A之間做出選擇。
著名的CAP理論指出,一個分布式系統不可能同時滿足C(一致性)、A(可用性)和P(分區容錯性)。由于分區容錯性在是分布式系統中必須要保證的,因此我們只能在A和C之間進行權衡。在此Zookeeper保證的是CP, 而Eureka則是AP。
Zookeeper保證CP
? 當向注冊中心查詢服務列表時,我們可以容忍注冊中心返回的是幾分鐘以前的注冊信息,但不能接受服務直接down掉不可用。也就是說,服務注冊功能對可用性的要求要高于一致性。但是zk會出現這樣一種情況,當master節點因為網絡故障與其他節點失去聯系時,剩余節點會重新進行leader選舉。問題在于,選舉leader的時間太長,30 ~ 120s, 且選舉期間整個zk集群都是不可用的,這就導致在選舉期間注冊服務癱瘓。在云部署的環境下,因網絡問題使得zk集群失去master節點是較大概率會發生的事,雖然服務能夠最終恢復,但是漫長的選舉時間導致的注冊長期不可用是不能容忍的。
Eureka保證AP
? Eureka看明白了這一點,因此在設計時就優先保證可用性。Eureka各個節點都是平等的,幾個節點掛掉不會影響正常節點的工作,剩余的節點依然可以提供注冊和查詢服務。而Eureka的客戶端在向某個Eureka注冊或時如果發現連接失敗,則會自動切換至其它節點,只要有一臺Eureka還在,就能保證注冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。除此之外,Eureka還有一種自我保護機制,如果在15分鐘內超過85%的節點都沒有正常的心跳,那么Eureka就認為客戶端與注冊中心出現了網絡故障,此時會出現以下幾種情況:
- Eureka不再從注冊列表中移除因為長時間沒收到心跳而應該過期的服務
- Eureka仍然能夠接受新服務的注冊和查詢請求,但是不會被同步到其它節點上(即保證當前節點依然可用)
- 當網絡穩定時,當前實例新的注冊信息會被同步到其它節點中
因此, Eureka可以很好的應對因網絡故障導致部分節點失去聯系的情況,而不會像zookeeper那樣使整個注冊服務癱瘓。
詳情代碼訪問: https://github.com/Acorn2/springcloud-eureka ,如有疑惑可聯系我。
參考文獻
Eureka高可用之Client重試機制:RetryableEurekaHttpClient
spring cloud eureka注冊原理-注冊失敗填坑
智能推薦
SpringCloud之eureka集群
springcloud 1、Eureka集群搭建 普通操作 騷操作 2、Eureka自我保護機制 1、Eureka集群搭建 高可用集群配置 當注冊中心扛不住高并發的時候,這時候 要用集群來扛; 普通操作 我們再新建兩個module microservice-eureka-server-2002 microservice-eureka-server-2003 1、加pom.xml依賴 2、2002 ...
springCloud之Eureka
Eureka是什么? 服務注冊和發現。 只要所有的服務注冊進Eureka中,大家可以直接去Eureka中找到服務名稱(標識符),可以直接進行服務調用,不像dubbo還得修改配置文件。 類似dubbo的注冊中心,比如zookeeper。 Eureka服務注冊中心建立 搭建項目eureka_service application.yml 現在只是部署一臺服務,使用單機模式 啟動項配置@E...
SpringCloud之Eureka
1. eureka是什么 2.創建eureka注冊中心 3.創建eureka客戶端并注冊到注冊中心 4.給eureka注冊中心添加監聽器 5.關于eureka客戶端心跳和自我保護機制 6.給eureka添加安全機制 7.eureka的高可用 準備兩個yml文件 application-8761.yml: application-8762.yml: 克隆兩個相同的服務,分別指向不同的配置) 啟動兩個...
springcloud之eureka集群
前言: 我們通過springcloud入門大概的了解了springcloud。在springcloud入門中的案例中我們是直接通過服務消費者向服務提供者發送請求,然后得到結果的,但真正的項目開發中并不是這樣的,如圖所示,而是服務消費者向eureka發送請求,然后eureka再向服務提供者發送請求找尋到相對應的節點,服務提供者的節點有多個,其中一個宕機了eureka會自動幫你找到第二的,這里采用的是...
springcloud之eureka搭建
注冊中心在于整個springcloud系統架構中,扮演著十分重要的角色,負責著服務發現,心跳檢測,服務調度等功能,且注冊中心的高可用意味著整個系統的高可用。 鑒于springcloud包含眾多組件,所以在idea創建項目,推薦使用子模塊的形式來建立各個項目組件。 1.創建項目 創建一個springboot項目,添加必要的依賴。 2.添加子模塊 在項目基礎上添加子模塊eureka-server 3....
猜你喜歡
springCloud系列之--Eureka
什么是eureka 服務注冊中心, 服務治理的一個框架組件,用來實現各個服務實例的自動化注冊和發現 服務注冊 在服務治理框架中,通常都會構建一個注冊中心,每個服務單元向注冊中心登記自己提供的服務,包括服務的主機與端口號、服務版本號、通訊協議等一些附加信息。注冊中心按照服務名分類組織服務清單,同時還需要以心跳檢測的方式去監測清單中的服務是否可用,若不可用需要從服務清單中剔除,以達到排除故障服務的效果...
springcloud之Eureka集群
springcloud之Eureka集群 1、Eureka集群搭建 普通操作 騷操作 2、Eureka自我保護機制 1、Eureka集群搭建 高可用集群配置 當注冊中心扛不住高并發的時候,這時候 要用集群來扛; 普通操作 新建兩個module microservice-eureka-server-2002 microservice-eureka-server-2003 1、pom.xml 依賴如下...
springcloud之eureka集群
文章目錄 一、eureka集群搭建 二、eureka自我保護機制 一、eureka集群搭建 高可用集群配置 當注冊中心扛不住高并發的時候,這時候要用集群來抗 普通操作 新建兩個module并且更改其中的配置 1.1、microservice-eureka-server-2002 1.2、microservice-eureka-server-2003 在兩個module中的啟動類都加上注解(@Ena...
SpringCloud之Eureka,Ribbon
服務架構 微服務 "微服務”一詞源于 Martin Fowler的名為 Microservices 的博文,可以在他的官方博客上找到[(http://martinfowler.com/articles/microservices.html)] 微服務是系統架構上的一種設計風格,它的主旨是將一個原本獨立的系統拆分成多個小型服務,這些小型服務都在各自獨立的進程中運行,服務之間一般...