- [Eureka](#eureka) - [Service Discovery: Eureka Client](#service-discovery-eureka-client) - [将Eureka Client包含到项目中](#将eureka-client包含到项目中) - [向Eureka中注册](#向eureka中注册) - [status page和health indicator](#status-page和health-indicator) - [Eureka的健康检查](#eureka的健康检查) - [Eureka实例和客户端的元数据](#eureka实例和客户端的元数据) - [修改Eureka instance id](#修改eureka-instance-id) - [使用EurekaClient](#使用eurekaclient) - [注册服务速度](#注册服务速度) - [Eureka Server](#eureka-server) - [Eureka Server的启动](#eureka-server的启动) - [高可用](#高可用) - [单机模式](#单机模式) - [Peer Awareness](#peer-awareness) - [IP地址注册](#ip地址注册) # Eureka ## Service Discovery: Eureka Client 服务发现是基于微服务体系结构的关键之一。在微服务体系结构中,如果手动配置每个客户端,这将会很困难,并且很脆弱。 Eureka是Netflix的服务发现的client和server。通过配置和部署,Eureka server可以实现高可用,每个server节点会向其他server节点复制已注册service的状态。 ## 将Eureka Client包含到项目中 如果想要将Eureka Client包含到项目中,可以在依赖中添加如下starter: ```xml org.springframework.cloud spring-cloud-starter-netflix-eureka-client ``` ## 向Eureka中注册 当一个client向eureka server中注册时,其提供了关于其自身的元数据(例如host,port,判断health状态的url等)。eureka从一个service的所有实例接收心跳信息,如果一个实例心跳报接收超过特定的时间,那么该实例将会从注册中心移除。 如下显示了一个简单的Eureka Client: ```java @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); } } ``` 在上述client项目中,如果classpath中存在`spring-cloud-starter-netflix-eureka-client`依赖,那么client应用将会自动在注册到eureka server中。 eureka server的信息需要手动配置: ```yml eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ ``` 在上述的配置中,defaultZone是一个默认的回退值,用于向client提供service url默认值。 将`spring-cloud-starter-netflix-eureka-client`依赖包含在classpath中,既会将应用注册为eureka的一个实例,也会将应用变为eureka的一个客户端(可以查询注册中心并且获取其他service的信息)。 eureka实例的行为将会由`eureka.instance.*`来进行配置,但是当项目制定了`spring.application.name`时,使用默认值来控制eureka实例行为即可。 如果想要禁用Eureka Discovery Client,可以将`eureka.client.enabled`属性配置为false,当`spring.cloud.discovery.enabled`属性被设置为false时,Eureka Discovery Client同样会被禁用。 ## status page和health indicator Eureka实例的status page和health indicator分别指向/info和/health,是spring boot actuator应用的默认端点。 ## Eureka的健康检查 默认情况下,Eureka使用客户端的心跳来判断该客户端是否启用。除非显式指定,否则客户端并不会传播当前应用的健康检查状态。因此,在成功注册之后,Eureka总是宣布该应用处于`UP`状态。 通过显式启用健康检查,上述行为可以被改变,客户端将会将应用的状态传播给eureka server。所有的应用都不会向处于非`UP`状态的节点发送负载。 可以按如下方式启用健康检查: ```yml eureka: client: healthcheck: enabled: true ``` ## Eureka实例和客户端的元数据 标准元数据包含hostname、ip address、port、status page、health indicator等信息。这些元数据信息将会被发布到注册中心,并且被eureka client使用,用于调用远程服务。 ### 修改Eureka instance id Spring Cloud为Eureka instance提供了一个合理的id默认值,其默认值如下: `${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}` 例如`myhost:myappname:8080` 在Spring Cloud中,可以通过如下方式自定义Eureka实例的id: ```yml eureka: instance: instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}} ``` ## 使用EurekaClient 当应用中包含discovery client时,可以使用其从Eureka Server中发现服务实例: ```java @Autowired private EurekaClient discoveryClient; public String serviceUrl() { InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false); return instance.getHomePageUrl(); } ``` ## 注册服务速度 在注册为服务时,需要在一定期间内持续向eureka server发送心跳包,默认情况下该期间持续时间为30s。可以通过定义`eureka.instance.leaseRenewalIntervalInSeconds`值来缩短该期间的时间,将其值设置为小于30.但是,默认情况下,最好将其保留为默认值。 ## Eureka Server 如果要在项目中包含eureka-server,可以在项目中包含如下启动器: ```xml org.springframework.cloud spring-cloud-starter-netflix-eureka-server ``` ### Eureka Server的启动 如下显示了要启动一个Eureka Server的最简代码: ```java @SpringBootApplication @EnableEurekaServer public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } } ``` 在`/eureka/*`路径下,该eureka server拥有UI和http api endpoint。 ### 高可用 Eureka Server并没有后端存储,但是注册到Eureka Server中的所有service实例都必须向eureka server发送心跳包来保证其注册状态是最新的,上述所有操作都是在eureka server的内存中完成的。 client端也会在内存中对eureka server中的注册状态进行缓存,故而无需每次请求其他service时都要从eureka server中获取注册状态。 > 默认情况下,每个eureka server都同时是一个client,并且需要至少一个URL来定位其他的peer instance。如果没有提供该URL,服务仍然能启动,但是会一直输出日志表示无法向其他peer instance注册。 ### 单机模式 单机模式下,可能需要关闭eureka的客户端行为,例如持续获取其peer instance并失败。可以通过如下配置来关闭客户端的行为: ```yml server: port: 8761 eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ ``` 单机模式下,`serviceUrl`指向与本地实例相同的host地址。 ### Peer Awareness 相比于单机模式,通过运行多个eureka实例并且让实例之间相互注册,Eureka可以配置的更加弹性和高可用。上述是eureka的默认行为,配置时只需要指定peer instance的`serviceUrl`,如下所示: ```yml --- spring: profiles: peer1 eureka: instance: hostname: peer1 client: serviceUrl: defaultZone: https://peer2/eureka/ --- spring: profiles: peer2 eureka: instance: hostname: peer2 client: serviceUrl: defaultZone: https://peer1/eureka/ ``` 可以向系统中添加多个peer instance,实例之间两两相互连接,实例之间相互同步注册信息。示例如下: ```yml eureka: client: serviceUrl: defaultZone: https://peer1/eureka/,http://peer2/eureka/,http://peer3/eureka/ --- spring: profiles: peer1 eureka: instance: hostname: peer1 --- spring: profiles: peer2 eureka: instance: hostname: peer2 --- spring: profiles: peer3 eureka: instance: hostname: peer3 ``` ### IP地址注册 在某些场景下,可能更喜欢通过ip地址而不是hostname来进行注册。如果将`eureka.instance.preferIpAddress`设置为true,那么在应用注册到eureka时,会使用ip地址而不是hostname