本文章是在網(wǎng)易云課堂的課程學(xué)習(xí)中編寫剪个,部分圖片從網(wǎng)易云課堂ppt引用
一、什么是Eureka注冊中心
各個服務(wù)注冊到Eureka,Eureka對服務(wù)進(jìn)行管理:
1、可感知注冊的服務(wù)的健康情況取董,是否下線
2、可感知注冊的服務(wù)的IP和Port地址變更
注:若使用nginx无宿,nginx無法感知注冊的服務(wù)是否下線茵汰,且若變更服務(wù)地址,需改動nginx配置
Eureka使用圖示:
說明:
服務(wù)提供者啟動時:定時向EurekaServer注冊自己的服務(wù)信息(服務(wù)名孽鸡、IP蹂午、端口..等等)
服務(wù)消費(fèi)者啟動時:后臺定時拉取Eureka-Server中存儲的服務(wù)信息
二、如何集成Eureka
1. Eureka注冊中心
1.1 maven引入
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<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>
1.2 代碼
在Application使用 @EnableEurekaServer
注解
1.3 yml配置
spring:
application:
name: eureka-peer
profiles: dev
server:
port: 10000
eureka:
#實例
instance:
hostname: dev
instance-id: dev
#作為客戶端的配置
client:
#是否從eureka拉取信息
fetch-registry: false
#是否將自己注冊到eureka
register-with-eureka: false
#定義區(qū)域彬碱,進(jìn)行分區(qū)豆胸。使得調(diào)用更加方便快捷,適用于非常大的服務(wù)器
#availability-zones:
#beijing: zone-1
service-url:
#默認(rèn)的注冊中心的通信地址
defaultZone: http://localhost:10000/eureka/,http://localhost:10001/eureka/,http://localhost:10002/eureka/
#beijing對應(yīng)區(qū)域的通信地址巷疼,若該區(qū)域沒有找到服務(wù)晚胡,再嘗試去訪問別的區(qū)域
#zone-1: http://localhost:10000/eureka/
#作為服務(wù)端的配置
server:
#服務(wù)間請求的等待時長
wait-time-in-ms-when-sync-empty: 0
#自我保護(hù)機(jī)制
enable-self-preservation: true
#同步時長
peer-eureka-nodes-update-interval-ms: 10000
啟動工程,網(wǎng)頁打開 localhost:10000 可以看到Eureka頁面:
1.4 調(diào)用鏈路
在配置文件中,可加入日志級別的配置估盘,查看調(diào)用鏈路信息瓷患,用來排查問題
logging.level.org.springframework.cloud = debug
logging.level.com.netflix = debug
2. 生產(chǎn)者(服務(wù)提供者)
2.1 maven引入
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<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>
<version>2.1.1.RELEASE</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.2 代碼示例
在Application使用 @EnableEurekaClient
注解。這里配置2個服務(wù)提供者
服務(wù)提供者1:
@SpringBootApplication
@EnableEurekaClient
@RestController
public class HelloDemoPeer1Application {
public static void main(String[] args) {
SpringApplication.run(HelloDemoPeer1Application.class, args);
}
@GetMapping("")
public Object index(){
String str = "這是服務(wù)端1返回的應(yīng)答";
return new String(str);
}
}
服務(wù)提供者2:
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient
@RestController
@RefreshScope
public class HelloDemoPeer1Application {
public static void main(String[] args) {
SpringApplication.run(HelloDemoPeer1Application.class, args);
}
@GetMapping("")
public Object index(){
String str = "這是服務(wù)端2返回的應(yīng)答";
return new String(str);
}
}
2.3 yml配置
服務(wù)提供者1:
server:
port: 8001
spring:
application:
name: helloserver
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10000/eureka/,http://127.0.0.1:10001/eureka/,http://127.0.0.1:10002/eureka/
服務(wù)提供者2:
server:
port: 8002
spring:
application:
name: helloserver
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10000/eureka/
3. 消費(fèi)者
3.1 maven引入
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<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>
<!-- 重試機(jī)制遣妥。如果調(diào)用后擅编,出現(xiàn)異常,可以通過重試機(jī)制燥透,發(fā)起重試沙咏。 -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</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>
3.2 代碼示例
使用RestTemplate對服務(wù)提供者進(jìn)行訪問
注:template方法上的 @LoadBalanced 是用來實現(xiàn)負(fù)載均衡,是Ribbon的一種內(nèi)部應(yīng)用模式
/**
* CustomerDemoApplication
*/
@SpringBootApplication
@RestController
public class CustomerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerDemoApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate template(){
return new RestTemplate();
}
}
/**
* CustomerController
*/
@RestController
public class CustomerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("index")
public Object getIndex(){
//使用RestTemplate對服務(wù)提供者進(jìn)行訪問班套,這里使用服務(wù)名去訪問
return restTemplate.getForObject("http://HELLOSERVER/",String.class,"");
}
}
3.3 yml配置
server:
port: 8083
spring:
application:
name: consumer-demo
eureka:
client:
service-url:
defaultZone : http://127.0.0.1:10000/eureka/
將Eureka注冊中心肢藐、生產(chǎn)者、消費(fèi)者都啟動起來吱韭,可以在頁面上看到注冊的服務(wù)實例:
(注意:Eureka中的instance名稱吆豹,不區(qū)分大小寫)
三、Eureka核心知識
1. 啟動時服務(wù)如何注冊到Eureka的理盆?
啟動時痘煤,通過后臺任務(wù),將 【服務(wù)名猿规、ip衷快、端口】 注冊到EurekaServer
2. 服務(wù)端如何保存這些信息?
客戶端啟動后姨俩,會去調(diào)用http蘸拔,將服務(wù)實例放在Server內(nèi)部一個Map對象中存儲
3. 消費(fèi)者如何根據(jù)服務(wù)名稱發(fā)現(xiàn)服務(wù)實例?
啟動時环葵,通過后臺任務(wù)调窍,定期從EurekaServer拉取服務(wù)信息,緩存到消費(fèi)者本地內(nèi)存中
4. 如何構(gòu)建高可用的eureka集群张遭?
- 在高可用狀態(tài)下邓萨,Eureka通過【對等協(xié)議】,將注冊在自身的實例菊卷,與組內(nèi)其他Eureka進(jìn)行同步缔恳。
- 在【defaultZone】參數(shù),可配置多個注冊中心的地址洁闰。
以下配置文件中褐耳,分別修改 active 屬性值,啟動三個注冊中心渴庆。然后啟動生產(chǎn)者铃芦,將服務(wù)注冊到其中一個注冊中心雅镊。可以看到刃滓,三個注冊中心都有注冊的服務(wù)實例 -
服務(wù)注冊的高可用機(jī)制:如果其中一個注冊中心出現(xiàn)問題仁烹,不會影響其他注冊中心的處理。
比如:注冊中心1卓缰、2扔字、3之間同步服務(wù)實例。假設(shè)注冊中心1掛了,生產(chǎn)者將服務(wù)注冊到注冊中心 1 年枕,注冊中心 2 和 3 也還是能收到該生產(chǎn)者注冊的服務(wù)實例 - 如何防止各注冊中心的重復(fù)傳播:源碼中,通過isReplication判斷
spring:
profiles:
active: dev
#分割符號霍弹,分割不同的環(huán)境
---
spring:
application:
name: eureka-peer
profiles: dev
server:
port: 10000
eureka:
#實例
instance:
hostname: dev
instance-id: dev
#作為客戶端的配置
client:
#是否從eureka拉取信息
fetch-registry: false
#是否將自己注冊到eureka
register-with-eureka: false
service-url:
#默認(rèn)的注冊中心的通信地址岛宦,高可用配置
defaultZone: http://localhost:10000/eureka/,http://localhost:10001/eureka/,http://localhost:10002/eureka/
#作為服務(wù)端的配置
server:
#服務(wù)間請求的等待時長
wait-time-in-ms-when-sync-empty: 0
#自我保護(hù)機(jī)制
enable-self-preservation: true
#同步時長
peer-eureka-nodes-update-interval-ms: 10000
---
spring:
profiles: dev1
application:
name: eureka-peer2
server:
port: 10001
eureka:
instance:
hostname: dev1
instance-id: dev1
client:
fetch-registry: false
register-with-eureka: false
service-url:
defaultZone: http://localhost:10000/eureka/,http://localhost:10001/eureka/,http://localhost:10002/eureka/
server:
wait-time-in-ms-when-sync-empty: 0
enable-self-preservation: true
peer-eureka-nodes-update-interval-ms: 10000
---
spring:
profiles: dev2
application:
name: eureka-peer3
server:
port: 10002
eureka:
instance:
hostname: dev2
instance-id: dev2
client:
fetch-registry: false
register-with-eureka: false
service-url:
defaultZone: http://localhost:10000/eureka/,http://localhost:10001/eureka/,http://localhost:10002/eureka/
server:
wait-time-in-ms-when-sync-empty: 0
enable-self-preservation: true
peer-eureka-nodes-update-interval-ms: 10000
---
5. 心跳和服務(wù)剔除機(jī)制是什么变汪?
心跳:客戶端定期發(fā)送心跳請求包到EurekaServer
若心跳長時間沒有發(fā)送他嫡,eureka則會采用剔除機(jī)制钢属,將服務(wù)實例改為 Down 狀態(tài)
6. eureka自我保護(hù)模式是什么?
生產(chǎn)上一般會開啟自我保護(hù)模式染乌。開啟自我保護(hù)機(jī)制后,服務(wù)一旦下線台谊,注冊中心中不會剔除該服務(wù),避免將可用的服務(wù)也剔除了盐须。
問題:如何避免調(diào)用到宕機(jī)的服務(wù)
處理:提供了補(bǔ)償方案贼邓,如重試機(jī)制、熔斷機(jī)制