Eureka
服务注册与发现的组件,统一管理微服务的通信地址,同类型的组件还有 zookeeper等。Eureka包含EurekaServer(服务端)与EurekaClient(客户端),EurekaServer是独立的服务,EurekaClient需要集成到每个微服务中。
工作原理
服务注册
微服务(EurekaClient)启动时,会向注册中心(EurekaServer)提交服务信息(服务命、ip、端口等),注册中心会将服务信息存储起来,形成服务通信地址表存储起来。
服务发现
微服务(EurekaClient)会定期(RegistryFetchIntervalSeconds:默认30s)从注册中心(EurekaServer)拉取服务通讯地址表存储到本地。当微服务之间发起访问时,会先根据服务命,从服务通讯地址表中找到对应的通讯地址,基于http协议向目标服务发起请求。如果找到多个通讯地址,则会根据Ribbon的负载均衡算法(默认轮询),找到其中的一个,发起请求。
服务续约
微服务(EurekaClient)会定时(LeaseRenewalIntervalInSeconds:默认30s)向注册中心(EurekaServer)发起“心跳”请求,进行服务续约。其实就是向注册中心报告自己的健康状况,告诉注册中心自己还活着,不要将自己从服务通讯地址表中清除。
如果微服务(EurekaClient)宕机未向注册中心(EurekaServer)进行续约,或者续约超时,那么注册中心(EurekaServer)就会将微服务(EurekaClient)从服务通讯地址表中清除,清除掉续约失败的微服务(EurekaClient)。
注意
并不是定时30秒一到,注册中心(EurekaServer)没有收到微服务(EurekaClient)的续约请求,注册中心(EurekaServer)就会立即将微服务(EurekaClient)从服务通讯地址表中清除,而是有3次机会(默认90秒),都没有收到微服务(EurekaClient)的续约请求,才会将微服务(EurekaClient)从服务通讯地址表中清除,因为可能会存在网络波动,导致注册中心(EurekaServer)没有收到续约请求的情况。
服务下线
微服务(EurekaClient)关闭服务前,向注册中心(EurekaServer)发送下线请求,注册中心(EurekaServer)收到下线请求后,将该服务从服务通讯地址表中清除。
注意
场景:
如果微服务(EurekaClient)已经宕机,但是注册中心(EurekaServer)还未将该微服务(EurekaClient)从服务通讯地址表中清除,此时有其它微服务(EurekaClient)访问已经宕机的微服务(EurekaClient),会造成访问失败。
解决:
1、在向该服务发起访问请求时,执行重试机制,如果两次(次数可自己设)均访问失败,则访问集群中的另一个服务;
2、将续约时间设短;
EurekaServer
涉及依赖
<!--eureka服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--web包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
启动类:
/**
* 注册中心启动类
* @EnableEurekaServer : 开启EurekaServer服务端
*/
@SpringBootApplication
@EnableEurekaServer //开启EurekaServer服务端,需加此注解
public class EurekaServerApplication{
public static void main( String[] args ){
SpringApplication.run(EurekaServerApplication.class);
}
}
application.yml配置文件
server:
port: 1010 #端口
eureka:
instance:
hostname: localhost #主机
client: #客户端配置
registerWithEureka: false #EurekaServer自己不要注册到EurekaServer自己 ,只有EurekaClient才注册
fetchRegistry: false #EurekaServer不要拉取服务的通信地址列表 ,只有EurekaClient才拉取地址列表
serviceUrl: #注册中心的注册地址
defaultZone: http://localhost:1010/eureka/ #http://${eureka.instance.hostname}:${server.port}/eureka/
server:
enable-self-preservation: false #关闭自我保护警告
说明
EurekaServer的基础依赖spring-cloud-starter-netflix-eureka-server,这个依赖即引入了EurekaServer所需要的包,也引入了EurekaClient的包。意思就是:现在的EurekaServerApplication-1010工程既是一个 EurekaServer,也是一个EurekaClient。所以关闭了向自己注册和拉取通讯地址表
EurekaClient
涉及依赖
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--web包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
启动类:
/**
* 微服务启动类
* @EnableEurekaClient: 标记该应用是 Eureka客户端,可加可不加
* 因为导入spring-cloud-starter-netflix-eureka-client 依赖后,默认就开启了EurekaClient
*/
@SpringBootApplication
@EnableEurekaClient //此应用为 Eureka客户端,可加可不加
public class UserServerApplication {
public static void main( String[] args ) {
SpringApplication.run(UserServerApplication.class);
}
}
application.yml配置文件
#注册到EurekaServer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1010/eureka/ # serviceUrl是EurekaServer注册中的地址
spring:
application:
name: user-server # 该服务的服务命
server:
port: 1020 # 端口
使用ip注册到EurekaServer
#注册到EurekaServer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1010/eureka/
instance:
prefer-ip-address: true # 使用ip地址进行注册
instance-id: user-server:1020 # 实例ID
spring:
application:
name: user-server
server:
port: 1020
默认情况下EurekaClient使用hostname进行注册到EurekaServer,若使用ip进行注册,则配置eureka.instance.prefer-ip-address=true来指定,并且通过eureka.instance.instance-id为user-serer:1020 指定服务的实例ID