Eureka简介
Eureka是Netflix开源的服务发现组件,本身是一个基于REST的服务。它包含server和client两部分。Spring Cloud将它继承在子项目Spring Cloud Netflix中,从而实现服务的发现与注册。
Eureka包含两个组件:Eureka Server和Eureka Client。
Eureka Server提供服务发现的能力,各个微服务启动时,会向Eureka Server注册自己的信息(例如IP地址,端口号,服务名称等等),Eureka Server会记录这些信息。
Eureka Client是一个Java客户端,用户简化与Eureka Server的交互。
微服务启动之后,会周期性(默认30秒)的向Eureka Server发送心跳以续约自己的“租期”。
如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将注销这个实例(默认90秒)。
默认情况下,Eureka Server同时也是Eureka Client。多个Eureka Server实例相互之间通过复制的方式实现服务注册表中数据同步。
Eureka Client会缓存服务注册表中的信息。这种方式有一定的优势——首先,微服务无需每次请求都查询Eureka Server,从而降低了Eureka Server的压力;其次,即使Eureka Server所有节点都宕机,服务消费之也可以使用缓存中的信息找到服务提供者并完成调用。
编写Eureka Server
新建Spring Boot项目命名为microservice-discovery-eureka
- pom.xml文件添加如下依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 在启动类上添加@EnableEurekaServer注解,声明这是一个Eureka Server。
@SpringBootApplication
@EnableEurekaServer
public class MicroserviceDiscoveryEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceDiscoveryEurekaApplication.class, args);
}
}
在application.properties文件添加一下内容。
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
eureka.client.register-with-eureka:表示是否将自己注册到Eureka Server,默认为ture。由于当前应用就是一个Eureka Server,所以设置为false。
eureka.client.fetch-registry:表示是否从Eureka Server获取注册信息,默认为true。由于这是一个单点的Eureka Server,不需要同步其他Eureka Server节点的数据,所以设置为false。
eureka.client.service-url.default-zone:设置与Eureka Server交互的地址,查询服务和注册服务都要依赖这个地址。默认是http://localhost:8761/eureka;多个地址间可以使用,隔开。
访问http://localhost:8761/我们就可以看到Eureka Server界面
将微服务注册到Eureka Server上
新建一个SpringBoot项目microservice-provider-user(此处省略接口代码实现),在pom.xml添加如下依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependencyManageent>
<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>
在application.properties中添加一下配置
spring.application.name=microservice-provider-user
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
eureka.instance.ip-address=true
spring.application.name:表示将自己注册到Eureka Server上的应用名字
eureka.instance.ip-address:表示将自己的IP注册到Eureka Server。如不配置该属性或者将其配置为false,则表示注册微服务所在操作系统的hostname到Eureka Server。
启动项目,可以在Eureka Server上看到我们注册的服务
编写高可用的Eureka Server
- 将之前Eureka Server拷贝一份。
- 修改hosts文件。
127.0.0.1 peer1 peer2
- 修改之前拷贝的Eureka Server,添加application-peer1.properties和application-peer2.properties
application-peer1.properties
server.port=8761
eureka.instance.hostname=peer1
eureka.client.service-url.default-zone=http://peer2:8762/eureka/
application-peer2.properties
server.port=8762
eureka.instance.hostname=peer2
eureka.client.service-url.default-zone=http://peer1:8761/eureka/
application.properties
spring.application.name=microservice-discovery-eureka-ha
- 打包并运行
java -jar microservice-discovery-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar microservice-discovery-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
将应用注册到Eureka Server集群上
以之前写好的microservice-provider-user为例,只需要修改eureka.client.service-url.default-zone配置多个Eureka Server地址,就可以将其注册到Eureka Service集群上。
eureka.client.service-url.default-zone=http://peer2:8762/eureka/,http://peer1:8761/eureka/
当然只配置之其中一个Eureka Service节点也可以将其注册到集群中,因为Eureka Service之前的数据会相互同步。
eureka.client.service-url.default-zone=http://peer2:8762/eureka/
Eureka Server添加用户认证
Eureka Server提供的web控制台是没有安全认证的。可以通过Spring Security来进行安全认证。
复制之前的microservice-discovery-eureka命名为microservice-discovery-eureka-authenticating
在pom.xml添加Spring Security依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
修改application.yml
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
default-zone: http://root:123456@localhost:8761/eureka/
security:
basic:
enabled: true
user:
name: root
password: 123456
security.basic.enable开启基于HTTP basic的认证(默认为true)
security.user.name设置用户名(默认值为user)
security.user.password设置密码(默认值是一个随机值,启动的时候会打印出来)
复制之前的microservice-provider-user命名为microservice-provider-user-authenticating
在pom.xml添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
修改application-dev.properties中的eureka.client.service-url.default-zone
eureka.client.service-url.default-zone=http://root:123456@localhost:8761/eureka/
Eureka的健康检查
模拟情况当Eureka Client连接不上数据源,Eureka Server中的微服务状态还是显示为UP,如下图
但是我们查看当前微服务的/health节点发现status为DOWN,这种情况下微服务的提供者已经不能正确提供服务,但是Eureka Server并不知道,那么就需要用到Eureka的健康检查,将/health节点中的状态传给Eureka Server
- 给Eureka Client添加actuator依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 给Eureka Client的application.yml添加如下配置
eureka:
client:
healthcheck:
enabled: true
配置详解
Eureka客户端的配置主要分为以下两个方面:
- 服务注册相关的配置信息,包括服务注册中心的地址、服务获取的间隔时间、可用区域等。
- 服务实例相关的配置信息,包括服务实例的名称、IP地址、端口号、健康检查路径等。
以下列出常用的一些服务注册相关的配置信息以及说明。以下配置均以eureka.client为前缀
参数名 | 说明 | 默认值 |
enabled | 启用Eureka客户端 | true |
registry-fetch-interval-seconds | 从Eureka服务端获取注册信息的间隔时间,单位为秒 | 30 |
instance-info-replication-interval-seconds | 更新实例信息的变化到Eureka服务端的间隔时间,单位为秒 | 30 |
initial-instance-info-replication-interval-seconds | 初始化实例信息到Eureka服务端的间隔时间,单位为秒 | 40 |
eureka-service-url-poll-interval-seconds | 轮训Eureka服务端地址更改的间隔时间,单位为秒 | 300 |
eureka-server-read-timeout-seconds | 读取Eureka Server信息的超时时间,单位为秒 | 8 |
eureka-server-connect-timeout-seconds | 连接Eureka Server的超时时间,单位为秒 | 5 |
eureka-server-total-connections | 从Eureka客户端到所有Eureka服务端的连接总数 | 200 |
eureka-server-total-connections-per-host | 从Eureka客户端到每个Eureka服务端主机的连接总数 | 50 |
eureka-connection-idle-timeout-seconds | Eureka服务端连接的空闲关闭时间,单位为秒 | 30 |
heartbeat-executor-thread-pool-size | 心跳连接池的初始化线程总数 | 2 |
heartbeat-executor-exponential-back-off-bound | 心跳超时重试延迟时间的最大乘数值 | 10 |
use-dns-for-fetching-service-urls | 使用DNS来获取Eureka服务端的ServiceUrl | false |
filter-only-up-instances | 获取实例时是否过滤,仅保留UP状态的实例 | true |
prefer-same-zone-eureka | 是否偏好使用处于相同zone的Eureka服务端 | true |
cache-refresh-executor-exponential-back-off-bound | 缓存刷新重试延迟时间的最大乘数值 | 10 |
cache-refresh-executor-thread-pool-size | 缓存刷新线程池的初始化线程数 | 2 |
register-with-eureka | 是否将自身的实例信息注册到Eureka服务端 | true |
fetch-registry | 是否从Rureka服务端获取注册信息 | true |
以下列出常用的一些服务实例相关的配置信息以及说明。以下配置均以eureka.instance为前缀
参数名 | 说明 | 默认值 |
prefer-ip-address | 是否优先使用IP地址作为主机名的表示 | false |
lease-renewal-interval-in-seconds | Eureka客户端向服务端发送心跳的间隔时间,单位为秒 | 30 |
lease-expiration-duration-in-seconds | Eureka服务端在收到最后一次心跳之后的等待时间上线,单位为秒。超过该时间之后服务端会将该服务实例从服务清单中剔除 | 90 |
non-secure-port | 非安全的通信端口号 | 80 |
secure-port | 安全的通信端口号 | 443 |
non-secure-port-enabled | 是否启用非安全的通信端口号 | true |
secure-port-enabled | 是否启用安全的通信端口号 | |
appname | 服务名,默认取spring.application.name的配置值,如果没有则为unknown | |
hostname | 主机名,不配置的时候根据操作系统的主机名来获取 |