Spring Cloud 知识归纳
文章目录
前言
在Spring Cloud 中涉及到非常多的组件,如Eureka 注册中心、,远程调用、负载均衡、微服务容错机制、微服务网关的配置、微服务链路追踪等,这些组件版本多,并且更新迭代比较快,对此对其中涉及到的一些关键插件及原理做些详细总结。
一、微服务的注册和发现 Eureka
如何配置一个微服务注册组件??
- 使用Spring Initializar 构建项目,主要在Spring Cloud Discovery中选择 Eureka Server组件,(lombok 和 DevToos 可选可不选),然后构建项目即可。
- 在启动类需使用注解 @Enable Eureka Server
- 配置文件的配置
server:
port: 9004
spring:
application:
name: eureka-server
eureka:
client:
service-url:
# eureka 服务地址,如果是集群的话;需要指定其它集群eureka地址
defaultZone: http://127.0.0.1:9004/eureka
# 不注册自己
register-with-eureka: false
# 不拉取服务
fetch-registry: false
- 启动测试即可
所引入的依赖:
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
二、远程微服务调用涉及到的组件
1、RestTemplate
RestTemplate是用来消费REST服务的,所以RestTemplate的主要方法都与REST的HTTP协议的一些方法紧密相连,例如HEAD、GET、POST、PUT、DELETE、OPTIONS等方法,这些方法在RestTemplate类对应的方法为headForHeaders(),getForObject()、postForObject()、put()、delet()等。
三、负载均衡的实现 LoadBalancer
再将RestTemplate 注入Spring 容器时,加上 @LoadBalancer 注解即可。
主要工具类LoadBlancerClient,LoadBalancerClient可以获取负载均衡的服务提供者实例信息。
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/test-load-balancer")
public String testLoadBalancer() {
ServiceInstance instance = loadBalancerClient.choose("cloud-payment-service");
return instance.getHost() + ":" + instance.getPort();
}
四、对于OpenFeign 的认识
Feign是一个声明式的HTTP客户端组件,它旨在是编写Http客户端变得更加容易。OpenFeign添加了对于Spring MVC注解的支持,同时集成了Spring Cloud LoadBalancer和Spring Cloud CircuitBreaker,在使用Feign时,提供负载均衡和熔断降级的功能。
五、微服务容错 Resilience4j
一般微服务提供了四种手段实现容错
- 隔离
线程池隔离、信号量隔离 - 熔断
CircuitBreaker,三种状态之间的转换 Closed 、Open、HalfOpen - 降级
停止一些不重要的服务的功能,让出内存和资源去处理一些重要的服务 - 限流
限制规定时间的访问次数
涉及到的算法:
漏桶算法、令牌桶算法、固定时间窗口算法、移动时间窗口算法
4.2.1 Resilience4j简介
Netflix的Hystrix微服务容错库已经停止更新,官方推荐使用Resilience4j代替Hystrix,或者使用Spring Cloud Alibaba的Sentinel组件。
Resilience4j是受到Netflix Hystrix的启发,为Java8和函数式编程所设计的轻量级容错框架。整个框架只是使用了Varr的库,不需要引入其他的外部依赖。与此相比,Netflix Hystrix对Archaius具有编译依赖,而Archaius需要更多的外部依赖,例如Guava和Apache Commons Configuration。
Resilience4j提供了提供了一组高阶函数(装饰器),包括断路器,限流器,重试机制,隔离机制。你可以使用其中的一个或多个装饰器对函数式接口,lambda表达式或方法引用进行装饰。这么做的优点是你可以选择所需要的装饰器进行装饰。
在使用Resilience4j的过程中,不需要引入所有的依赖,只引入需要的依赖即可。
核心模块
● resilience4j-circuitbreaker: 熔断
● resilience4j-ratelimiter: 限流
● resilience4j-bulkhead: 隔离
● resilience4j-retry: 自动重试
● resilience4j-cache: 结果缓存
● resilience4j-timelimiter: 超时处理
六 、微服务网关
第三章我们介绍了通过Spring Cloud LoadBalancer实现了微服务之间的调用和负载均衡,以及使用Spring Cloud OpenFeign声明式调用,那我们的各种微服务又要如何提供给外部应用调用呢?
当然,因为是REST API接口,外部客户端直接调用各个微服务是没有问题的。但出于种种原因,这并不是一个好的选择。让客户端直接与各个微服务通讯,会存在以下几个问题。
● 客户端会多次请求不同的微服务,增加了客户端的复杂性。
● 存在跨域请求,在一定场景下处理会变得相对比较复杂。
● 实现认证复杂,每个微服务都需要独立认证。
● 难以重构,项目迭代可能导致微服务重新划分。如果客户端直接与微服务通讯,那么重构将会很难实施。
● 如果某些微服务使用了防火墙、浏览器不友好的协议,直接访问会有一定困难。
面对类似上面的问题,我们要如何解决呢?答案就是:服务网关!在微服务系统中微服务资源一般不直接暴露给我外部客户端访问,这样做的好处是将内部服务隐藏起来,从而解决上述问题。
网关有很多重要的意义,具体体现在下面几个方面。
● 网关可以做一些身份认证、权限管理、防止非法请求操作服务等,对服务起一定保护作用。
● 网关将所有微服务统一管理,对外统一暴露,外界系统不需要知道微服务架构个服务相互调用的复杂性,同时也避免了内部服务一些敏感信息泄露问题。
● 易于监控。可在微服务网关收集监控数据并将其推送到外部系统进行分析。
● 客户端只跟服务网关打交道,减少了客户端与各个微服务之间的交互次数。
● 多渠道支持,可以根据不同客户端(WEB端、移动端、桌面端…)提供不同的API服务网关。
● 网关可以用来做流量监控。在高并发下,对服务限流、降级。
● 网关把服务从内部分离出来,方便测试。
微服务网关能够实现,路由、负载均衡等多种功能。类似Nginx,反向代理的功能。在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的URL,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,在API网关中进行权限控制,同时API网关将请求以负载均衡的方式发送给后端服务
Spring Cloud Gateway 简介
SpringCloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。 SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。 Spring Cloud Gateway 的目标,不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。 注意:Spring Cloud Gateway 底层使用了高性能的通信框架Netty。
主要涉及到三个部分:
1)Filter(过滤器):
和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对下游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的实例。
(2)Route(路由):
网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。
(3)Predicate(断言):
这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。
原理图:
统一跨域访问问题
跨域请求就是指:当前发起请求的域与该请求指向的资源所在的域不一样。这里的域指的是这样的一个概念:我们认为若协议 + 域名 + 端口号均相同,那么就是同域。
举个例子:假如一个域名为aaa.cn的网站,它发起一个资源路径为aaa.cn/books/getBookInfo的 Ajax 请求,那么这个请求是同域的,因为资源路径的协议、域名以及端口号与当前域一致(例子中协议名默认为http,端口号默认为80)。但是,如果发起一个资源路径为bbb.com/pay/purchase的 Ajax 请求,那么这个请求就是跨域请求,因为域不一致,与此同时由于安全问题,这种请求会受到同源策略限制
通常的两种解决方式:
- 使用注解 @CrossOrigin
- 使用Spring Cloud Gateway 的配置方式
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origin-patterns: "*" # spring boot2.4配置
# allowed-origins: "*"
allowed-headers: "*"
allow-credentials: true
allowed-methods:
- GET
- POST
- DELETE
- PUT
- OPTION
七、 Spring Cloud Config 配置中心组件
1. 如何配置
- 使用Config Server 组件(在Spring Cloud Config 下)
- 在启动类引入注解@EnableConfigServer
- 在配置文件中配置
server:
port: 9006
spring:
application:
name: cloud-config
cloud:
config:
server:
git:
uri: #仓库地址
search-paths: config
default-label: master
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9004/eureka
- 创建自己的配置仓库(在第三 步之前创建)
2. 自动刷新
- 安装Rabbitmq,并启动
- 在配置中心服务端引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 在application.yml中配置连接RabbitMQ,同时配置暴露/actuator/bus-refresh端点,代码如下
spring:
rabbitmq:
host: 服务器地址
port: 5672
username: rabbitmq 账号
password: 密码
management:
endpoints:
web:
exposure:
include: bus-refresh
endpoint:
bus-refresh:
enabled: true
- 配置客户端,引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 在application.yml中配置连接RabbitMQ
spring:
application:
name: cloud-payment-service
rabbitmq:
host: rabbitmq服务主机地址
port: 5672
username: guest
password: guest
- 添加注解刷新更改的配置 @RefreshScope
- 在修改后,需先要使用 POST请求给 (配置中心地址/actuator/busrefresh) 地址发送请求后才能自动更新。(只有post请求才能)