SpringCloud——Eureka服務註冊和發現

1、SpringCloud和Dubbo

SpringCloud整合了一套較爲完整的微服務解決方案框架,而Dubbo只是解決了微服務的幾個方面的問題。java

content Dubbo SpringCloud
服務註冊中心 zookeeper Spring Cloud Netflix Eureka
服務調用方式 RPC REST API
服務網關 Spring Cloud Netflix Zuul
斷路器 不完善 Spring Cloud Netflix Hystrix
分佈式配置 Spring Cloud Config
服務跟蹤 Spring Cloud Sleuth
消息總線 Spring Cloud Bus
數據流 Spring Cloud Stream
批量任務 Spring Cloud Task

固然,雖然dubbo沒有提供不少解決方案,但他也能夠整合第三方的項目來實現。git

2、Demo

今天介紹的服務發現是在SpringCloud的子項目Netflix中,除此以外,他還提供了熔斷器、負載均衡、智能路由等,以後會介紹到。github

和往常同樣,咱們先來實現這個實例,而後再分析。這裏,咱們須要一個服務註冊中心(即下面例子中的eureka-server)和一個服務的提供方(eureka-provider)。web

一、服務註冊中心

1)、引入pom文件

<!--基於Springboot--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> <relativePath/> </parent> <properties> <!--設置字符編碼及java版本--> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--增長eureka-server的依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <!--用於測試的,本例可省略--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <!--依賴管理,用於管理spring-cloud的依賴,其中Camden.SR3是版本號--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

2)、配置

新建application.properties,注意名稱只能是這個,否則不會被識別。spring

server.port=8761 #註冊中心默認端口就是8761,也可經過下面的方式定義其餘端口 #eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/ eureka.client.registerWithEureka=false eureka.client.fetchRegistry=false

 

  在application.properties配置文件中使用以下配置:bootstrap

  server.port=8761瀏覽器

  eureka.instance.hostname=localhost緩存

  eureka.client.registerWithEureka=false服務器

  eureka.client.fetchRegistry=false網絡

  eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

  其中server.port配置eureka服務器端口號。Eureka的配置屬性都在開源項目spring-cloud-netflix-master中定義(spring boot連文檔都沒有,只能看源碼了),

       在這個項目中有兩個類EurekaInstanceConfigBean 和EurekaClientConfigBean,分別含有eureka.instance和eureka.client相關屬性的解釋和定義。

       從中能夠看到,registerWithEureka表示是否註冊自身到eureka服務器,由於當前這個應用就是eureka服務器,不必註冊自身,因此這裏是false。

       fetchRegistry表示是否從eureka服務器獲取註冊信息,同上,這裏不須要。defaultZone就比較重要了,是設置eureka服務器所在的地址,查詢服務和註冊服務都須要依賴這個地址。

3)、啓動類

@EnableEurekaServer //啓動一個服務註冊中心提供給其餘應用進行對話 @SpringBootApplication public class ServerApplication { public static void main(String[] args) { //下面兩行代碼均可以用來啓動 SpringApplication.run(ServerApplication.class, args); //new SpringApplicationBuilder(Application.class).web(true).run(args); } }

 

4)、測試

在瀏覽器中輸入http://localhost:8761 就會顯示: 
這裏寫圖片描述

二、服務提供者

1)、pom文件跟註冊中心相似,只有eureka有區別:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>

 

 

2)、配置文件

#應用(服務)名稱 spring.application.name=compute-service server.port=8762 #註冊中心地址 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 

 

3)、Java Code

Controller中,經過DiscoveryClient發現服務。 
啓動類

@EnableDiscoveryClient //激活eureka中的DiscoveryClient實現 @SpringBootApplication public class ComputeServiceApplication { public static void main(String[] args) { new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args); } }

 

 

4)、測試

這裏寫圖片描述

在瀏覽器中輸入http://localhost:8762/hello?name=Sherryhttp://yfywyangsx.hiersun.com:hello-service:8762/hello?name=Sherry

這裏寫圖片描述 ##

 

Spring Cloud中,Eureka常見問題總結。

指定Eureka的Environment

 
    
1
 
    
eureka.environment: 指定環境

參考文檔:https://github.com/Netflix/eureka/wiki/Configuring-Eureka

指定Eureka的DataCenter

 
    
1
 
    
eureka.datacenter: 指定數據中心

參考文檔:https://github.com/Netflix/eureka/wiki/Configuring-Eureka
文中指出,配置-Deureka.datacenter=cloud,這樣eureka將會知道是在AWS雲上。

如何解決Eureka註冊服務慢的問題

使用配置項:

 
    
1
 
    
eureka.instance.leaseRenewalIntervalInSeconds

參考文檔:
http://cloud.spring.io/spring-cloud-static/Camden.SR1/#_why_is_it_so_slow_to_register_a_service
原文:

 
    
1
2
3
 
    
Why is it so Slow to Register a Service?
 
Being an instance also involves a periodic heartbeat to the registry (via the client’s serviceUrl) with default duration 30 seconds. A service is not available for discovery by clients until the instance, the server and the client all have the same metadata in their local cache (so it could take 3 heartbeats). You can change the period using eureka.instance.leaseRenewalIntervalInSeconds and this will speed up the process of getting clients connected to other services. In production it’s probably better to stick with the default because there are some computations internally in the server that make assumptions about the lease renewal period.

翻譯:

 
    
1
 
    
做爲實例還涉及到與註冊中心的週期性心跳,默認持續時間爲30秒(經過serviceUrl)。在實例、服務器、客戶端都在本地緩存中具備相同的元數據以前,服務不可用於客戶端發現(因此可能須要3次心跳)。你可使用eureka.instance.leaseRenewalIntervalInSeconds 配置,這將加快客戶端鏈接到其餘服務的過程。在生產中,最好堅持使用默認值,由於在服務器內部有一些計算,他們對續約作出假設。

Eureka的自我保護模式

若是在Eureka Server的首頁看到如下這段提示,則說明Eureka已經進入了保護模式。

 
    
1
 
    
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.

保護模式主要用於一組客戶端和Eureka Server之間存在網絡分區場景下的保護。一旦進入保護模式,Eureka Server將會嘗試保護其服務註冊表中的信息,再也不刪除服務註冊表中的數據(也就是不會註銷任何微服務)。

詳見:https://github.com/Netflix/eureka/wiki/Understanding-Eureka-Peer-to-Peer-Communication

如何解決Eureka Server不踢出已關停的節點的問題

在開發過程當中,咱們經常但願Eureka Server可以迅速有效地踢出已關停的節點,可是新手因爲Eureka自我保護模式,以及心跳週期長的緣由,經常會遇到Eureka Server不踢出已關停的節點的問題。解決方法以下:

(1) Eureka Server端:配置關閉自我保護,並按需配置Eureka Server清理無效節點的時間間隔。

 
    
1
2
 
    
eureka.server.enable-self-preservation # 設爲false,關閉自我保護
eureka.server.eviction-interval-timer-in-ms # 清理間隔(單位毫秒,默認是60*1000)

(2) Eureka Client端:配置開啓健康檢查,並按需配置續約更新時間和到期時間。

 
    
1
2
3
 
    
eureka.client.healthcheck.enabled # 開啓健康檢查(須要spring-boot-starter-actuator依賴)
eureka.instance.lease-renewal-interval-in-seconds # 續約更新時間間隔(默認30秒)
eureka.instance.lease-expiration-duration-in-seconds # 續約到期時間(默認90秒)

示例:
服務器端配置:

 
    
1
2
3
4
 
    
eureka:
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 4000

客戶端配置:

 
    
1
2
3
4
5
6
7
 
    
eureka:
client:
healthcheck:
enabled: true
instance:
lease-expiration-duration-in-seconds: 30
lease-renewal-interval-in-seconds: 10

注意:
更改Eureka更新頻率將打破服務器的自我保護功能,生產環境下不建議自定義這些配置。
詳見:https://github.com/spring-cloud/spring-cloud-netflix/issues/373

自定義Eureka的Instance ID

在Spring Cloud中,服務的Instance ID的默認值是${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} ,也就是機器主機名:應用名稱:應用端口 。所以在Eureka Server首頁中看到的服務的信息相似以下:itmuch:microservice-provider-user:8000 。若是想要自定義這部分的信息怎麼辦?

示例:

  1.  
    eureka:
  2.  
    client:
  3.  
    serviceUrl:
  4.  
    defaultZone: http: //localhost:8761/eureka/
  5.  
    instance:
  6.  
    preferIpAddress: true
  7.  
    instance- id: ${spring.cloud.client.ipAddress}:${server.port} # 將Instance ID設置成IP:端口的形式

Eureka配置最佳實踐參考

https://github.com/spring-cloud/spring-cloud-netflix/issues/203

注意點:eureka.client.healthcheck.enabled=true配置項必須設置在application.yml中

eureka.client.healthcheck.enabled=true 只應該在application.yml中設置。若是設置在bootstrap.yml中將會致使一些不良的反作用,例如在Eureka中註冊的應用名稱是UNKNOWN等。

相關文章
相關標籤/搜索