本文章是在网易云课堂的课程学习中编写,部分图片从网易云课堂ppt引用
一、什么是Eureka注册中心
各个服务注册到Eureka,Eureka对服务进行管理:
1、可感知注册的服务的健康情况,是否下线
2、可感知注册的服务的IP和Port地址变更
注:若使用nginx,nginx无法感知注册的服务是否下线,且若变更服务地址,需改动nginx配置
Eureka使用图示:
说明:
服务提供者启动时:定时向EurekaServer注册自己的服务信息(服务名、IP、端口..等等)
服务消费者启动时:后台定时拉取Eureka-Server中存储的服务信息
二、如何集成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
#定义区域,进行分区。使得调用更加方便快捷,适用于非常大的服务器
#availability-zones:
#beijing: zone-1
service-url:
#默认的注册中心的通信地址
defaultZone: http://localhost:10000/eureka/,http://localhost:10001/eureka/,http://localhost:10002/eureka/
#beijing对应区域的通信地址,若该区域没有找到服务,再尝试去访问别的区域
#zone-1: http://localhost:10000/eureka/
#作为服务端的配置
server:
#服务间请求的等待时长
wait-time-in-ms-when-sync-empty: 0
#自我保护机制
enable-self-preservation: true
#同步时长
peer-eureka-nodes-update-interval-ms: 10000
启动工程,网页打开 localhost:10000 可以看到Eureka页面:
1.4 调用链路
在配置文件中,可加入日志级别的配置,查看调用链路信息,用来排查问题
logging.level.org.springframework.cloud = debug
logging.level.com.netflix = debug
2. 生产者(服务提供者)
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个服务提供者
服务提供者1:
@SpringBootApplication
@EnableEurekaClient
@RestController
public class HelloDemoPeer1Application {
public static void main(String[] args) {
SpringApplication.run(HelloDemoPeer1Application.class, args);
}
@GetMapping("")
public Object index(){
String str = "这是服务端1返回的应答";
return new String(str);
}
}
服务提供者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 = "这是服务端2返回的应答";
return new String(str);
}
}
2.3 yml配置
服务提供者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/
服务提供者2:
server:
port: 8002
spring:
application:
name: helloserver
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10000/eureka/
3. 消费者
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>
<!-- 重试机制。如果调用后,出现异常,可以通过重试机制,发起重试。 -->
<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对服务提供者进行访问
注:template方法上的 @LoadBalanced 是用来实现负载均衡,是Ribbon的一种内部应用模式
/**
* 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对服务提供者进行访问,这里使用服务名去访问
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注册中心、生产者、消费者都启动起来,可以在页面上看到注册的服务实例:
(注意:Eureka中的instance名称,不区分大小写)
三、Eureka核心知识
1. 启动时服务如何注册到Eureka的?
启动时,通过后台任务,将 【服务名、ip、端口】 注册到EurekaServer
2. 服务端如何保存这些信息?
客户端启动后,会去调用http,将服务实例放在Server内部一个Map对象中存储
3. 消费者如何根据服务名称发现服务实例?
启动时,通过后台任务,定期从EurekaServer拉取服务信息,缓存到消费者本地内存中
4. 如何构建高可用的eureka集群?
- 在高可用状态下,Eureka通过【对等协议】,将注册在自身的实例,与组内其他Eureka进行同步。
- 在【defaultZone】参数,可配置多个注册中心的地址。
以下配置文件中,分别修改 active 属性值,启动三个注册中心。然后启动生产者,将服务注册到其中一个注册中心。可以看到,三个注册中心都有注册的服务实例 -
服务注册的高可用机制:如果其中一个注册中心出现问题,不会影响其他注册中心的处理。
比如:注册中心1、2、3之间同步服务实例。假设注册中心1挂了,生产者将服务注册到注册中心 1 ,注册中心 2 和 3 也还是能收到该生产者注册的服务实例 - 如何防止各注册中心的重复传播:源码中,通过isReplication判断
spring:
profiles:
active: dev
#分割符号,分割不同的环境
---
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:
#默认的注册中心的通信地址,高可用配置
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: 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. 心跳和服务剔除机制是什么?
心跳:客户端定期发送心跳请求包到EurekaServer
若心跳长时间没有发送,eureka则会采用剔除机制,将服务实例改为 Down 状态
6. eureka自我保护模式是什么?
生产上一般会开启自我保护模式。开启自我保护机制后,服务一旦下线,注册中心中不会剔除该服务,避免将可用的服务也剔除了。
问题:如何避免调用到宕机的服务
处理:提供了补偿方案,如重试机制、熔断机制