Files
rikako-note/spring/Spring Cloud/Spring Cloud Netflix.md
2023-03-27 18:28:44 +08:00

120 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Eureka
## Service Discovery: Eureka Client
服务发现是基于微服务体系结构的关键之一。在微服务体系结构中,如果手动配置每个客户端,这将会很困难,并且很脆弱。
Eureka是Netflix的服务发现的client和server。通过配置和部署Eureka server可以实现高可用每个server节点会向其他server节点复制已注册service的状态。
## 将Eureka Client包含到项目中
如果想要将Eureka Client包含到项目中可以在依赖中添加如下starter
```xml
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
```
## 向Eureka中注册
当一个client向eureka server中注册时其提供了关于其自身的元数据例如hostport判断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
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
```
### 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来定位其他的service实例。
### 单机模式
单机模式下,可以通过如下配置来关闭客户端的行为:
```yml
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
```