服务注册与发现-Eureka单机模式
Eureka组件说明
eureka包含两大组件.分别是Eureka Server和Eureka Client,它们的作用如下:
1.Eureka提供服务发现的能力.各个微服务启动的时候.会想Eureka Server注册自己的信息(IP, 端口, 微服务名称等)
2.Eureka Client是一个Java客户端, 用于简化和Eureka Server的交互
3.Client默认启动的时候.会周期性(默认30s)的向Eureka Server发送心跳已续约自己的租期
如果Server在一定周期内(默认90s)没有接收到Client实例的心跳.Server将会注销该实例
4.默认情况下.Server同时也是Client.多个Server实例.相互之间通过复制的方式.来实现服务注册表中数据的同步
5.Client会缓存服务注册表中的信息.无需每次请求都查询Server.避免因Server宕机而发生无法请求服务
- 以上 Eureka 理论知识,来源于 [SpringClound微服务实战][2],
进入代码
1.首先我们新建一个spring boot项目.引入spring-cloud-starter-netflix-eureka-server 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2.在启动类上.添加EnableEurekaServer注解.声明该项目为Eureka服务注册中心
@SpringBootApplication
@EnableEurekaServer
public class EurekaModelApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaModelApplication.class, args);
}
}
3.修改application.properties配置文件后缀为yml.并添加如下配置信息
ip-addr: localhost
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
client:
register-with-eureka: false # 是否将自己注册到eureka Server注册中心去,默认为true,因为该服务本身为注册服务.所以为false
fetch-registry: false # 是否需要从注册中心获取注册信息.默认为true,我们只是一个单点服务.不需要同步.所以设为false
service-url:
defaultZone: http://${ip-addr}:${server.port}/eureka/
启动Eureka Server.访问http://localhost:8761/见到如下界面.即为配置成功
4.新建一个spring boot项目.引入Eureka依赖.启动类添加EnableEurekaClient注解.标明该项目为一个微服务客户端
@SpringBootApplication
@EnableEurekaClient
public class EurekaProviderUserApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaProviderUserApplication.class, args);
}
}
5.同理.修改配置文件
ip-addr: localhost
server:
port: 8080
spring:
application:
name: eureka-provider-user
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://${ip-addr}:8761/eureka/
启动Eureka-Client类.可见实例已经注册成功
在这里.我如果关掉该Client实例.再次刷新http://localhost:8761/,还是能显示该实例.这个因为自我保护机制,Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致)。
解决办法:
添加如下配置,关闭自我保护
Eureka server application.yml
eureka:
client:
register-with-eureka: false # 是否将自己注册到eureka Server注册中心去,默认为true,因为该服务本身为注册服务.所以为false
fetch-registry: false # 是否需要从注册中心获取注册信息.默认为true,我们只是一个单点服务.不需要同步.所以设为false
service-url:
defaultZone: http://${ip-addr}:${server.port}/eureka/
server:
enable-self-preservation: false # eureka的自我保护机制,默认为true
Eureka Client application.yml
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://${ip-addr}:8761/eureka/
instance:
lease-renewal-interval-in-seconds: 1 # 表示eureka client发送心跳给server端的频率。如果在leaseExpirationDurationInSeconds后,server端没有收到client的心跳,则将摘除该instance,默认为30秒
lease-expiration-duration-in-seconds: 2 #表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance。默认为90秒
关于Eureka的自我保护机制
首先对Eureka注册中心需要了解的是Eureka各个节点都是平等的,没有ZK中角色的概念, 即使N-1个节点挂掉也不会影响其他节点的正常运行。默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护。