14.微服务SpringCloud

一、基本概念

        Spring Cloud 被称为构建分布式微服务系统的“全家桶”,它并不是某一门技术,而是一系列微服务解决方案或框架的有序集合。它将市面上成熟的、经过验证的微服务框架整合起来,并通过 Spring Boot 的思想进行再封装,屏蔽调其中复杂的配置和实现原理,最终为开发人员提供了一套简单易懂、易部署和易维护的分布式系统开发工具包。

二、版本对应

        在使用 Spring Boot + Spring Cloud 进行微服务开发时,我们需要根据项目中 Spring Boot 的版本来决定 Spring Cloud 版本,否则会出现许多意想不到的错误。Spring Boot 与 Spring Cloud 的版本对应关系如下表:

Spring Cloud Alibaba Version Spring Cloud Version Spring Boot Version
2022.0.0.0-RC* Spring Cloud 2022.0.0 3.0.0

2021.0.4.0*

Spring Cloud 2021.0.4

2.6.11

2021.0.1.0

Spring Cloud 2021.0.1

2.6.3

2021.1

Spring Cloud 2020.0.1

2.4.2

2.2.9.RELEASE*

Spring Cloud Hoxton.SR12

2.3.12.RELEASE

2.2.8.RELEASE

Spring Cloud Hoxton.SR12

2.3.12.RELEASE

2.2.7.RELEASE

Spring Cloud Hoxton.SR12

2.3.12.RELEASE

2.2.6.RELEASE

Spring Cloud Hoxton.SR9

2.3.2.RELEASE

2.1.4.RELEASE

Spring Cloud Greenwich.SR6

2.1.13.RELEASE

2.2.1.RELEASE

Spring Cloud Hoxton.SR3

2.2.5.RELEASE

2.2.0.RELEASE

Spring Cloud Hoxton.RELEASE

2.2.X.RELEASE

2.1.2.RELEASE

Spring Cloud Greenwich

2.1.X.RELEASE

三、SpringCloud Netflix

<dependencyManagement>
    <dependencies>
        <!--在主工程中使用 dependencyManagement 声明 Spring Cloud 的版本,
        这样工程内的 Module 中引入 Spring Cloud 组件依赖时,就不必在声明组件的版本信息
        保证 Spring Cloud 各个组件一致性-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR12</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

        1.Eureka:Eureka 是 Netflix 公司开发的一款开源的服务注册与发现组件。

        服务注册中心

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
server:
  port: 8080                           #该 Module 的端口号
eureka:
  instance:
    hostname: localhost                #eureka服务端的实例名称,
  client:
    register-with-eureka: false        #false表示不向注册中心注册自己。
    fetch-registry: false              #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone:                     #将自己注册到其他注册中心(集群)

        在主启动类上使用 @EnableEurekaServer 注解开启服务注册中心功能,接受其他服务的注册。

        服务提供者/消费者

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
server:
  port: 8081 #服务端口号
spring:
  application:
    name: microServiceCloudProviderDept     #微服务名称,对外暴漏的微服务名称,十分重要
eureka:
  client:
    service-url:
      defaultZone:                          ##将自己注册到其他注册中心(集群)
  instance:
    instance-id: spring-cloud-provider-8001 #自定义服务名称信息
    prefer-ip-address: true                 #显示访问路径的 ip 地址

        在主启动类上,使用 @EnableEurekaClient 注解开启 Eureka 客户端功能,将服务注册到服务注册中心。

        2.Ribbon:Netflix Ribbon 是 Netflix 公司发布的开源组件,其主要功能是提供客户端的负载均衡算法和服务调用。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
@Bean //将 RestTemplate 注入到容器中
@LoadBalanced //在客户端使用 RestTemplate 请求服务端时,开启负载均衡(Ribbon)
public RestTemplate restTemplate() {
    return new RestTemplate();
}

@Bean //切换负载均衡策略
public IRule iRule() {
    return new RandomRule();
}

        3.OpenFeign:OpenFeign 全称 Spring Cloud OpenFeign,它是 Spring 官方推出的一种声明式服务调用与负载均衡组件,且内部集成了 Ribbon,是为了替代 RestTemplete 进行远程调用。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
//服务提供者提供的服务名称,即 application.name
@FeignClient(value = "")
public interface UserService {
    //接口内部的定义与被调用服务的接口一致
}

        在主启动类上添加 @EnableFeignClients 注解开启 OpenFeign 功能。

        4.Hystrix:Spring Cloud Hystrix 是基于 Netflix 公司的开源组件 Hystrix 实现的,它提供了熔断器功能,能够有效地阻止分布式微服务系统中出现联动故障,以提高微服务系统的弹性。Spring Cloud Hystrix 具有服务降级、服务熔断、线程隔离、请求缓存、请求合并以及实时故障监控等强大功能。

        服务降级

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
//一旦该方法失败并抛出了异常信息后,会自动调用fallbackMethod指定的方法
//规定 5 秒钟以内就不报错,正常运行,超过 5 秒就报错,调用指定的方法
@HystrixCommand(fallbackMethod = "exceptionHandler",
            commandProperties =
{@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value = "5000")})

        在主启动类上添加 @EnableCircuitBreaker 注解开启功能。

        如果是客户端服务需要降级,需要在主启动类上添加 @EnableHystrix 注解,还需要配置:

feign:
  hystrix:
    enabled: true #开启客户端 hystrix

        服务熔断

@HystrixCommand(fallbackMethod = "deptCircuitBreaker_fallback", commandProperties = {
        //以下参数在 HystrixCommandProperties 类中有默认配置
        @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //是否开启熔断器
    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "1000"), //统计时间窗
        @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //统计时间窗内请求次数
        @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠时间窗口期
        @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), //在统计时间窗口期以内,请求失败率达到 60% 时进入熔断状态
})

参数 描述
metrics.rollingStats.timeInMilliseconds 统计时间窗。
circuitBreaker.sleepWindowInMilliseconds 休眠时间窗,熔断开启状态持续一段时间后,熔断器会自动进入半熔断状态,这段时间就被称为休眠窗口期。
circuitBreaker.requestVolumeThreshold 请求总数阀值。
在统计时间窗内,请求总数必须到达一定的数量级,Hystrix 才可能会将熔断器打开进入熔断开启转态,而这个请求数量级就是 请求总数阀值。Hystrix 请求总数阈值默认为 20,这就意味着在统计时间窗内,如果服务调用次数不足 20 次,即使所有的请求都调用出错,熔断器也不会打开。
circuitBreaker.errorThresholdPercentage 错误百分比阈值。
当请求总数在统计时间窗内超过了请求总数阀值,且请求调用出错率超过一定的比例,熔断器才会打开进入熔断开启转态,而这个比例就是错误百分比阈值。错误百分比阈值设置为 50,就表示错误百分比为 50%,如果服务发生了 30 次调用,其中有 15 次发生了错误,即超过了 50% 的错误百分比,这时候将熔断器就会打开。

        5.Gateway:Spring Cloud Gateway 是 Spring Cloud 团队基于 Spring 5.0、Spring Boot 2.0 和 Project Reactor 等技术开发的高性能 API 网关组件。

        网关服务不能导入spring-web 依赖。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
spring:
  cloud:
    gateway: #网关路由配置,将服务器提供的服务隐藏起来,不暴露给客户端,只给客户端暴露 API 网关的地址
      routes:
        #可配置多个路由
        - id:                           #路由id,没有固定规则,但唯一,建议与服务名对应
          uri:lb://service-name         #路由匹配后提供服务的服务名
          predicates:
            #以下是断言条件,必选全部符合条件
            - Path=                     #断言,路径匹配 注意:Path 中 P 为大写
            - Method=GET                #只能时 GET 请求时,才能访问
          filters:
            - AddRequestParameter=X-Request-Id,1024 #过滤器工厂会在匹配的请求头加上一对请求头,名称为 X-Request-Id 值为 1024
            - PrefixPath=/prefix #在请求路径前面加上 /prefix

        常用断言:

断言 示例 说明
Path - Path=/dept/list/**  当请求路径与 /dept/list/** 匹配时,该请求才能被转发到 http://localhost:8001 上。
Before - Before=2021-10-20T11:47:34.255+08:00[Asia/Shanghai] 在 2021 年 10 月 20 日 11 时 47 分 34.255 秒之前的请求,才会被转发到 http://localhost:8001 上。
After - After=2021-10-20T11:47:34.255+08:00[Asia/Shanghai] 在 2021 年 10 月 20 日 11 时 47 分 34.255 秒之后的请求,才会被转发到 http://localhost:8001 上。
Between - Between=2021-10-20T15:18:33.226+08:00[Asia/Shanghai],2021-10-20T15:23:33.226+08:00[Asia/Shanghai] 在 2021 年 10 月 20 日 15 时 18 分 33.226 秒 到 2021 年 10 月 20 日 15 时 23 分 33.226 秒之间的请求,才会被转发到 http://localhost:8001 服务器上。
Cookie - Cookie=name,c.biancheng.net 携带 Cookie 且 Cookie 的内容为 name=c.biancheng.net 的请求,才会被转发到 http://localhost:8001 上。
Header - Header=X-Request-Id,\d+ 请求头上携带属性 X-Request-Id 且属性值为整数的请求,才会被转发到 http://localhost:8001 上。
Method - Method=GET 只有 GET 请求才会被转发到 http://localhost:8001 上。

         常用过滤:

路由过滤器 描述 参数 使用示例
AddRequestHeader  拦截传入的请求,并在请求上添加一个指定的请求头参数。 name:需要添加的请求头参数的 key;
value:需要添加的请求头参数的 value。
- AddRequestHeader=my-request-header,1024
AddRequestParameter 拦截传入的请求,并在请求上添加一个指定的请求参数。 name:需要添加的请求参数的 key;
value:需要添加的请求参数的 value。
- AddRequestParameter=my-request-param,c.biancheng.net
AddResponseHeader 拦截响应,并在响应上添加一个指定的响应头参数。 name:需要添加的响应头的 key;
value:需要添加的响应头的 value。
- AddResponseHeader=my-response-header,c.biancheng.net
PrefixPath 拦截传入的请求,并在请求路径增加一个指定的前缀。  prefix:需要增加的路径前缀。 - PrefixPath=/consumer
PreserveHostHeader 转发请求时,保持客户端的 Host 信息不变,然后将它传递到提供具体服务的微服务中。 - PreserveHostHeader
RemoveRequestHeader 移除请求头中指定的参数。 name:需要移除的请求头的 key。 - RemoveRequestHeader=my-request-header
RemoveResponseHeader 移除响应头中指定的参数。 name:需要移除的响应头。 - RemoveResponseHeader=my-response-header
RemoveRequestParameter 移除指定的请求参数。 name:需要移除的请求参数。 - RemoveRequestParameter=my-request-param
RequestSize 配置请求体的大小,当请求体过大时,将会返回 413 Payload Too Large。 maxSize:请求体的大小。 - name: RequestSize
   args:
     maxSize: 5000000

        全局过滤器:

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return null;
    }
    @Override
    public int getOrder() {
        //过滤器的顺序,0 表示第一个
        return 0;
    }
}

四、SpringCloud Alibaba

<dependencyManagement>
    <dependencies>
        <!--Spring Cloud Alibaba 的版本信息-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2021.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--Spring Cloud 的版本信息-->
        <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.Nacos:Nacos 服务注册中心和配置中心的组合体,它可以替换 Eureka 作为服务注册中心,实现服务的注册与发现;还可以替换 SpringCloud Config 作为配置中心,实现配置的动态刷新。先在官网下载 Nacos Server 并运行。

        注册中心

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
spring:
  cloud:
    nacos:
      discovery:
        cluster-name: BJ #设置集群
        namespace: public #命名空间
        ephemeral: false #设置非临时实例
        server-addr: localhost:8848 #注册中心地址

        在主启动类上,使用 @EnableDiscoveryClient 注解开启 Nacos 服务发现功能。

        配置中心

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

        在 /resources 目录下,添加一个 bootstrap.yml文件:

#启动时获取远程配置
spring:
  application:
    name: book                     #应用名称
  profiles:
    active: public                 #应用环境
  cloud:
    nacos:
      config:
        file-extension: yaml        #文件名后缀
        server-addr: localhost:8848 #配置中心地址
        group:                      #配置分组

        在 Nacos 控制台新建配置文件,并进行配置,文件名:

${application.name}-${spring.profiles.active}.${file-extension}

        在 Controller 类上使用 @RefreshScope 注解实现配置的自动更新。

        集群:在 mysql 执行 conf 中的 mysql-schema.sql 文件,并在 application.properties 文件中添加数据库信息。

        2.Sentinel:Sentinel 是由阿里巴巴中间件团队开发的开源项目,是一种面向分布式微服务架构的轻量级高可用流量控制组件。先在官网下载 jar 包并运行。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
spring:
   cloud:
      sentinel:
         transport:
           #配置 Sentinel dashboard 地址
           dashboard: localhost:8080
           #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
           port: 8719

        限流:可以通过 Sentinel 控制台,直接对资源定义流控规则。

属性 说明 默认值
资源名 流控规则的作用对象。 -
阈值 流控的阈值。 -
阈值类型 流控阈值的类型,包括 QPS 或并发线程数。 QPS
针对来源 流控针对的调用来源。 default,表示不区分调用来源
流控模式 调用关系限流策略,包括直接、链路和关联。 直接
流控效果 流控效果(直接拒绝、预热、匀速排队),不支持按调用关系限流。 直接拒绝

        在服务代码中使用 @SentinelResource 注解定义资源名称,并在 blockHandler 属性指定一个限流函数或 blockHandlerClass 限流类,自定义服务限流信息。使用 @SentinelResource 注解的 blockHandler 属性时,需要注意以下事项:

  • blockHandler 函数访问范围需要是 public;
  • 返回类型需要与原方法相匹配;
  • 参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException;
  • blockHandler 函数默认需要和原方法在同一个类中,若希望使用其他类的函数,则可以指定 blockHandler 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

        熔断降级: 可以通过 Sentinel 控制台直接对资源定义熔断降级规则。

熔断策略 说明
慢调用比例
(SLOW_REQUEST_RATIO)
选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大响应时间),若请求的响应时间大于该值则统计为慢调用。
当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。
经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则再次被熔断。
异常比例 (ERROR_RATIO) 当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目且异常的比例大于阈值,则在接下来的熔断时长内请求会自动被熔断。
经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
异常数 (ERROR_COUNT) 当单位统计时长内的异常数目超过阈值之后会自动进行熔断。
经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

        规则持久化: 

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
spring:
  cloud:
    sentinel:
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId:                  #微服务名称
            groupId:                 #分组名称
            data-type: json
            rule-type: flow          #流控规则

        在 nacos 控制台添加配置:

[
    {
        "resource":"/persistent",//资源名称
        "limitApp":"default",//来源应用
        "grade":1,//阈值类型,0线程数,1QPS
        "count":1,//单机阈值
        "strategy":0,//流控模式,0表示直接,1表示关联,2表示链路
        "controlBehavior":0,//流控效果 ,0表示快速失败,1表示warm up,2表示排队等待
        "clusterMode":false //是否集群
    }
]

        3.Seata:Seata 是一个分布式事务处理框架,它是由阿里巴巴和蚂蚁金服共同开源的分布式事务解决方案,能够在微服务架构下提供高性能且简单易用的分布式事务服务。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

        在事务方法上添加 @GlobalTransactional

猜你喜欢

转载自blog.csdn.net/weixin_60466670/article/details/129009792