13. springCloud AlibabaSeata处理分布式事务

目录

一、分布式事务面试题

1.多个数据库之间如何处理分布式事务?

2.若拿出如下场景,阁下将如何应对?

3.阿里巴巴的Seata-AT模式如何做到对业务的无侵入?

4.对于分布式事务问题,你知道的解决方案有哪些?请你谈谈?

二、分布式事务问题如何产生?请先看业务

分布式事务之前:

分布式事务改变后:

三、Seata简介

Seata的发展历程:

‌官网及源码

使用

Seata的分布式交易解决方案

四、Seata工作流程简介:

分布式事务的理解:

Seata对分布式事务的协调和控制就是1+3

分布式事务的执行流程-总结:(重点)

五、各事务模式(重点)

Seata AT 模式(常用)

适用场景:

前提​

整体机制​

整体机制的理解

一阶段过程;

二阶段异常回滚:

二阶段正常提交:

写隔离

以一个示例来说明:

读隔离

工作机制示例:

一阶段​

二阶段-回滚​

二阶段-提交​

回滚日志表​

Seata TCC 模式

适用场景:

Seata Saga 模式

适用场景:

Seata XA 模式

适用场景:

六、Seata-Server2.0.0安装

1.下载地址

2.下载版本

3.各种seata参数官网参考

关注属性(详细描述见全属性)​

全属性​

公共部分​

server 端​

client 端​

4.Seata新手部署指南

5.mysql8.0数据库里面建库+建表

建库—创建seata库

建表—在seata库创建表

运行结果

6.更改配置

7.先启动Nacos2.2.3端口号8848

8.再启动seata-server-2.0.0

七、Seata案例实战-数据库和表准备(AT)

分布式事务案例—业务说明

1.创建3个业务数据库DATABASE

建库SQL

2. 按照上述3库分别建对应的undo log回滚日志表

undo_log建表sql

3.按照上述3库分别建对应业务表

t_order脚本SQL

t_account脚本SQL

t_storage脚本SQL

最终SQL(全)

建seata_order库+建t_order表+undo_log表

建seata_storage库+建t_storage 表+undo_log表

建seata_account库+建t_account 表+undo_log表

最终效果:

八、Seata系例实战-微服务编码落地实现(AT)

1.Mybaits一键生成

config.properties

generatorConfig.xml

双击执行一键生成

2.修改公共cloud-api-commons新增库存和账户两个Feign服务接口

3.新建订单Order微服务

(1).建Module

(2).改POM

(3).写YML

(4).主启动类

‌SpringBootApplication‌是一个组合注解,主要用于标记Spring Boot的主配置类,用于启动Spring Boot应用程序。它由以下三个注解组成:

(5).业务类

1).entities

2).OrderMapper

3).Service接口及实现

OrderService

OrderServiceImpl(重点)

4).Controller

4.新建库存Storage微服务

(1).建Module

(2).改POM

(3).写YML

(4).主启动类

(5).业务类

1).entities

2).StorageMapper

3).Service接口及实现

4).Controller

5.新建账户Account微服务

(1).建Module

(2).改POM

(3).写YML

(4).主启动类

(5).业务类

1).entities

2).AccountMapper

3).Service接口及实现

4).Controller

九、Seata案例实战-测试

服务启动情况

数据库初始化情况

1.正常下单

2).此时我们没有在订单模块添加@GlobalTransactional

3).正常下单,第1次

故障现象

导致原因

4).正常下单,第2次

数据库情况

 2.超时异常出错,没有@GlobalTransactional

1).添加超时方法

2).故障情况

 3.超时异常解决,添加@GlobalTransactional

前提条件

查看Seata后台:

全局事务ID

全局锁

数据回滚

业务中

回滚后

全局事务,正常扣除操作

总结


一、分布式事务面试题

1.多个数据库之间如何处理分布式事务?
2.若拿出如下场景,阁下将如何应对?
3.阿里巴巴的Seata-AT模式如何做到对业务的无侵入?
4.对于分布式事务问题,你知道的解决方案有哪些?请你谈谈?

1.多个数据库之间如何处理分布式事务?

在订单支付成功后,交易中心会调用订单中心的服务把订单状态更新,并调用物流中心的服务通知商品发货,同时还要调用积分中心的服务为用户增加相应的积分。 如何保障分布式事务一致性,成为了确保订单业务稳定运行的核心诉求之一

2.若拿出如下场景,阁下将如何应对?

冻库存:
冻结库存 ‌是指在ERP系统中, 将部分库存暂时锁定,使其不能参与正常的出库和入库操作 。这种操作通常用于防止库存被意外或错误地使用,确保在特定时间段内库存的稳定性和可用性。冻结库存的方法包括设置库存冻结、使用库存锁定功能、创建保留订单和利用批次管理‌。

3.阿里巴巴的Seata-AT模式如何做到对业务的无侵入?

4.对于分布式事务问题,你知道的解决方案有哪些?请你谈谈?

1.2PC(两阶段提交)
2.3PC(三阶段提交)
3.TCC方案
  • TCC(Try-Confirm-Cancel)又被称补偿事务
  • 类似2PC的柔性分布式解决方案,2PC改良版
4.LocalMessage本地消息表;
5.独立消息微服务+RabbitMQ/KafKa组件,实现可靠消息最终一致性方案;
6.最大努力通知方案;

二、分布式事务问题如何产生?请先看业务

上述面试问题都指向一个重要问题
一次业务操作需要 跨多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务问题。
但是
关系型数据库提供的能力是基于 单机事务的,一旦遇到分布式事务场景,就需要通过更多其他技术手段来解决问题。

分布式事务之前:

  • 单机单库没这个问题
  • 表结构的关系从1:1->1:N -> N:N

分布式事务改变后:

单体应用被拆分成微服务应用,原来的三个模块被拆分成三个独立的应用,分别使用三个独立的数据源,
业务操作需要调用三个服务来完成。
此时 每个服务自己内部的数据一致性由 本地 事务来保证,但是 全局 的数据一致性问题没法保证
结论:迫切希望提供一种分布式事务框架,解决微服务架构下的分布式事务问题。

三、Seata简介

Simple Extensible Autonomous Transaction Architecture 简单可扩展自治事务框架
Apache Seata(incubating) 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。

Seata的发展历程:

阿里巴巴作为国内最早一批进行应用分布式(微服务化)改造的企业,很早就遇到微服务架构下的分布式事务问题。
2019年1月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案:
2014 年,阿里中间件团队发布 TXC(Taobao Transaction Constructor),为集团内应用提供分布式事务服务。
2016 年,TXC 在经过产品化改造后,以 GTS(Global Transaction Service) 的身份登陆阿里云,成为当时业界唯一一款云上分布式事务产品。在阿云里的公有云、专有云解决方案中,开始服务于众多外部客户。
2019 年起,基于 TXC 和 GTS 的技术积累,阿里中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback, FESCAR),和社区一起建设这个分布式事务解决方案。
2019 年  fescar(全称fast easy commit and rollback)  被重命名为了seata(simple extensiable autonomous transaction architecture)。TXC、GTS、Fescar 以及 seata 一脉相承,为解决微服务架构下的分布式事务问题交出了一份与众不同的答卷。
‌Seata最初是阿里巴巴开发的,但现在已经捐赠给了Apache基金会,成为Apache项目的一部分。
Seata框架的理解:
  • 单个数据库只能对本身进行事务的控制, 而seata是分布式事务框架,可以对多个数据库进行全局的事务控制,保证全局事务的运行正常的框架。
  • 当事物发生超时或异常时,seata会对所管理数据库,统一进行数据回滚,保证数据的正确性。

官网及源码

官网地址: Apache Seata

使用

本地@Transactional
全局@GlobalTransactional

Seata的分布式交易解决方案

(TC→TM→RM)分别什么意思
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

四、Seata工作流程简介:

分布式事务的理解:

  • 分布式事务是由一批分支事务组成的全局事务,通常分支事务只是本地事务。
  • 纵观整个分布式事务的管理,就是全局事务ID的传递和变更,要让开发者无感知。

Seata对分布式事务的协调和控制就是1+3

1+3:1个XID+TC+TM+RM
  • 1个XID :XID是全局事务的唯一标识,它可以在服务的调用链路中传递,绑定到服务的事务上下文中。
官网3个概念(重点)
  • TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
  • TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
对TC->TM->RM的理解:
  1. TC(Transaction Coordinator)事务协调器就是Seata,负责维护全局事务和分支事务的状态,驱动全局事务提交或回滚。
  2. TM(Transaction Manager) 事务管理器标注全局@GlobalTransactional启动入口动作的微服务模块(比如订单模块),它是事务的发起者,负责定义全局事务的范围,并根据TC维护的全局事务和分支事务状态,做出开始事务、提交事务、回滚事务的决议。
  3. RM(Resource Manager)资源管理器就是mysql数据库本身,可以是多个RM,负责管理分支事务上的资源,像TC注册分支事务,汇报分支事务状态,驱动分支事务的提交和回滚。

分布式事务的执行流程-总结:重点)

三个组件相互协作, TC以Seata 服务器(Server)形式独立部署,TM和RM则是以Seata Client的形式集成在微服务中运行 流程如下
1.TM(事务管理器) 向 TC (事务协调者)申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID;
2.XID 在微服务调用链路的上下文中传播;
3.RM(资源管理器) 向 TC (事务协调者)注册分支事务,将其纳入 XID 对应全局事务的管辖;
4.TM(事务管理器) 向 TC (事务协调者)发起针对 XID 的全局提交或回滚决议;
5.TC (事务协调者) 调度 XID 下管辖的全部分支事务完成提交或回滚请求。
常用 @GlobalTransactional方式一:
一般控制3到5个本地事务,超过则使用方法嵌套的方式。
@GlobalTransactional
public void doBusiness() {
    // 本地事务
    serviceA.doSomething();
    // 本地事务
    serviceB.doSomethingElse();
}
常用 @GlobalTransactional方式二:
@GlobalTransactional
public void globalMethod() {
    // 调用另一个标记为@GlobalTransactional的方法
    nestedMethod();
    // 业务逻辑...
}
@GlobalTransactional
public void nestedMethod() {
// 业务逻辑...
}

五、各事务模式重点)

  • Seata AT 模式
  • Seata TCC 模式
  • Seata Saga 模式
  • Seata XA 模式
备注:AT模式因其简单易用和自动完成事务的特性,可能在一些基本的分布式事务场景中较为常用。然而,在复杂的业务逻辑或需要强一致性保证的场景下,TCC、SAGA或XA模式可能更受欢迎。

Seata AT 模式(常用)

AT 模式是 Seata 创新的一种非侵入式的分布式事务解决方案,Seata 在内部做了对数据库操作的代理层,我们使用 Seata AT 模式时,实际上用的是 Seata 自带的数据源代理 DataSourceProxy,Seata 在这层代理中加入了很多逻辑,比如插入回滚 undo_log 日志,检查全局锁等。
适用场景:
  • 适用场景:主要用于CRUD(创建、读取、更新、删除)操作较多的业务场景,尤其是当业务逻辑直接操作数据库,并且可以容忍短暂的数据不一致时。AT模式通过记录数据的前后镜像来实现撤销(回滚)操作,适合于大部分单纯依赖于单个数据库事务的微服务场景。
  • 优点:简单易用,不需要改动业务代码,自动完成分布式事务的提交和回滚。
  • 缺点:不适合跨多种存储资源的事务,且在高并发场景下性能可能受影响。
前提
  • 基于支持本地 ACID 事务的关系型数据库。
  • Java 应用,通过 JDBC 访问数据库。
整体机制
两阶段提交协议的演变:
  • 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
  • 二阶段:
    • 提交异步化,非常快速地完成。
    • 回滚通过一阶段的回滚日志进行反向补偿。
整体机制的理解
一阶段过程;
一阶段,Seata 会拦截“业务 SQL”,
1  解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,
2  执行“业务 SQL”更新业务数据,在业务数据更新之后,
3  其保存成“after image”,最后生成行锁。
以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。
二阶段异常回滚:
二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。
回滚方式便是用undo_log中的“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,
如果两份数据完全一致就说明没有脏写,可以还原业务数据, 如果不一致就说明有脏写,出现脏写就需要转人工处理。
二阶段正常提交:
因为“业务 SQL”在一阶段已经提交至数据库,所以Seata框架只需将 一阶段保存的快照数据和行锁删掉,完成数据清理即可。
写隔离
  • 一阶段本地事务提交前,需要确保先拿到 全局锁 。
  • 拿不到 全局锁 ,不能提交本地事务。
  • 拿 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。
以一个示例来说明:
两个全局事务 tx1 和 tx2,分别对 a 表的 m 字段进行更新操作,m 的初始值 1000。
tx1 先开始,开启本地事务,拿到本地锁,更新操作 m = 1000 - 100 = 900。本地事务提交前,先拿到该记录的  全局锁 ,本地提交释放本地锁。 tx2 后开始,开启本地事务,拿到本地锁,更新操作 m = 900 - 100 = 800。本地事务提交前,尝试拿该记录的  全局锁 ,tx1 全局提交前,该记录的全局锁被 tx1 持有,tx2 需要重试等待  全局锁 。
tx1 二阶段全局提交,释放  全局锁 。tx2 拿到  全局锁 提交本地事务。
如果 tx1 的二阶段全局回滚,则 tx1 需要重新获取该数据的本地锁,进行反向补偿的更新操作,实现分支的回滚。
此时,如果 tx2 仍在等待该数据的  全局锁,同时持有本地锁,则 tx1 的分支回滚会失败。分支的回滚会一直重试,直到 tx2 的  全局锁 等锁超时,放弃  全局锁 并回滚本地事务释放本地锁,tx1 的分支回滚最终成功。
因为整个过程  全局锁 在 tx1 结束前一直是被 tx1 持有的,所以不会发生  脏写 的问题。
读隔离
在数据库本地事务隔离级别  读已提交(Read Committed) 或以上的基础上,Seata(AT 模式)的默认全局隔离级别是  读未提交(Read Uncommitted) 。
如果应用在特定场景下,必需要求全局的  读已提交 ,目前 Seata 的方式是通过 SELECT FOR UPDATE 语句的代理。
SELECT FOR UPDATE 语句的执行会申请  全局锁 ,如果  全局锁 被其他事务持有,则释放本地锁(回滚 SELECT FOR UPDATE 语句的本地执行)并重试。这个过程中,查询是被 block 住的,直到  全局锁 拿到,即读取的相关数据是  已提交 的,才返回。
出于总体性能上的考虑,Seata 目前的方案并没有对所有 SELECT 语句都进行代理,仅针对 FOR UPDATE 的 SELECT 语句。
工作机制示例:
以一个示例来说明整个 AT 分支的工作过程。
业务表:product

Field

Type

Key

id
bigint(20)
PRI
name
varchar(100)
since
varchar(100)

AT 分支事务的业务逻辑:
update product set name = 'GTS' where name = 'TXC';

一阶段
过程:
  1. 解析 SQL:得到 SQL 的类型(UPDATE),表(product),条件(where name = 'TXC')等相关的信息。
  2. 查询前镜像:根据解析得到的条件信息,生成查询语句,定位数据。
select id, name, since from product where name = 'TXC';
得到前镜像:
id
name
since
1
TXC
2014

3.执行业务 SQL:更新这条记录的 name 为 'GTS'。

4.查询后镜像:根据前镜像的结果,通过 主键 定位数据。

select id, name, since from product where id = 1;
得到后镜像:
id
name
since
1
GTS
2014

5.插入回滚日志:把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 UNDO_LOG 表中。

{
    "branchId": 641789253,
    "undoItems": [{
        "afterImage": {
            "rows": [{
                "fields": [{
                    "name": "id",
                    "type": 4,
                    "value": 1
                }, {
                    "name": "name",
                    "type": 12,
                    "value": "GTS"
                }, {
                    "name": "since",
                    "type": 12,
                    "value": "2014"
                }]
            }],
            "tableName": "product"
        },
        "beforeImage": {
            "rows": [{
                "fields": [{
                    "name": "id",
                    "type": 4,
                    "value": 1
                }, {
                    "name": "name",
                    "type": 12,
                    "value": "TXC"
                }, {
                    "name": "since",
                    "type": 12,
                    "value": "2014"
                }]
            }],
            "tableName": "product"
        },
        "sqlType": "UPDATE"
    }],
    "xid": "xid:xxx"
}

6.提交前,向 TC 注册分支:申请 product 表中,主键值等于 1 的记录的 全局锁 。

7.本地事务提交:业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交。

8.将本地事务提交的结果上报给 TC。

二阶段-回滚

1.收到 TC 的分支回滚请求,开启一个本地事务,执行如下操作。

2.通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。

3.数据校验:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理,详细的说明在另外的文档中介绍。

4.根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句:

update product set name = 'TXC' where id = 1;

5.提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。

二阶段-提交
  1. 收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。
  2. 异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。
回滚日志表
UNDO_LOG Table:不同数据库在类型上会略有差别。
以 MySQL 为例:
Field
Type
branch_id
bigint PK
xid
varchar(100)
context
varchar(128)
rollback_info
longblob
log_status
tinyint
log_created
datetime
log_modified
datetime
-- 注意此处0.7.0+ 增加字段 context
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Seata TCC 模式

TCC 模式是 Seata 支持的一种由业务方细粒度控制的侵入式分布式事务解决方案,是继 AT 模式后第二种支持的事务模式,最早由蚂蚁金服贡献。其分布式事务模型直接作用于服务层,不依赖底层数据库,可以灵活选择业务资源的锁定粒度,减少资源锁持有时间,可扩展性好,可以说是为独立部署的 SOA 服务而设计的。
适用场景:
  • 适用场景:适用于需要显式控制事务边界的复杂业务流程,特别是在业务操作可以明确分为尝试(Try)、确认(Confirm)和取消(Cancel)三个阶段的情况下。TCC模式适合于执行时间较长,需要人工干预或第三方服务参与的分布式事务。
  • 优点:灵活性高,可以精细控制事务的每个阶段,适用于复杂的业务逻辑。
  • 缺点:需要用户显式地实现Try、Confirm、Cancel三个操作,增加了开发的复杂度。

Seata Saga 模式

Saga 模式是 SEATA 提供的长事务解决方案,在 Saga 模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。
适用场景:
  • 适用场景:适用于长事务场景,其中业务流程包含一系列的本地事务,这些本地事务需要按照一定的顺序执行。SAGA模式通过定义一系列的事务步骤和相对应的补偿操作(回滚操作)来管理事务,适合于微服务架构下的复杂业务流程。
  • 优点:适合长事务处理,可以保证分布式事务的最终一致性。
  • 缺点:需要定义每个步骤的补偿操作,对业务侵入性较高。

Seata XA 模式

XA 模式是从 1.2 版本支持的事务模式。XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准。Seata XA 模式是利用事务资源(数据库、消息服务等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务的一种事务模式。
适用场景:
  • 适用场景:适用于长事务场景,其中业务流程包含一系列的本地事务,这些本地事务需要按照一定的顺序执行。SAGA模式通过定义一系列的事务步骤和相对应的补偿操作(回滚操作)来管理事务,适合于微服务架构下的复杂业务流程。
  • 优点:适合长事务处理,可以保证分布式事务的最终一致性。
  • 缺点:需要定义每个步骤的补偿操作,对业务侵入性较高。

六、Seata-Server2.0.0安装

1.下载地址
2.下载版本
3.各种seata参数官网参考4.Seata新手部署指南
5.mysql8.0数据库里面建库+建表
6.更改配置
7.先启动Nacos2.2.3端口号8848
8.再启动seata-server-2.0.0

1.下载地址

2.下载版本

3.各种seata参数官网参考

关注属性(详细描述见全属性)
server 端
client 端
registry.type
registry.type
config.type
config.type
#store.mode=db 需要以下配置
service.vgroupMapping.my_test_tx_group
store.db.driverClassName
service.default.grouplist
store.db.url
service.disableGlobalTransaction
store.db.user
store.db.password
#store.mode=redis 需要以下配置
store.redis.host
store.redis.port
store.redis.database
store.redis.password
#store.mode=raft 需要以下配置
server.raft.group
server.raft.server-addr
server.raft.snapshot-interval
全属性
公共部分
<
key
desc
remark
change record
transport.type
socket 通信方式
TCP、UNIX_DOMAIN_SOCKET,默认 TCP
transport.server
socket 通道类型
NIO、NATIVE(根据操作系统类型和 socket 通信方式选择 KQueue 或 Epoll,注意 Windows 只支持 NIO,选择这种方式会抛出异常)
transport.threadFactory.bossThreadSize
Netty 通信模型 Boss group 线程数
默认 1
transport.threadFactory.workerThreadSize
Netty 通信模型 Worker group 线程数
可配置线程数或选择特定线程工作模式下的线程数,线程的默认工作模式有 4 种:Auto(2*CPU 核数 + 1)、Pin(CPU 核数,适用于计算密集型任务)、BusyPin(CPU 核数 + 1,适用于计算密集型且内存比较有限的场景)、Default(2*CPU 核数,适用于 IO 密集型任务),默认值为 Default 模式
transport.shutdown.wait
服务端 Netty 线程池关闭前等待服务下线时间
默认 3 秒
transport.serialization
client 和 server 通信编解码方式
seata(ByteBuf)、protobuf、kryo、hessian、fst,默认 seata
transport.compressor
client 和 server 通信数据压缩方式
none、gzip、zip、sevenz、bzip2、lz4、deflater、zstd,默认 none
1.2.0 之前:gzip
1.2.0:zip、sevenz、bzip2
1.3.0:lz4
1.4.1:deflater
1.5.1:zstd
transport.heartbeat
client 和 server 通信心跳检测开关
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值