本文基于 Spring Cloud Finchley.RELEASE 版本.
服务发现: Eureka clients
服务发现是微服务架构的一个关键原则. 手动配置每一个客户端不仅非常复杂, 同时也容易出错. Netflix 提供了 Erueka 作为服务发现的服务端和客户端. Srever 端可配置, 同时每个 server 可以互相注册做高可用部署.
如何使用 Eureka Client
将 groupId 为
org.springframework.cloud
,artifactId 为
spring-cloud-starter-netflix-eureka-client
的依赖添加到项目中即可引入 Eureka Client, 具体版本号可以参考 Spring Cloud Project https://projects.spring.io/spring-cloud/
注册 Eureka Client
客户端向 Eureka 注册的时候会提供一系列的元数据信息, 例如: 主机, 端口, 健康检查 url, 主页等. Eureka 接受每个服务发送的心跳信息, 如果在某个配置的超时时间内未接收到心跳信息, 实例会被从注册列表中移除. 例如如下的服务:
- @SpringBootApplication
- @RestController
- public class Application { @RequestMapping("/")
- public String home() {
- return "Hello world";
- }
- public static void main(String[] args) {
- new SpringApplicationBuilder(Application.class).web(true).run(args);
- }
- }
当把
spring-cloud-starter-netflix-eureka-client
添加到 classpath 时, 应用会自动的注册到 Eureka Server 中, 只需要配置 Eureka 服务器位置.
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8761/eureka/
可以通过
${spring.application.name}
,${server.port} 配置注册的服务名和服务端口. 将
spring-cloud-starter-netflix-eureka-client
添加到 classpath 会使服务注册为一个 Eureka 的实例, 即服务本身会向自己注册, 同时也是一个从注册中心获取其他服务的客户端. 如果想要关闭自我注册的服务可以设置
eureka.client.enabled=false
. 更多配置信息可以参考 https://github.com/spring-cloud/spring-cloud-netflix/tree/master/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java 和 https://github.com/spring-cloud/spring-cloud-netflix/tree/master/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java .
通过 Eureka Server 授权
如果 Eureka Server 配置了 http basic 的授权信息, 可以通过将授权信息添加到
eureka.client.serviceUrl.defaultZone
中设置授权信息,
- eureka.client.serviceUrl.defaultZone=http://user:password@localhost:8761/eureka
- .
状态页和健康检查
Eureka 实例默认的状态页和健康检查接口是 / info 和 / health, 他们是 Spring Boot Actuator 默认的端点. 如果不想采用默认的设置可以通过修改 Servlet Path (server.servletPath=/custom) 或者管理路径 (management.contextPath=/admin),yaml 中配置
- eureka:
- instance:
- statusPageUrlPath: ${management.server.servlet.context-path}/info
- healthCheckUrlPath: ${management.server.servlet.context-path}/health
注册一个安全的应用
如果应用需要通过 HTTPS 通信, 可以设置:
- eureka.instance.nonSecurePortEnabled=false
- eureka.instance.securePortEnabled=true
通过设置这两个配置, 可以让 Eureka 发布安全的通信, DiscoveryClient 每次都会返回 https 开头的 URI. 同样的, 如果服务这么设置, 健康检查也会使用 https. 由于 Eureka 工作在内网, 所以仍然会发布非 https 的健康检查和状态端点, 所以需要手工替换, 例如:
- eureka:
- instance:
- statusPageUrl: https://${eureka.hostname}/info
- healthCheckUrl: https://${eureka.hostname}/health
- homePageUrl: https://${eureka.hostname}/
健康检查
默认情况下, Eureka 使用心跳判断一个服务是否可用. 除非特别说明, 否则服务发现客户端不会根据 Spring Boot Actuator 来发布健康检查. 当成功注册服务的后, Eureka 总是将应用标记为 UP 状态. 可以通过如下配置修改:
- eureka:
- client:
- healthcheck:
- enabled: true
注意这个配置只能配置在 application.yml 中, 如果配置在 bootstrap.yml 可能会出现副作用, 例如注册服务为 UNKNOWN 状态.
Eureka 元数据
标准的元数据信息包括, host,port,ip, 状态页, 健康检查. 如果需要自定义元数据信息可以将其配置到
eureka.instance.metadataMap
中, 这些元数据信息可以被其服务获取
修改 Eureka 实例的 ID
Spring Cloud Eureka 将如下
${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}}
信息注册微 Eureka 实例的 ID. 例如
myhost:myappname:8080
. 通过如下配置可以修改其实例 ID
- eureka:
- instance:
- instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
使用 Eureka Client
通过 EurekaClient 可以获取服务发现的信息, 例如:
- @Autowired
- private EurekaClient discoveryClient;
- public String serviceUrl() {
- InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false);
- return instance.getHomePageUrl();
- }
注意, 不要将 EurekaClient 应用在 @PostConstruct 或者 @Scheduled 的方法中或者其他 ApplicationContext 还未启动的方法中.
移出 Jersey 依赖
默认情况下, EurekaClient 使用 Jersey 作为 HTTP 通信工具, 如果不希望依赖 Jersey, 可以通过将 Jersey 依赖移出. Spring Cloud 默认会使用 RestTempalte 作为通信工具.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-apache-client4</artifactId>
</exclusion>
</exclusions>
</dependency>
为什么服务注册很慢
默认情况下, 心跳时间为 30 秒. 只有在, client,server,client 缓存同时可以用的情况下, 才会判断一个实例可用. 可以修改
eureka.instance.leaseRenewalIntervalInSeconds
参数修改心跳的时间. 尽量不要修改这个参数.
来源: https://juejin.im/entry/5b4de473e51d45194f62b01c