分布式事务——9种解决方案的原理与分类

目录

  • 一、概要
    • 1. 分布式事务的概念
    • 2. 分布式事务解决方案分类
  • 二、常见的分布式事务解决方案
    • 1. 基础的 2PC(二阶段提交)
      • 1.1 核心思想
      • 1.2 简介
      • 1.3 主要特点
        • 1.3.1 优点
        • 1.3.2 缺点
    • 2. 基础的 3PC(三阶段提交)
      • 2.1 核心思想
      • 2.2 简介
      • 2.3 主要特点
        • 2.3.1 优点
        • 2.3.2 缺点
    • 3. Seata - XA
      • 3.1 核心思想
      • 3.2 简介
      • 3.3 主要特点
        • 3.3.1 优点
        • 3.3.2 缺点
        • 3.3.3 适用场景
    • 4. Seata - AT
      • 4.1 核心思想
      • 4.2 简介
      • 4.3 主要特点
        • 4.3.1 优点
        • 4.3.2 缺点
        • 4.3.3 适用场景
    • 5. Seata - TCC
      • 5.1 核心思想
      • 5.2 简介
      • 5.3 主要特点
        • 5.3.1 优点
        • 5.3.2 缺点
        • 5.3.3 适用场景
    • 6. Seata - SAGA
      • 6.1 核心思想
      • 6.2 简介
      • 6.3 主要特点
        • 6.3.1 优点
        • 6.3.2 缺点
        • 6.3.3 适用场景
    • 7. 本地消息表
      • 7.1 核心思想
      • 7.2 简介
      • 7.3 主要特点
        • 7.3.1 优点
        • 7.3.2 缺点
        • 7.3.3 适用场景
    • 8. RocketMQ 事务消息
      • 8.1 核心思想
      • 8.2 简介
      • 8.3 主要特点
        • 8.3.1 优点
        • 8.3.2 缺点
        • 8.3.3 适用场景
    • 9. 最大努力通知
      • 9.1 核心思想
      • 9.2 简介
      • 9.3 主要特点
        • 9.3.1 优点
        • 9.3.2 缺点
        • 9.3.3 适用场景
  • 三、总结
    • 1. 分布式事务解决方案的对比
    • 2. 使用分布式事务中间件的弊端

一、概要

1. 分布式事务的概念

官话: 分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于分布式系统的不同节点之上。简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成成功,要么全部失败。

白话: 本质上来说,分布式事务就是为了保证分散在各处的数据之间的一致性。

2. 分布式事务解决方案分类

分布式是否要考虑的第一个问题 —— 是否允许回滚:

  • 若不允许回滚,则事务必须执行成功,不得执行失败,因此只能采用异步通知型策略,且需要设计重试幂等
  • 若允许回滚,则需要考虑第二个问题 —— 是否要加锁:
    • 若要加锁,则事务为刚性事务(CP - 强一致性)
    • 若不加锁,则事务为柔性事务(AP - 最终一致性),且只能采用同步补偿策略

分布式事务的分类
可以通过图表的方式更加清晰地划分各种不同的分布式事务解决方案和它们的设计思想

分布式事务的分类图
接下来开始详细讲解这 9 种不同分布式事务解决方案的设计思想和优缺点。

二、常见的分布式事务解决方案

1. 基础的 2PC(二阶段提交)

1.1 核心思想

对分布式事务最暴力的做法就是让所有参与者直接执行并提交本地事务,也就是一阶段提交(1PC)。
但是这样会导致事务失去回滚能力,各个参与者之间无法进行协同,极可能出现数据不一致的问题。
当然,也可以选择放弃事务的回滚能力,要求事务必须执行成功,此时即为异步通知型事务,也即某种意义上的 1PC 模式。

为了给予分布式事务中的各个参与者协调与回滚的能力,自然地提出二阶段提交的方案:

各个参与者先执行而不提交,若所有参与者都执行成功则提交,若有某个参与者执行失败则其他参与者随之回滚。

为了让各个参与者(资源管理器)之间可以做到同步,需要一个中心节点进行统一调度,也就是事务管理器。

1.2 简介

基础的 2PC

  1. Prepare 阶段:
    事务管理器给每个资源管理器发送 prepare 消息,资源管理器判断是否可以执行事务。
    若可以执行,则开启本地事务,将事务写入本地的 redo log 和 undo log,但是不提交,然后返回成功;
    若不可以执行,则返回失败。
  2. Commit 阶段:
    若事务管理器没有收到任何资源管理器的失败反馈,则给所有资源管理器发送 commit 消息;
    若事务管理器收到了部分资源管理器的失败反馈,则给所有资源管理器发送 rollback 消息。
    资源管理器根据收到的消息执行本地事务的 commit 或 rollback。

1.3 主要特点

1.3.1 优点
  • 灵活性:相比于不允许回滚的分布式事务解决方案,能够允许事务的执行失败,因而灵活度更高。
1.3.2 缺点
  • 并发性能: 很低,在提交前,数据库中的记录是被排它锁独占的,因此并发性能会很低。
  • 稳定性: 如果事务管理器发送故障,RM 无法收到 TM 下达的提交命令,则未提交的数据就会长时间被锁。而此时,其他需要访问被锁数据的线程就会因无法访问而进入阻塞,随着阻塞线程越来越多,系统可能会崩溃。

核心的问题就在于对提交前数据的加锁,既导致了并发性能低的问题,也导致了线程阻塞的问题。
能不能不加锁?或能不能减少加锁时间?大部分允许回滚的改进方案都是基于这两个方面进行设计的。

2. 基础的 3PC(三阶段提交)

2.1 核心思想

3PC 模式试图通过减少加锁时间改进 2PC 模式。
为了解决 2PC 模式存在的问题,一个自然的想法就是引入超时机制,即资源管理器设等待超时时间,等待过久就自动提交或回滚,从而防止资源长期被锁导致的并发问题和线程阻塞问题。
然而,关键的问题在于在等待超时后 RM 该如何进行决策?是应该默认提交还是默认回滚?
如果不能做出可靠的决策,直接给 2PC 添加超时机制的简单做法极有可能导致数据不一致的问题。

为此,考虑在 2PC 模式的 prepare 阶段前加一个阶段,用于帮助超时后的默认操作进行决策。

2.2 简介

基础的 3PC

  1. CanCommit 阶段(新增阶段):
    事务管理器询问每个资源管理器是否可以执行事务。
    若可以执行,则资源管理器返回 Yes;若不可以执行,则资源管理器返回 No。
  2. PreCommit 阶段(2PC 的 Prepare 阶段):
    若事务管理器收到的所有回复均为 Yes,则向所有资源管理器发送 PreCommit 消息;
    若事务管理器收到的部分回复为 No,则向所有资源管理器发送 Abort 消息。
    若资源管理器收到 PreCommit 消息,则执行事务但不提交;若资源管理器收到 Abort 消息,则中断事务。

若某 RM 等待超时,则选择中断本地事务。分如下两种情况讨论。

  • 实际上 TM 发送了 PreCommit 消息,但是该 RM 已中断,其他 RM 也无法执行 DoCommit
    阶段,也就无法提交本地事务,因此全局事务失败,不会发生数据不一致。
  • 实际上 TM 发送了 Abort 消息,则该 RM 执行的中断是正确的操作,全局事务本应失败,保证了数据一致。
  1. DoCommit 阶段(2PC 的 Commit 阶段):
    若事务管理器收到了所有资源管理器在 PreCommit 阶段返回的成功 ack,则向它们发送 doCommit 消息;
    若事务管理器收到了某个资源管理器在 PreCommit 阶段返回的失败 ack,则向它们发送 rollback 消息。
    资源管理器根据收到的消息执行本地事务的 commit 或 rollback。

若某 RM 等待超时,则选择提交本地事务。因为全局事务可以执行到 DoCommit 阶段,是因为在 CanCommit 阶段所有 RM 都回应了 Yes(可以执行),因此可以认为全局事务大概率会执行成功,所以选择提交本地事务,可以大概率保证数据一致性。

2.3 主要特点

2.3.1 优点
  • 并发性能: 优于 2PC 模式,有效缓解了 2PC 模式中由于资源长期被锁而产生的并发问题和线程阻塞问题。
2.3.2 缺点
  • 数据一致性: 不能绝对保证,3PC 模式通过添加一个 CanCommit 阶段来判断在 DoCommit 阶段等待超时的情况下应该如何决策。虽然相比于直接引入超时机制的 2PC 模式,能够更大概率地保证数据一致性,但是并不能绝对地保证数据一致性

3. Seata - XA

3.1 核心思想

直接基于数据库的 XA 协议来忠实的实现 2PC(二阶段提交)。

3.2 简介

  • 第一阶段(prepare): 所有 RM 准备执行事务并锁住所需的资源,然后各个 RM 向 TM 报告是否 ready。
  • 第二阶段(commit 或 rollback): 如果所有 RM 都是 ready ,则 TM 向所有参与者发送 commit 命令;如果有参与者 RM 不是 ready,则 TM 向所有参与者发送 rollback 命令。

Seata - XA

3.3 主要特点

3.3.1 优点
  • 使用难度: 非常简单,因为是基于数据库自带特性实现,无需改动任何数据库表,也无需开发任何额外代码。
  • 数据一致性: 强一致性,不会存在数据不一致的中间状态,因为是 CP 模式,放弃了可用性 A。
3.3.2 缺点
  • 并发性能: 很低,因为会长时间锁资源,使其他线程被阻塞,而且各个 RM 之间会产生短板效应,所有 RM 都要锁资源并等待最慢的 RM。
3.3.3 适用场景

并发量低,对数据的一致性要求很高,对中间结果较敏感的业务场景。

4. Seata - AT

4.1 核心思想

AT 是 Automatic Transaction 的缩写,因为它能够自动完成事务的提交与回滚操作,不需要额外的代码开发。

其实现自动提交与回滚的方式如下:
TM 和 RM 所有数据库里都要额外加一张表 UNDO_LOG,自动生成并存储所有 SQL 的逆向 SQL 语句。

收到 TC 的分支提交,就删除 UNDO_LOG;收到 TC 的分支回滚,就执行 UNDO_LOG 中存储的逆向 SQL 语句。

本质上,Seata - AT 是通过补偿的方式回滚事务(同步补偿型),从而避免数据的加锁。

4.2 简介

执行本地业务和保存 redo/undo log 在同一个本地事务中,从而保证事务最终无论是 commit 还是 rollback 都必定能够执行。
第一阶段执行全部主要逻辑,第二阶段主要做回滚或日志清理。
仍然属于二阶段提交,只是以数据库加表为代价,自己模拟 MySQL 的 undo log 用于事务的回滚,从而避免加锁。
Seata - AT

4.3 主要特点

4.3.1 优点
  • 并发性能: 较高,因为本质上是同步补偿型事务,所以不用长时间锁定资源。
  • 使用难度: 简单,因为是靠 Seata 自己解析生成反向 SQL 并回滚,无需额外的代码开发,只需添加数据库表。
4.3.2 缺点
  • 数据一致性: 会存在数据不一致的中间状态,因为是保障最终一致性的柔性事务(AP),放弃了数据的强一致性,所以若事务需要回滚,则在补偿前会存在数据不一致的中间状态。
  • 业务侵入度: 少量,因为所有数据库都需要额外添加一个 UNDO_LOG 表。
4.3.3 适用场景

高并发,允许数据出现短时不一致的业务场景。

5. Seata - TCC

5.1 核心思想

TCC 是 Try、Confirm、Cancel 三个单子的首字母缩写,本质上是二阶段模式(Confirm、Cancel 在二阶段二选一)
设计理念上希望 90% 的事在 T 阶段(第一阶段)做完,CC 阶段(第二阶段)只做简单操作。
然而,TCC 模式可能需要改动数据库表,还需要自己额外编写 3 个接口,以实现其复杂逻辑。

5.2 简介

  • Try 阶段: 尝试执行,完成所有业务检查,预留所需的业务资源。
  • Confirm 阶段: 确认执行,真正执行业务,不需要再进行业务检查,直接使用 Try 阶段预留的业务资源(Confirm 失败后需要进行重试,因此 Confirm 操作要有幂等设计)。
  • Cancel 阶段: 取消执行,释放 Try 阶段预留的业务资源(Cancel 操作也要有幂等设计)。
    Seata - TCC

5.3 主要特点

5.3.1 优点
  • 并发性能: 高,因为在数据库中额外存储准备状态的数据,不用长时间锁定资源。
  • 灵活性: 高,各个分布式节点可以混用各种不同数据库,因为 Try、Confirm 和 Cancel 操作的具体逻辑都是自己实现。
5.3.2 缺点
  • 数据一致性: 存在数据不一致的中间状态,因为是保障最终一致性的柔性事务(AP),放弃了数据的强一致性。
  • 使用难度: 非常困难,TCC 模式中,Seata 只负责全局事务的提交与回滚指令,具体的提交与回滚操作全部需要开发人员自己实现,从而产生大量额外工作。
  • 业务侵入度: 高,因为可能涉及到数据库表的改动,自定义的 Confirm 和 Cancel 操作也容易对业务逻辑造成影响。
5.3.3 适用场景

高并发,允许数据出现短时不一致的业务场景。

6. Seata - SAGA

6.1 核心思想

考虑需要与外部第三方进行交互的事务,例如:调用支付宝支付接口 -> 出库失败 -> 调用支付宝退款接口
此时无法对外部系统的内部进行操作,只能通过接口调用进行交互,因此给每个操作实现一个逆向操作,这样就可以通过调用第三方的逆向操作接口来进行回滚。

6.2 简介

给每个操作实现一个逆向操作,通过逆向操作接口来进行回滚。
将长事务拆分为多个本地短事务,由事务管理器协调。如果某个步骤失败,则根据相反的顺序依次调用补偿操作
本质上是同步补偿型的二阶段模式。
Seata - SAGA

6.3 主要特点

6.3.1 优点
  • 并发性能: 较高,因为无需对资源加锁,而是直接提交本地短事务,若需回滚则执行逆向操作。
6.3.2 缺点
  • 数据一致性: 存在数据不一致的中间状态,因为是保障最终一致性的柔性事务(AP),放弃了数据的强一致性。
  • 使用难度: 困难,因为本地短事务的提交操作和逆向补偿操作都需要开发者自己实现。
6.3.3 适用场景

需要与外部第三方进行交互,只能通过接口调用进行事务的回滚操作的场景。

异步通知型方案:可靠消息 VS 最大努力通知
都是异步通知型,区别在于消息的发送方和接收方谁来保证消息必定被传达。

  • 可靠消息:由发送方保证。
  • 最大努力通知:由接收方保证。

可靠消息的两个关键要求:

  1. 事务发起方一定能够将消息成功发送出去(让事务发起方的本地事务与能够消息协同)
  2. 事务参与方一定能够成功接收到消息(让事务参与方的本地事务与能够消息协同) 为了满足可靠消息的两个要求,必须有一个节点负责落库并维护消息, 由事务发起方维护即为本地消息表,由消息中间件维护即为 MQ 事务消息。

7. 本地消息表

7.1 核心思想

通过让事务发起方落库并维护消息的方式,满足可靠消息模式的两个关键要求。

  • 要求 1: 将本地消息表的落库与发起方的本地事务放入同一个本地事务中,从而保证发起方本地事务的执行成功与本地消息的落库成功保持原子性
  • 要求 2: 本地消息表维护消息的状态,对于“未完成”状态的消息,不断重试发送,直到收到参与方对该消息的回执,从而保证消息必定能够被参与方成功接收

7.2 简介

  • 写业务数据和写消息数据在一个本地事务中,从而保证了业务操作和发送消息的原子性。
  • 生产者定时扫描本地消息表,将未删除的消息进行重发,从而保证所有消息都会发送给 MQ。
  • 生产者收到 MQ 的回执 ACK 之后删除本地消息表中的对应消息,从而保证所有消息都被 MQ 成功接收。
  • MQ 会将未能成功发送给消费者的消息重新发送,从而保证所有消息都会发送给消费者。

本地消息表

7.3 主要特点

7.3.1 优点
  • 灵活性: 不依赖任何分布式事务中间件,完全依靠开发者自己实现的可靠消息模式。
7.3.2 缺点
  • 使用难度: 中等,需要在数据库中添加本地消息表,并实现其增删改查和定时扫码重发、回执接收等功能。
  • 数据一致性: 存在数据不一致的中间状态,因为是保障最终一致性的柔性事务(AP),放弃了数据的强一致性。
  • 业务入侵度: 较高,容易与业务耦合,不利于扩展和维护,难以实现通用。
7.3.3 适用场景

可以接受异步通知型方案,不希望依赖分布式事务中间件的业务场景。

8. RocketMQ 事务消息

8.1 核心思想

通过让消息中间件落库并维护消息的方式,满足可靠消息模式的两个关键要求。

  • 要求 1: 发起方的本地事务执行前 MQ 落库半消息,发起方的本地事务执行成功则 MQ 将半消息投递到参与方,发起方的本地事务执行失败则 MQ 将半消息丢弃,从而保证发起方本地事务的执行成功与本地消息的发送成功保持原子性
  • 要求 2: 由消息中间件对“未完成”的消息进行重试,直到收到参与方的回执,从而保证消息必定能够被参与方成功接收

8.2 简介

  • MQ 定期回查每个未 commit 或 rollback 的半消息对应的生产者的事务状态,从而保证生产者方的本地事务必有一个终态。
  • 消费者完成本地事务后需要将 MQ 中对应的消息标记为已消费,从而保证消费者必定完成每个消息对应的事务。

RocketMQ 事务消息
因此,所以使用 RocketMQ 的事务消息需要自己实现两个方法:

  • 执行本地事务的方法:在发起方的本地事务的末尾需要给 MQ 发 commit / rollback 的消息。
  • 查询本地事务状态的方法:提供给 MQ,用于对发起方的本地事务状态进行回查。

8.3 主要特点

8.3.1 优点
  • 业务侵入度: 业务系统与消息系统的耦合度明显低于本地消息表模式。
  • 使用难度: 比较简单,只需实现本地事务的执行与查询两个方法,消息的维护由中间件负责。
8.3.2 缺点
  • 灵活性: 需要依赖消息中间件。
  • 数据一致性: 存在数据不一致的中间状态,因为是保障最终一致性的柔性事务(AP),放弃了数据的强一致性。
8.3.3 适用场景

可以接受异步通知型方案,对达到最终一致性的时间敏感度较低的业务场景。

9. 最大努力通知

9.1 核心思想

与可靠消息模式相反,最大努力通知模式由接收方保证消息必定被传达
事务发起方只负责“尽最大努力”通知事务参与方,但是并不保证消息的成功送达,事务参与方需要主动调用消息校对接口来确保事务主动方的消息被成功接收。

9.2 简介

最大努力通知

9.3 主要特点

9.3.1 优点
  • 业务侵入度: 较低,事务主动方只需提供一个消息校对接口。
9.3.2 缺点
  • 数据一致性: 存在数据不一致的中间状态,因为是保障最终一致性的柔性事务(AP),放弃了数据的强一致性。
  • 使用难度: 中等,需要额外的定期校验机制对数据进行兜底,保证数据的最终一致性。
9.3.3 适用场景

跨平台、跨企业的系统间业务交互,外部系统网络环境复杂、不可信,对达到最终一致性的时间敏感度较低的业务场景。如充值平台与运营商、支付对接、商户通知等等跨平台、跨企业的系统间业务交互场景。

三、总结

1. 分布式事务解决方案的对比

基础 2PC基础 3PCSeata - XASeata - ATSeata - TCCSeata - SAGA本地消息表事务消息最大努力通知
一致性强一致强一致强一致最终一致最终一致最终一致最终一致最终一致最终一致
并发性能很低较低很低较高较高中等中等较高
使用难度简单中等简单简单非常困难困难中等比较简单中等
业务侵入无侵入无侵入无侵入少量较高较高较低较低
优点· 允许事务的执行失败和回滚,因而灵活度更高· 业务无侵入
· 并发性能高于 2PC
· 使用简单
· 强一致性,无数据不一致的中间状态
· 使用简单
· 并发性能较高
· 并发性能较高
· 可以混用数据库
· 并发性能较高
· 便于与外部第三方进行交互
· 易于实现,使用简单
· 不依赖任何分布式事务中间件
· 对业务侵入较少
· 通过消息中间件解耦,下游事务异步化
· 对业务侵入较少
缺点· 稳定性差,容易造成大量线程阻塞· 无法绝对保证数据一致性· 并发性能很低,会长时间锁资源· 最终一致性,会存在数据不一致的中间状态
· 有少量的业务侵入性
· 最终一致性,会存在数据不一致的中间状态
· 使用难度高,会带来大量额外工作
· 业务侵入度高
· 最终一致性,会存在数据不一致的中间状态
· 使用难度较高,会带来额外的开发工作
· 最终一致性,会存在数据不一致的中间状态
· 容易与业务耦合,难以实现通用
· 最终一致性,会存在数据不一致的中间状态
· 需要依赖消息中间件。
· 最终一致性,会存在数据不一致的中间状态
· 需要额外的定期校验机制对数据进行兜底
适用业务· 要求强一致性
· 短事务
· 并发量低
· 要求强一致性
· 短事务
· 并发量低
· 要求强一致性
· 短事务
· 并发量低
· 并发量高
· 允许出现短时间的数据不一致
· 并发量高
· 允许出现短时间的数据不一致
· 并发量高
· 允许出现短时间的数据不一致
· 需要与外部第三方进行交互
· 可以接受异步通知型方案
· 允许出现短时间的数据不一致
· 不希望依赖分布式事务中间件
· 可以接受异步通知型方案
· 允许出现短时间的数据不一致
· 允许出现短时间的数据不一致
· 跨平台、跨企业的系统间业务交互
· 外部系统网络环境复杂、不可信

2. 使用分布式事务中间件的弊端

  • 引入分布式事务中间件会造成系统大规模耦合。
  • TC(事务协调者)作为基础设施却需要对外部的 TM(事务管理器)暴露,一定程度上违背了微服务的理念。
  • 带来了额外的学习成本与开发成本,提高了开发者的使用门槛,如果用不好反而会带来更多棘手的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/637421.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【系统架构师】-案例篇(十五)SOA、微服务与数据库

1、可复用构件应具备哪些属性 可用性:构件必须易于理解和使用。 质量:构件及其变形必须能正确工作。 适应性:构件应该易于通过参数化等方式在不同语境中进行配置。 可移植性:构件应能在不同的硬件运行平台和软件环境中工作。 可变…

# 全面解剖 消息中间件 RocketMQ-(2)

全面解剖 消息中间件 RocketMQ-(2) 一、RocketMQ – RocketMQ 各角色介绍 1、RocketMQ 各角色介绍 Producer : 消息的发送者; 举例:发信者。Consumer : 消息接收者; 举例:收信者。Broker : 暂存和传输消息; 举例:邮局。NameServer : 管理 Broker; 举例…

全网最全爬取-b站爬取弹幕+评论之js逆向与xml降本增效

🌟 ❤️ 作者:yueji0j1anke 首发于公号:剑客古月的安全屋 字数:801 阅读时间: 10min 声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及…

K-means聚类模型

目录 1.定义 2.K-means聚类模型的优点 3.K-means聚类模型的缺点 4.K-means聚类模型的应用场景 5.对K-means聚类模型未来的展望 6.小结 1.定义 什么是 K-means 聚类模型?K-means 聚类模型是一种无监督学习算法,用于将数据划分为不同的组或簇&#…

概念+bug

模型 迭代模型和增量模型 增量模型是将一个大的需求变成小的功能,然后将每个功能逐个开发几乎完整再上线。 迭代模型会上线一个基础版本,但是基础版本所有的功能都有但是非常简陋,之后再迭代优化上线。 一般都是两个一起用,不…

微服务Day7学习

文章目录 数据聚合聚合分类 自动补全DSL实现Bucket聚合DSL实现Metrics聚合RestAPI实现聚合多条件聚合对接前端接口拼音分词器自定义分词器自动补全查询实现酒店搜索框自动补全 数据同步数据同步思路分析利用mq实现mysql与elasticsearch数据同步 集群介绍搭建ES集群 数据聚合 聚…

T01.如何寻找隐藏目录usr?

当我们打开Mac自带的Shell或者另外安装的zsh等工具时,我们所在的默认目录为用户目录usr。 Mac的这个bin目录,是一个已经包含在环境变量里的目录,程序放在里面或者链接到里面就可以在终端里直接执行。Mac的usr/bin目录是不允许增删文件的&…

tomcat三级指导

版本 ./catalina.sh linux version.bat win 1.确认是否使用了tomcat管理后台 我们先找到配置文件:tomcat主目录下/conf/server.xml 可以查看到连接端口,默认为8080 然后查看manager-gui管理页面配置文件,是否设置了用户登录 配置文件…

Obsidian Git 多端同步

2023年6月,某云笔记限制了免费用户最多同时登录 2 台设备,想要增加设备数量需要付费开通会员。之后我一直想找一款合适的笔记本软件,年底尝试了Obsidian,断断续续摸索了好几天终于成功了。将那时的笔记拿来分享一下。 相关地址&am…

Java轻松转换Markdown文件到Word和PDF文档

Markdown 凭借其简洁易用的特性,成为创建和编辑纯文本文档的常用选择。但某些时候我们需要更加精致的展示效果,例如在专业分享文档或打印成离线使用的纸质版时,就需要将Markdown文件以其他固定的文档格式呈现。通过将 Markdown 转换为 Word 和…

错误代码126:加载x3daudio1_7.dll失败的几种修复方法分享

在使用电脑玩游戏或者工作的过程中,我们经常会遇到一些错误提示,其中最常见的就是“错误代码[126]:加载x3daudio1_7.dll失败,该文件缺失或损坏!”,那么,什么是x3daudio17.dll文件?它为什么会丢失&#xff1…

剪画小程序:3个方法:告诉你如何将普通的照片转换成动漫二次元风格!

Hello!亲爱的小伙伴们! 你是否还在纠结于自己的自拍太普通,每次分享到社交账号上都觉得平平无奇,引不起波澜? 假如,你和朋友们一起出去玩,大家都开心地拍着自拍。你看着自己的照片&#xff0c…

多联机分户计费控制系统

中央空调多联机分户计费控制系统,针对国内常见几种品牌的多联机空调系统实行,远程控制与计费管理。系统采用MQTT网络协议,以订阅/发布模式实行设备感知,实现对室外机、室内机的状态监测、实时故障报警、累计分摊费用的实时数据传导…

SSMP整合案例第一步 制作分析模块创建与开发业务实体类

制作分析 我们要实现一个模块的增删改查 实际开发中mybatisplus用的不多,他只能对没有外键的单表进行简单的查询 但在这个案例中我们还是选择mybatisplus开发 模块创建 我们把所有服务器都放在一起 就不用前后端分离 我们尝试用后端开发进行全栈开发 新建项目添…

C++语法|多重继承详解(一)|理解虚基类和虚继承

系列汇总讲解,请移步: C语法|虚函数与多态详细讲解系列(包含多重继承内容) 虚基类是多重继承知识上的铺垫。 首先我们需要明确抽象类和虚基类的区别: 抽象类:有纯虚函数的类 虚基类是什么呢&a…

精选ThingsBoard物联网关

Thingsboard网关BL104 ThingsBoard物联网网关是一个指可以将数据采集转发至ThingsBoard平台的物联网网关,它使用且仅使用MQTT协议与ThingsBoard平台(ThingsBoard IoT Platform)进行通讯。这个网关为ThingsBoard平台提供支持更多协议的数据收…

poi操作word模板,对原有的word修改

/*** 化工园区调查表** param templatePath* param outPath* param parkInterview*/public static String getDocx(String templatePath, String outPath, ParkInterview parkInterview){File file new File(templatePath);File file1 new File(outPath);if(!file1.exists()…

2024 年 电工杯(B题)大学生数学建模挑战赛 | 平衡膳食食谱 | 数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时,你是否曾经感到茫然无措?作为2022年美国大学生数学建模比赛的O奖得主,我为大家提供了一套优秀的解题思路,让你轻松应对各种难题。 CS团队倾注了大量时间和心血,深入挖掘解决方案。通…

怎么查看公网IP?

在网络通信中,每个设备都会被分配一个IP地址,用于在互联网上进行唯一标识和通信。公网IP是指可以被公开访问的IP地址,可以用来建立远程连接或者进行网络访问等操作。怎么查看公网IP呢?下面将介绍几种常用的方法。 使用命令行查询公…