服務治理
服務治理應該是微服務架構中最核心和基礎的模塊,他主要用來實現各個微服務實例的自動化註冊與發現。
服務註冊
在服務治理框架中,通常都會構建一個註冊中心,每個服務單元向註冊中心登記自己提供的服務,將主機與端口號、版本號、通信協議等一些附加信息告知註冊中心,註冊中心按服務名分類組織服務清單。服務註冊中心還需要以心跳的方式去監測清單中的服務是否可用,如果不可用就需要從服務清單中剔除,達到排除故障服務的效果。
服務發現
Netflix Eureka
簡介
SpringCloud Eureka,使用Netflix Eureka來實現服務註冊與發現,它既包含了服務端組件也包含了客戶端組件。
Eureka服務端 : 稱之爲服務註冊中心,支持高可用配置。如果Eureka以集羣的模式部署,當集羣中有分片出現故障時,那麼eureka會轉入自我保護模式,它容許分片在故障期間繼續提供服務的註冊和發現,當故障分片恢復的時候,集羣中其他分片會把他們的狀態在同步過來
Eureka客戶端 : 主要處理服務的註冊與發現。客戶端服務通過註解和參數配置的方式,
嵌入在客戶端應用程序的代碼中,在應用程序運行時,Eureka客戶端向註冊中心註冊自身
提供的服務並週期性地發送心跳來更新它的服務租約。同時,它也能從服務端查詢當前注
冊的服務信息並把它們緩存到本地並週期性地刷新服務狀態
搭建服務註冊中心
1.創建maven項目,添加pom文件
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.dyc.sprincloud</groupId> <artifactId>eureka-server-dyc</artifactId> <version>0.0.1-SNAPSHOT</version>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project> |
編寫開啓類
@EnableEurekaServer //開啓eureka服務端 @SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class); } } |
創建配置文件application.properties
server.port=1111
eureka.instance.hostname=192.3.4.102 eureka.client.register-with-eureka=false eureka.client.fetch-registery=false eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/ |
搭建高可用註冊中心
用原來的eureka-server-dyc項目
1.創建文件application-peer1.properties
2.創建文件application-peer2.properties
3.window上在host配置pee1和pee2的映射
4.用原先的hello項目,修改配置文件
5.啓動發現,通過192.3.4.102:1111,192.3.4.102:1112,可以觀察到hello服務同時被註冊到了peer1和peer2上。此時如果斷開peer1,peer2也可以正常運行去訪問peer2,從而實現服務中心的高可用
服務發現與消費
簡介
我們現在有了服務註冊中心和服務提供者,下面嘗試創建一個服務消費者,他主要實現兩個功能:發現服務和消費服務,其中發現服務Eureka的客戶端完成,消費服務的任務由Ribbon完成。Ribbon是一個基於HTTP和TCP的客戶端負載均衡器,它可以通過客戶端z紅配置的ribbonServerList服務端列表去輪詢訪問達到均衡負載的作用。
創建ribbon項目
1.創建maven項目,編寫pom文件
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.dyc.springcloud</groupId> <artifactId>ribbon-consumer</artifactId> <version>0.0.1-SNAPSHOT</version>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.7.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent>
<dependencies>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> </dependencies>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project> |
2.編寫配置文件
spring.application.name=ribbon-consumer server.port=9000 eureka.client.serviceUrl.defaultZone=http\://peer1:1111/eureka/,http\://peer2:1112/eureka/
|
3.編寫Ctrl類和啓動類
package cn.dyc.ctrl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;
@RestController public class ConsumerCtrl { @Autowired RestTemplate restTemplate;
@RequestMapping(value="/helloConsumer",method=RequestMethod.GET) public String helloConsumer(){ //這裏的url是註冊中心上服務列表的服務名 return restTemplate.getForEntity("http://hello/hello", String.class).getBody(); } }
|
package cn.dyc;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;
@EnableDiscoveryClient @SpringBootApplication public class ConsumerApplication {
@Bean @LoadBalanced RestTemplate resulTemplate(){ return new RestTemplate(); }
public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } |
流程測試
項目準備好之後,把之前準備的eureka-server-dyc和hello項目都啓動好,在啓動ribbon項目,分別測試6次。測試結果如下:
當訪問hello項目的時候log日誌如下
通過之前的實例,已經簡單的構建了Eureka服務治理體系中的三個核心角色:服務註冊中心、服務提供者以及服務消費者
基礎架構
服務註冊中心 : Eureka提供的服務端,提供服務註冊與發現的功能 eureka-server-dyc
服務提供者 : 服務提供者他將自己的服務註冊到eureka,以供其他應用發現 hello
服務消費者 : 消費者從服務註冊中心獲取服務列表,從而使消費者知道去何處調用其 所需的服務 ribbon-consumer
很多時候客戶端即是服務提供者也是服務消費者
Eureka實現服務治理體系是如何運轉起來的,其中重要幾個元素總結一下:
1.“服務註冊中心-1”和“服務註冊中心-2”他們互相註冊組成了高可用集羣
2.“服務提供者”啓動了兩個實例,一個註冊到“服務註冊中心-1”,一個註冊到 “服務註冊中心-2”
3.還有兩個“服務消費者”,分別指向服務註冊中心
配置詳解
配置地址
org.springframework.cloud.netflix.eureka.EurekaClientConfigBean 服務註冊類配置,查看該類可以獲得比官網更詳細的配置信息,這些配置都是以eureka.client爲前綴
org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean 服務端配置,這些參數均以eureka.server爲前綴
org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean 服務實例類配置信息,這些參數均以eureka.instance爲前綴
注意事項
1.服務中心有一個自我保護機制,這個機制是會統計心跳失敗的比例在15分鐘之內是否低於85%,如果低於的情況下,EurekaServer會將當前的實例註冊信息保護起來,讓這些實例不會過期,在單機調試的時候很容易有這種關閉了服務提供者但是註冊中心還有的情況,所以請關閉自我保護機制eureka.server.enable-self-preservation=false,並添加清理間隔時間爲:eureka.server.eviction-interval-timer-in-ms=9000(默認爲60*1000太長了,不利於單機測試或者開發),而在客戶端上需要設置eureka.instance.lease-renewal-interval-in-seconds=30 # 續約更新時間間隔(默認30秒)
eureka.instance.lease-expiration-duration-in-seconds=90 # 續約到期時間(默認90秒)
eureka.client.healthcheck.enabled=true,其實以上兩個配置已經可以把心跳停止的服務關掉了,但是如果你的客戶端中有比如數據庫,mq無法與我們的應用聯通時,實際上是不能提供正常服務了,但是心跳機制還在,項目不會剔除,所以在這個時候需要加入健康機制,需要在pom文件裏引入:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> |
2.獲取服務是服務消費者的基礎,所以必須確保eureka.client.fetch-registery=true,該值默認爲true
服務註冊類配置
org.springframework.cloud.netflix.eureka.EurekaClientConfigBean 查看該類可以獲得比官網更詳細的配置信息,這些配置都是以eureka.client爲前綴
簡單配置如下:
參數名 |
說明 |
默認值 |
registryFetchlntervaISeconds |
從Eureka服務端獲取註冊信息的間隔時間單位爲秒 |
30 |
instanceInfoReplicationlntervaISeconds |
更新實例信息的變化到Eureka服務端的間隔時間,單位爲秒 |
30 |
initialInstancelnfoReplicationIntervaISeconds |
初始化實例信息到Eureka服務端的間隔時間,單位爲秒 |
40 |
eurekaServiceUrIPolllntervaISeconds |
輪詢Eureka服務端地址更改的間隔時間,單位爲秒。當我們與Spring Cloud Config配合,動態刷新Eureka的serviceURL地址時需要關注該參數 |
300
|
eurekaServerReadTimeoutSeconds |
讀取Eureka Server信息的超時時間,單位爲秒 |
8 |
eurekaServerC onnectTimeoutSeconds |
連接Eureka Server的超時時間,單位爲秒 |
5 |
eurekaServerTotaIConnections |
從Eureka窖戶端到所有Eureka服務端的連接總數 |
200 |
eurekaServerTotaIConnectionsPerHost |
從Eureka客戶端到每個Eureka服務端主機的連接總數 |
50 |
eurekaConnectionIdleTimeoutSeconds |
Eureka服務端連接的空閒關閉時間,單位爲秒 |
30 |
heartbeatExecutorThreadPoolSize |
心跳連接池的初始化線程數 |
2 |
heartbeatExecutorExponentiaIBackOffBound |
心跳超時重試延遲時間的最大乘數值 |
10 |
cacheRefreshExecutorThreadPooISize |
緩存刷新線程池的初始化線程數 |
2 |
cacheRefreshExecutorExponentialBackOffBound |
緩存刷新重試延遲時間的最大乘數值 |
10 |
useDnsForFetchingServiceUrls |
使用DNS來獲取Eureka服務端的serviceUrl |
false |
registerWithEureka |
是否要將自身的實例信息註冊到Eureka服務端 |
true |
preferSameZoneEureka |
是否偏好使用處於相向Zone的Eureka服務端 |
true |
filterOnlyUplnstances |
獲取實例時是否過濾,僅保留UP狀態的實例 |
true |
fetchRegistry |
是否從Eureka服務端獲取註冊信息 |
true |
enabled |
啓用Eureka客戶端 |
true |
服務實例類配置
關於服務實例類的配置信息,我們可以通過查看org. springframework.cloud.
netflix.eureka .EurekaInstanceConfigBean的源碼來獲取詳細內容,這些配置
信息都以eureka.instance爲前綴,下面我們針對一些常用的配置信息做一些詳細的說
簡單配置如下:
參數名 |
說明 |
默認值 |
preferIpAddress |
是否優先使用lP地址作爲主機名的標識 |
false |
leaseRenewallntervallnSeconds |
Eureka客戶端向服務端發送心跳的時間間隔,單位爲秒 |
30 |
leaseExpirationDurationlnSeconds |
Eureka服務端在收到最後一次心跳之後等待的時間上限單位爲秒。超過該時間之後服務端會將該服務實例從服務清單中剔除,從而禁止服務調用請求被髮送到該實例上 |
90 |
nonSecurePort |
非安全的通信端口號 |
80 |
securePort |
安全的通信端口號 |
443 |
nonSecurePortEnabled |
是否啓用非安全的通信端口號 |
true |
securePortEnabled |
是否啓用安全的通信端口號 |
|
appname |
服務名,默認取spring.application.name的配置值如果沒有則爲unknown |
|
hostname |
主機名,不配置的時候將根據操作系統的主機名來獲取 |
|
|
|
|
在上面的這些配置中,除了前三個配置參數在需要的時候可以做一些調整,其他的參
數配置大多數情況下不需要進行配置,使用默認值即呵。