Spring Cloud 知识归纳

Spring Cloud 知识归纳


前言

在Spring Cloud 中涉及到非常多的组件,如Eureka 注册中心、,远程调用、负载均衡、微服务容错机制、微服务网关的配置、微服务链路追踪等,这些组件版本多,并且更新迭代比较快,对此对其中涉及到的一些关键插件及原理做些详细总结。

一、微服务的注册和发现 Eureka

如何配置一个微服务注册组件??

  1. 使用Spring Initializar 构建项目,主要在Spring Cloud Discovery中选择 Eureka Server组件,(lombok 和 DevToos 可选可不选),然后构建项目即可。
  2. 在启动类需使用注解 @Enable Eureka Server
  3. 配置文件的配置
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
  1. 启动测试即可

所引入的依赖:

<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

一般微服务提供了四种手段实现容错

  1. 隔离
    线程池隔离、信号量隔离
  2. 熔断
    CircuitBreaker,三种状态之间的转换 Closed 、Open、HalfOpen
  3. 降级
    停止一些不重要的服务的功能,让出内存和资源去处理一些重要的服务
  4. 限流
    限制规定时间的访问次数
    涉及到的算法:
    漏桶算法、令牌桶算法、固定时间窗口算法、移动时间窗口算法

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 请求,那么这个请求就是跨域请求,因为域不一致,与此同时由于安全问题,这种请求会受到同源策略限制

通常的两种解决方式:

  1. 使用注解 @CrossOrigin
  2. 使用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. 如何配置

  1. 使用Config Server 组件(在Spring Cloud Config 下)
  2. 在启动类引入注解@EnableConfigServer
  3. 在配置文件中配置
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

  1. 创建自己的配置仓库(在第三 步之前创建)

2. 自动刷新

  1. 安装Rabbitmq,并启动
  2. 在配置中心服务端引入依赖
<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>

  1. 在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  
  1. 配置客户端,引入依赖
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
 </dependency>
  1. 在application.yml中配置连接RabbitMQ
spring:
  application:
    name: cloud-payment-service
  rabbitmq:
    host: rabbitmq服务主机地址
    port: 5672
    username: guest
    password: guest
  1. 添加注解刷新更改的配置 @RefreshScope
  2. 在修改后,需先要使用 POST请求给 (配置中心地址/actuator/busrefresh) 地址发送请求后才能自动更新。(只有post请求才能)

猜你喜欢

转载自blog.csdn.net/CXgeng/article/details/123092553