SpringCould-Alibaba

Seata概述

什么是Seata

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务,能够保证一个业务中所有对数据库的操作要么都成功,要么都失败,来保证数据库的数据完整性

事务的4个特性:ACID特性

  • 原子性
  • 一致性
  • 隔离性
  • 永久性

Seata保证微服务远程调用业务的原子性

Seata的运行原理(AT模式)

在这里插入图片描述

Seata构成部分包含

  • 事务协调器TC
  • 事务管理器TM
  • 资源管理器RM

Seata其它模式简介

除了AT模式之外还有TCC、SAGA 和 XA 事务模式

TCC模式

简单来说,TCC模式就是自己编写代码完成事务的提交和回滚,TCC模式要求我们在每个参与事务的业务中编写一组共3个方法
(prepare\commit\rollback)

prepare:准备 commit:提交 rollback:回滚

  • prepare方法是无论事务成功与否都会运行的代码
  • commit当整体事务运行成功时运行的方法
  • rollback当整体事务运行失败是运行的方法
**优点**:虽然代码是自己写的,但是事务整体提交或回滚的机制仍然可用(仍然由TC来调度)

**缺点**:每个业务都要编写3个方法来对应,代码冗余,而且业务入侵量大

SAGA模式

SAGA模式的思想是对应每个业务逻辑层编写一个新的类,可以设置指定的业务逻辑层方法发生异常时,运行当新编写的类中的代码.

这样编写代码不影响已经编写好的业务逻辑代码,一般用于修改已经编写完成的老代码,缺点是每个事务分支都要编写一个类来回滚业务,会造成类的数量较多,开发量比较大

XA模式

支持XA协议的数据库分布式事务,使用比较少

Seata的使用

(1)生产者添加依赖

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
</dependency>
<!-- Seata完成分布式事务需要的两个相关依赖(Seata需要下面两个依赖中的资源) -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
</dependency>

(2)生产者配置yml文件

seata:
  tx-service-group: csmall_group   # 定义分组名称,一般是为了区分项目
  service:
    vgroup-mapping:
      csmall_group: default   # csmall_group组使用默认的Seata配置完成事务
    grouplist:
      default: localhost:8091  # 设置Seata所在的地址(默认端口号就是8091)

注意同一个事务必须在同一个tx-service-group中
(3)消费者添加依赖

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
</dependency>

(4)消费者配置yml文件

seata:
  tx-service-group: csmall_group   # 定义分组名称,一般是为了区分项目
  service:
    vgroup-mapping:
      csmall_group: default   # csmall_group组使用默认的Seata配置完成事务
    grouplist:
      default: localhost:8091  # 设置Seata所在的地址(默认端口号就是8091)

(5)消费者要想启动Seata非常简单,只要在启动业务的业务逻辑方法上添加专用的@GlobalTransactional注解即可
(6)依次启动seata软件=>生产者=>消费者

注意:在windows系统中运行seata可能出现不稳定的情况,重启seata即可解决

Sentinel

Sentinel下载地址:

https://github.com/alibaba/Sentinel/releases

什么是Sentinel(限流、降级)

Sentinel也是Spring Cloud Alibaba的组件
Sentinel英文翻译"哨兵\门卫"
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel使用

(1)打开Sentinel软件
(2)添加依赖

<!--  Sentinel依赖  -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

(3)配置yml文件

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 # 配置sentinel仪表台的位置
        # 执行限流的端口,每个项目唯一(别的项目(例如cart)设置的话不能再用8721)
        port: 8721 
    nacos:
      discovery:
        server-addr: localhost:8848

(4)在要限流的控制器方法前添加@SentinelResource注解

代码编写完毕,打开浏览器http://localhost:8080/,会看到下面的界面
在这里插入图片描述
用户名和密码都是sentinel

自定义限流方法

对与被限流的请求,我们可以自定义限流的处理方法,默认情况下可能不能正确给用户提示,一般情况下,对被限流的请求也要有"服务器忙请重试"或类似的提示,StockController类中@SentinelResource注解中,可以定义处理限流情况的方法:

@SentinelResource(value = "名称",blockHandler = "自定义限流方法名称")

例子:

@PostMapping("/reduce/count")
@ApiOperation("减少商品库存数")
// SentinelResource注解标记的控制器方法,会被Sentinel管理
// 在这个方法第一次运行后,可以在sentinel仪表台界面中设置限流规则
// "减少库存的方法"设置当前方法在仪表台中显示的名称
// blockHandler 指定请求被限流时运行的方法名称
@SentinelResource(value = "减少库存的方法",blockHandler = "blockError")
public JsonResult reduceCommodityCount(StockReduceCountDTO stockReduceCountDTO){
    // 调用业务逻辑层
    stockService.reduceCommodityCount(stockReduceCountDTO);
    return JsonResult.ok("商品库存减少完成!");
}

// Sentinel 自定义限流方法的定义
// 1.访问修饰符必须是public
// 2.返回值类型必须和限流的控制器方法一致
// 3.方法名称必须是限流注解中定义的blockHandler指定的方法名称
// 4.方法参数列表必须和限流的控制器方法一致,而且还要添加一个BlockException类型的参数
public JsonResult blockError(StockReduceCountDTO stockReduceCountDTO, BlockException e){
    // 限流方法一般直接返回限流信息即可
    return JsonResult.failed(ResponseCode.BAD_REQUEST,"服务器忙,请稍后再试");
}

自定义降级方法

所谓降级就是正常运行控制器方法的过程中,控制器方法发生了异常,Sentinel支持我们运行别的方法来处理异常,或运行别的业务流程处理我们也学习过处理控制器异常的统一异常处理类,和我们的降级处理有类似的地方,但是Sentinel降级方法优先级高,而且针对单一控制器方法编写StockController类中@SentinelResource注解中,可以定义处理降级情况的方法

@SentinelResource(value = "名称",blockHandler = "自定义限流方法名称",fallback = "自定义降级方法名称")

例子:

@PostMapping("/reduce/count")
@ApiOperation("减少商品库存数")
// SentinelResource注解标记的控制器方法,会被Sentinel管理
// 在这个方法第一次运行后,可以在sentinel仪表台界面中设置限流规则
// "减少库存的方法"设置当前方法在仪表台中显示的名称
// blockHandler 指定请求被限流时运行的方法名称
// fallback 指定控制器方法发生异常时,要执行的降级方法名称
@SentinelResource(value = "减少库存的方法",blockHandler = "blockError",
                    fallback = "fallbackError")
public JsonResult reduceCommodityCount(StockReduceCountDTO stockReduceCountDTO) {
    if(Math.random()<0.5){
        throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR,
                                                "抛出随机异常!");
    }
    // 调用业务逻辑层
    stockService.reduceCommodityCount(stockReduceCountDTO);
    return JsonResult.ok("商品库存减少完成!");
}

// Sentinel 自定义限流方法的定义
// 1.访问修饰符必须是public
// 2.返回值类型必须和限流的控制器方法一致
// 3.方法名称必须是限流注解中定义的blockHandler指定的方法名称
// 4.方法参数列表必须和限流的控制器方法一致,而且还要添加一个BlockException类型的参数
public JsonResult blockError(StockReduceCountDTO stockReduceCountDTO, BlockException e){
    // 限流方法一般直接返回限流信息即可
    return JsonResult.failed(ResponseCode.BAD_REQUEST,"服务器忙,请稍后再试");
}

// 这个方法是Sentinel注解中fallback指定的降级方法
// 当原定运行的控制器方法发送异常时,Sentinel会运行下面的方法
// 降级方法中,可以编写一些对正常逻辑的补救措施,使用户受到的损失最少
public JsonResult fallbackError(StockReduceCountDTO stockReduceCountDTO){
    return JsonResult.failed(ResponseCode.BAD_REQUEST,"因为运行时发生异常,服务降级");
}

SpringGateway网关

这些框架和SpringCloud Alibaba的对应关系我们要了解
Nacos对应Eureka都是注册中心
Dubbo对应Ribbon+feign都是实现微服务远程调用的组件
Sentinel对应Hystrix都是项目限流熔断降级的组件
Gateway对应Zuul都是网关项目
Gateway框架不是阿里写的,是Spring提供的

什么是网关

网关就是当前微服务项目的"统一入口"
在这里插入图片描述

网关的主要功能有:

  • 将所有请求统一由经过网关
  • 网关可以对这些请求进行检查
  • 网关方便记录所有请求的日志
  • 网关可以统一将所有请求路由到正确的模块\服务上

(1)创建一个新的模块
(2)添加依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

(3)配置yml文件

server:
  port: 9000
spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:    # gateway开始编写路由信息
        - id: gateway-shanghai
          uri: lb://shanghai
          predicates:
            - Path=/sh/**
        # routes是一个数组类型的变量,yml文件中出现"- ..."表示当前配置的是数组元素
        # 如果想访问下面数组元素的uri属性,实际结构为spring.cloud.gateway.routes[0].uri
        - id: gateway-beijing # 设置这个路由的名称,名称和项目没有任何关联,只是别和其它的路由名称重复
          # uri设置路由的目标
          # lb就是loadBalance(负载均衡)的缩写,beijing是beijing项目注册到nacos的名称
          uri: lb://beijing
          # predicates翻译为断言,断言的意思就是判断某个条件为真时,要做的事情
          predicates:
            # Path会设置当访问9000端口时如果路径以bj开头,会路由到上面uri配置的路径
            # Path就是路径断言,判断路径是否为/bj/开头,如果路径满足就会执行路由
            - Path=/bj/**
            # localhost:9000/bj/show 路由到 localhost:9001/bj/show
            # 当前配置结构找到Path=/bj/**路径为 spring.cloud.gateway.routes[0].predicates[2]

动态路由

网关项目随着微服务数量的增多gateway项目的yml文件配置会越来越多,维护的工作量也会越来越大,所以我们希望gateway能够设计一套默认情况下自动路由到每个模块的路由规则
这样的话,不管当前项目有多少个路由目标,都不需要维护yml文件了
这就是我们SpringGateway的动态路由功能
配置文件中开启即可

server:
  port: 9000
spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 默认情况gateway不开启动态路由,通过enabled: true开启动态路由
          # 路由规则是在9000端口号后面先编写路由目标项目注册到nacos的名称,再编写具体路径
          enabled: true

注意: 路由规则是在9000端口号后面先编写路由目标项目注册到nacos的名称,再编写具体路径

Gateway和SpringMvc依赖冲突问题和解决

当一起添加gateway依赖和web依赖时,默认情况下启动会报错
原因: SpringMvc框架中自带一个Tomcat服务器,而SpringGateway框架中自带一个Netty的服务器,在启动项目时,两个框架中包含的服务器都想占用相同端口,因为争夺端口号和主动权而发生冲突,导致启动服务时报错

解决: 要想能够正常启动必须在yml文件配置

spring:
  main:
    web-application-type: reactive

添加这个配置之后,会启动netty服务器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值