|
|
网飞实现的并开源的Spring cloud 套件,以下是常用组件
|
|
|
|
|
|
| | 用途 |
|
|
|
| ------- | ---- |
|
|
|
| Eureka | 服务注册和发现,它提供了一个服务注册中心、服务发现的客户端,还有一个方便的查看所有注册的服务的界面。 所有的服务使用Eureka的服务发现客户端来将自己注册到Eureka的服务器上 |
|
|
|
| Zuul | 网关,所有的客户端请求通过这个网关访问后台的服务。zuul也需要在注册中心注册 |
|
|
|
| Ribbon | 负载均衡,Zuul网关将一个请求发送给某一个服务的应用的时候,如果一个服务启动了多个实例,就会通过Ribbon来通过一定的负载均衡策略来发送给某一个服务实例 |
|
|
|
| Feign | 服务客户端,服务之间如果需要相互访问,可以使用RestTemplate,也可以使用Feign客户端访问。它默认会使用Ribbon来实现负载均衡 |
|
|
|
| Hystrix | 监控和断路器。我们只需要在服务接口上添加Hystrix标签,就可以实现对这个接口的监控和断路器功能 |
|
|
|
| Turbine | 监控聚合,使用Hystrix监控,我们需要打开每一个服务实例的监控信息来查看。而Turbine可以帮助我们把所有的服务实例的监控信息聚合到一个地方统一查看。这样就不需要挨个打开一个个的页面一个个查看 |
|
|
|
|
|
|
|
|
|
## 一、Eureka 注册中心
|
|
|
Eureka 是 Netflix 出品的用于实现服务注册和发现的工具,Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。
|
|
|
Eureka采用C-S的设计架构,包含Eureka Server 和Eureka Client两个组件。
|
|
|
服务启动后向Eureka注册,Eureka Server会将注册信息向其他Eureka Server进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。
|
|
|
|
|
|
客户端引入
|
|
|
```xml
|
|
|
<dependency>
|
|
|
<groupId>org.springframework.cloud</groupId>
|
|
|
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
|
|
</dependency>
|
|
|
```
|
|
|
|
|
|
服务端引入
|
|
|
```xml
|
|
|
<dependency>
|
|
|
<groupId>org.springframework.cloud</groupId>
|
|
|
<artifactId>spring-cloud-starter-eureka-server</artifactId>
|
|
|
</dependency>
|
|
|
```
|
|
|
|
|
|
在默认配置中EurekaServer服务在一定时间(默认为90秒)没接受到某个服务的心跳连接后,EurekaServer会注销该服务。但是会存在当网络分区发生故障,导致该时间内没有心跳连接,但该服务本身还是健康运行的情况。Eureka通过“自我保护模式”来解决这个问题。
|
|
|
在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。
|
|
|
## 二、Zuul 网关
|
|
|
API Gateway(APIGW / API 网关),顾名思义,是出现在系统边界上的一个面向 API 的、串行集中式的强管控服务,这里的边界是企业 IT 系统的边界,可以理解为`企业级应用防火墙`,主要起到`隔离外部访问与内部系统的作用`。API 网关是一个服务器,是系统对外的唯一入口。API 网关封装了系统内部架构,为每个客户端提供定制的 API。所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有非业务功能。
|
|
|
|
|
|
![[Pasted image 20231119161342.png]]
|
|
|
|
|
|
引入网关的好处:
|
|
|
- 聚合接口使得服务对调用者透明,客户端与后端的耦合度降低
|
|
|
- 聚合后台服务,节省流量,提高性能,提升用户体验
|
|
|
- 提供安全、流控、过滤、缓存、计费、监控等 API 管理功能
|
|
|
|
|
|
Zuul可以通过加载动态过滤机制,从而实现以下各项功能:
|
|
|
- 验证与安全保障: 识别面向各类资源的验证要求并拒绝那些与要求不符的请求。
|
|
|
- 审查与监控: 在边缘位置追踪有意义数据及统计结果,从而为我们带来准确的生产状态结论。
|
|
|
- 动态路由: 以动态方式根据需要将请求路由至不同后端集群处。
|
|
|
- 压力测试: 逐渐增加指向集群的负载流量,从而计算性能水平。
|
|
|
- 负载分配: 为每一种负载类型分配对应容量,并弃用超出限定值的请求。
|
|
|
- 静态响应处理: 在边缘位置直接建立部分响应,从而避免其流入内部集群。
|
|
|
- 多区域弹性: 跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。
|
|
|
## 三、Feign HttpClient
|
|
|
![[Pasted image 20231119163557.png]]
|
|
|
Feign 远程调用流程:
|
|
|
1. 基于面向接口的动态代理方式生成实现类
|
|
|
2. 根据 Contract 协议规则,解析接口类的注解信息,解析成内部表现
|
|
|
3. 基于 RequestBean,动态生成 Request
|
|
|
4. 使用 Encoder 将 Bean 转换成 Http 报文正文
|
|
|
5. 拦截器负责对请求和返回进行装饰处理
|
|
|
6. 日志记录器记录请求日志
|
|
|
7. 基于重试器发送 HTTP 请求
|
|
|
|
|
|
![[Pasted image 20231119223042.png]]
|
|
|
|
|
|
### 3.1 基于面向接口的动态代理方式生成实现类
|
|
|
在使用 Feign 时,会定义对应的接口类,在接口类上使用 Http 相关的注解,标识 Http 请求参数信息。 在 Feign 底层,通过基于面向接口的动态代理方式生成实现类,将请求调用委托到动态代理实现类,基本原理如下所示:
|
|
|
![[Pasted image 20231119225018.png]]
|
|
|
|
|
|
### 3.2 根据 Contract 协议规则,解析接口类的注解信息,解析成内部表现
|
|
|
![[Pasted image 20231119225141.png]]
|
|
|
|
|
|
### 3.3 基于 RequestBean,动态生成 Request
|
|
|
根据传入的 Bean 对象和注解信息,从中提取出相应的值,来构造 Http Request 对象。
|
|
|
|
|
|
|
|
|
### 3.4 使用 Encoder 将 Bean 转换成 Http 报文正文
|
|
|
Feign 最终会将请求转换成Http 消息发送出去,传入的请求对象最终会解析成消息体
|
|
|
![[Pasted image 20231119225224.png]]
|
|
|
|
|
|
### 3.5 拦截器负责对请求和返回进行装饰处理
|
|
|
在请求转换的过程中,Feign 抽象出来了拦截器接口,用于用户自定义对请求的操作,比如,如果希望 Http 消息传递过程中被压缩,可以定义一个请求拦截器。
|
|
|
|
|
|
### 3.6 日志记录器记录请求日志
|
|
|
|
|
|
### 3.7 基于重试器发送 HTTP 请求
|
|
|
Feign 内置了一个重试器,当 HTTP 请求出现 IO 异常时,Feign 会有一个最大尝试次数发送请求。
|
|
|
Feign 真正发送HTTP请求是委托给 feign.Client 来做的。
|
|
|
Feign 默认底层通过 JDK 的 java.net.HttpURLConnection 实现了 feign.Client 接口类,**在每次发送请求的时候,都会创建新的HttpURLConnection 链接**,这也就是为什么默认情况下 Feign 的性能很差的原因。可以通过拓展该接口,使用 Apache HttpClient 或者 OkHttp3 等基于连接池的高性能 Http 客户端。
|
|
|
|
|
|
## 四、Ribbon |