Spring Cloud 教程 - Eureka Client

3,461 阅读3分钟
原文链接: www.codemore.top

本文基于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

注册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。 更多配置信息可以参考EurekaInstanceConfigBeanEurekaClientConfigBean

通过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参数修改心跳的时间。尽量不要修改这个参数。