Files
rikako-note/spring/Spring Cloud/Spring Cloud Netflix.md

7.5 KiB
Raw Blame History

Eureka

Service Discovery: Eureka Client

服务发现是基于微服务体系结构的关键之一。在微服务体系结构中,如果手动配置每个客户端,这将会很困难,并且很脆弱。
Eureka是Netflix的服务发现的client和server。通过配置和部署Eureka server可以实现高可用每个server节点会向其他server节点复制已注册service的状态。

将Eureka Client包含到项目中

如果想要将Eureka Client包含到项目中可以在依赖中添加如下starter

<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

向Eureka中注册

当一个client向eureka server中注册时其提供了关于其自身的元数据例如hostport判断health状态的url等。eureka从一个service的所有实例接收心跳信息如果一个实例心跳报接收超过特定的时间那么该实例将会从注册中心移除。
如下显示了一个简单的Eureka Client

@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的信息需要手动配置

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属性配置为falsespring.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状态的节点发送负载。
可以按如下方式启用健康检查:

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

eureka:
  instance:
    instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}

使用EurekaClient

当应用中包含discovery client时可以使用其从Eureka Server中发现服务实例

@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可以在项目中包含如下启动器

<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

Eureka Server的启动

如下显示了要启动一个Eureka Server的最简代码

@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并失败。可以通过如下配置来关闭客户端的行为

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,如下所示:

---
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实例之间两两相互连接实例之间相互同步注册信息。示例如下

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地址而不是