springCloud 之 Eureka服務治理機制及代碼運行
阿新 • • 發佈:2018-10-06
一個 body dem lan 找不到 ima 行修改 單實例 boot.s
獲取服務:
將自身註冊為服務消費客戶端。當我們啟動服務消費者的時候,他會發送一個REST請求給服務註冊中心,來獲取上面註冊的服務清單。為了性能考慮,Eureka Server會維護一份只讀的服務清單來返回給客戶端,同時該緩存清單會每隔30s更新一次,
獲取服務時服務消費者的基礎,必須確保eureka.client.fetch-registry=true參數沒有被修改為false,該值默認為true。若希望修改緩存清單的更新時間,可以通過eureka.client.registry-fetch-interval-seconds=30參數進行修改。
獲取服務:
發送REST請求給服務註冊中心,服務註冊中心會返回給服務消費者一個只讀的服務清單。該緩存清單默認是30秒更新一次。
eureka.client.registry-fetch-interval-seconds= 30 這個參數用來修改緩存清單更新的時間間隔,時間單位為秒。
服務調用:
服務消費者在獲取服務清單後,通過服務名可以獲得具體提供服務的實例名和該實例的元數據信息,服務消費者可以根據需要調用哪個實例。在Ribbon中默認采用輪詢的方式進行調用,從而實現客戶端的負載均衡。
服務註冊中心
失效剔除:
當某個服務提供者出現網絡故障、內存溢出等各種原因而不能正常工作,服務中心並未受到”服務下線“的請求。為了能及時將這些無法提供服務的實例剔除,Eureka Server在啟動的時候會創建一個定時任務,默認是60秒一次,將沒有續約也就是沒有發送”心跳“的服務剔除出去。
自我保護:
我們在本地調試Eureka程序的時候,基本上都會碰到一個紅色的警告信息:
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啟動了自我保護機制,自我保護機制的工作機制是如果在15分鐘內超過85%的客戶端節點都沒有正常的心跳,那麽Eureka就認為客戶端與註冊中心出現了網絡故障,Eureka Server自動進入自我保護機制,在開發環境因為不會有網絡故障等原因,所以很容易出現這個警告。啟動自我保護後此時會出現以下幾種情況:
1、Eureka Server不再從註冊列表中移除因為長時間沒收到心跳而應該過期的服務。
2、Eureka Server仍然能夠接受新服務的註冊和查詢請求,但是不會被同步到其它節點上,保證當前節點依然可用。
3、當網絡穩定時,當前Eureka Server新的註冊信息會被同步到其它節點中。
因此Eureka Server可以很好的應對因網絡故障導致部分節點失聯的情況,而不會像Zookeeper那樣如果有一半不可用的情況會導致整個集群不可用而變成癱瘓。
eureka.server.enable-self-preservation= false 可以通過這個配置設置為false來關閉自我保護機制,默認識開啟的,且建議在生產環境開啟自我保護
一、高可用註冊中心代碼
註冊中心1:
pom.xml
服務提供者 服務註冊: 服務提供者在啟動的時候通過發送Rest請求的方式將自己註冊到Eureka Server上,同時帶上了自身服務的一些元數據信息。Eureka Server在收到這個請求後,將元數據信息存儲在一個雙層結構Map中,第一層的key是服務名,第二層的key是具體服務的實例名。 服務同步: 兩個服務提供者分別註冊到兩個不同的服務註冊中心上,因為服務中心之間是相互註冊為服務的,所以當服務提供者發送註冊請求到一個服務註冊中心時,它會將該請求轉發給集群中的其他註冊中心,從而實現服務註冊中心之間的服務同步,通過服務同步,兩個服務提供者的服務信息就可以通過這兩臺服務註冊中心的任意一臺獲取到。 服務續約: 服務提供者在註冊完後,會定期向註冊中心發送一個“心跳"來告訴Eureka Server自己還存活著,以防被Eureka Servertichu踢出服務列表。 eureka.instance.lease-renewal-interval-in-seconds= 30 這個參數是定義服務續約的調用間隔時間,默認為30秒。 eureka.instance.lease-expiration-duration-in-seconds= 90 這個參數是定義服務失效時間,默認為90秒。 服務消費者
<?xml version="1.0" encoding="UTF-8"?> <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>com.zxy</groupId> <artifactId>eureka-service-center1</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>eureka-service</name> <description>Forward project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>View Code
配置文件
1 #定義註冊中心端口號為8888 2 server: 3 port: 8888 4 spring: 5 application: 6 name: server-center1 7 eureka: 8 instance: 9 hostname: center1 10 client: 11 service-url: 12 defaultZone: http://127.0.0.1:9999/eureka/ 13 # 註冊中心沒必要將自己註冊給自己 14 register-with-eureka: false 15 # 註冊中心不需要去檢索服務,調用服務,故而不需要獲取註冊服務清單 16 fetch-registry: false 17 server: 18 peer-node-read-timeout-ms: 12000 19 enable-self-preservation: false
啟動
1 package com.zxy.forward; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 @EnableEurekaServer 7 @SpringBootApplication 8 public class Center1Application { 9 10 public static void main(String[] args) { 11 SpringApplication.run(Center1Application.class, args); 12 } 13 }View Code 註冊中心2: pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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>com.zxy</groupId> <artifactId>eureka-client-center2</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>eureka-client-center2</name> <description>Forward project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>View Code 配置文件
1 server: 2 port: 9999 3 spring: 4 application: 5 name: server-center2 6 eureka: 7 instance: 8 appname: center2 9 client: 10 service-url: 11 defaultZone: http://127.0.0.1:8888/eureka/ 12 # 註冊中心沒必要將自己註冊給自己 13 register-with-eureka: false 14 # 註冊中心不需要去檢索服務,調用服務,故而不需要獲取註冊服務清單 15 fetch-registry: false 16 server: 17 # 設置讀取超時時間 18 peer-node-read-timeout-ms: 12000 19 # 關閉自我保護 20 enable-self-preservation: false啟動
1 package com.zxy.demo; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 7 import org.springframework.scheduling.annotation.EnableScheduling; 8 9 @SpringBootApplication 10 @EnableEurekaServer 11 public class Center2Application { 12 13 public static void main(String[] args) { 14 SpringApplication.run(Center2Application.class, args); 15 } 16 }View Code 二、服務提供者代碼 pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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>com.zxy</groupId> <artifactId>eureka-client-provider1</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>eureka-client</name> <description>Forward project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>View Code 配置
server: port: 1001 spring: application: name: provider eureka: client: service-url: defaultZone: http://127.0.0.1:8888/eureka/ # 服務提供者如果也需要作為消費者則可以獲取註冊清單,如果單純作為服務提供者則不需要獲取服務清單 fetch-registry: false # 服務提供者需要提供服務,所以需要將自己註冊在註冊中心上 register-with-eureka: false # 服務提供者需要把下面的實例名關閉,否則在按照消費端的代碼調用是會找不到主機名(啟動單實例提供者把下面註釋掉) # instance: # hostname: provider1啟動類
1 package com.zxy.demo; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 7 @SpringBootApplication 8 @EnableDiscoveryClient 9 public class ProviderApplication { 10 11 public static void main(String[] args) { 12 SpringApplication.run(ProviderApplication.class, args); 13 } 14 }View Code 接口類
1 package com.zxy.demo.proapi; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.RestController; 7 8 @RestController 9 public class HelloWorldController { 10 private Logger logger = LoggerFactory.getLogger(this.getClass()); 11 12 @RequestMapping(value="/welcome") 13 public String getWelcome() { 14 String str = "hello,welcome the world!!!"; 15 logger.info(str); 16 System.out.println(str); 17 return str; 18 } 19 20 }三、消費者代碼 消費者添加一個負載均衡的模板和依賴 pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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>com.zxy</groupId> <artifactId>eureka-client-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>eureka-client-consumer</name> <description>Forward project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>View Code 配置
1 server: 2 port: 2001 3 spring: 4 application: 5 name: consumer 6 eureka: 7 # instance: 8 # hostname: consumer 9 client: 10 service-url: 11 defaultZone: http://127.0.0.1:8888/eureka 12 # 如果需要提供接口共別人調用也可以將其註冊在註冊中心 13 # register-with-eureka: false 14 #獲取服務是服務消費者的基礎,故而下面的設置必須為true,默認是true 15 # fetch-registry: false啟動
1 package com.zxy.demo; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 import org.springframework.cloud.client.loadbalancer.LoadBalanced; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.web.client.RestTemplate; 9 10 @SpringBootApplication 11 @EnableDiscoveryClient 12 public class ConsumerApplication { 13 14 @Bean 15 @LoadBalanced 16 RestTemplate restTemplate() { 17 return new RestTemplate(); 18 } 19 public static void main(String[] args) { 20 SpringApplication.run(ConsumerApplication.class, args); 21 } 22 23 }
接口的類
1 package com.zxy.demo.consumer; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 import org.springframework.web.bind.annotation.RequestMethod; 6 import org.springframework.web.bind.annotation.RestController; 7 import org.springframework.web.client.RestTemplate; 8 9 @RestController 10 public class ConsumerController { 11 @Autowired 12 private RestTemplate template; 13 @RequestMapping(value="/msg0",method=RequestMethod.GET) 14 public String getStr() { 15 System.out.println("I am consumer msg0!"); 16 return template.getForEntity("http://provider/welcome", String.class).getBody(); 17 } 18 19 @RequestMapping(value="/msg1",method=RequestMethod.GET) 20 public String msg() { 21 RestTemplate t = new RestTemplate(); 22 System.out.println("I am consumer msg1!"); 23 return t.getForEntity("http://127.0.0.1:1001/welcome", String.class).getBody(); 24 } 25 }
結果
springCloud 之 Eureka服務治理機制及代碼運行