From 376e78117c12ab4a39a95878d8724763c24bc75d Mon Sep 17 00:00:00 2001
From: zhangsan <646228430@qq.com>
Date: Tue, 27 May 2025 20:43:37 +0800
Subject: [PATCH] =?UTF-8?q?Commit=20on=202025/05/27=20=E5=91=A8=E4=BA=8C?=
=?UTF-8?q?=2020:43:37.87?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
自学/微服务.md | 211 ++++++++++++++++++++++++++++++++++++++++++++-
自学/消息队列MQ.md | 64 ++++++++++++++
2 files changed, 271 insertions(+), 4 deletions(-)
create mode 100644 自学/消息队列MQ.md
diff --git a/自学/微服务.md b/自学/微服务.md
index 4fff51a..f605d09 100644
--- a/自学/微服务.md
+++ b/自学/微服务.md
@@ -977,7 +977,7 @@ hm:
示例:购物车中的商品上限数量需动态调整。
-1)在nacos中添加配置
+**1)在nacos中添加配置**
在nacos中添加一个配置文件,将购物车的上限数量添加到配置中:
@@ -1001,7 +1001,7 @@ hm:
maxAmount: 1 # 购物车商品数量上限
```
-2)在微服务中配置
+**2)在微服务中配置**
```java
@Data
@@ -1012,7 +1012,7 @@ public class CartProperties {
}
```
-3)下次,只需改nacos中的配置文件=》发布,即可实现热更新。
+**3)下次,只需改nacos中的配置文件 =》发布,即可实现热更新。**
@@ -1156,7 +1156,7 @@ public class DynamicRouteLoader {
-## 服务保护与分布式事务
+## 服务保护
### 服务保护方案
@@ -1295,6 +1295,10 @@ feign:
触发限流或熔断后的请求不一定要直接报错,也可以返回一些默认数据或者友好提示,采用FallbackFactory,可以对远程调用的异常做处理。
+业务场景:购物车服务需要同时**openFeign**调用服务B和商品服务,现在对商务服务做了线程隔离,在高并发的时候,会疯狂抛异常,现在做个fallback让它返回默认值。
+
+
+
**步骤一**:在hm-api模块中给`ItemClient`定义降级处理类,实现`FallbackFactory`:
@@ -1343,3 +1347,202 @@ public interface ItemClient {
```
重启后,再次测试
+
+
+
+#### 熔断器
+
+
+
+
+
+
+
+## 分布式事务
+
+场景:订单服务依次调用了购物车服务和库存服务,它们各自操作不同的数据库。当清空购物车操作成功、库存扣减失败时,订单服务能捕获到异常,却无法通知已完成操作的购物车服务,导致数据不一致。虽然每个微服务内部都能保证本地事务的 ACID 特性,但跨服务调用**缺乏全局协调**,无法实现端到端的一致性。
+
+
+
+### Seeta
+
+要解决这个问题,只需引入一个统一的**事务协调者**,负责跟每个分支通信,检测状态,并统一决定全局提交或回滚。
+
+在 Seata 中,对应三大角色:
+
+- **TC(Transaction Coordinator)事务协调者**
+ 维护全局事务和各分支事务的状态,负责发起全局提交或回滚指令。
+- **TM(Transaction Manager)事务管理器**
+ 定义并启动全局事务,最后根据应用调用决定调用提交或回滚。
+- **RM(Resource Manager)资源管理器**
+ 嵌入到各微服务中,负责注册分支事务、上报执行结果,并在接到 TC 指令后执行本地提交或回滚。
+
+
+
+其中,TM 和 RM 作为客户端依赖,**直接集成到业务服务里**;TC 则是一个**独立部署的微服务**,承担全局协调的职责。这样,无论有多少分支参与,都能保证“要么都成功、要么都回滚”的一致性。
+
+
+
+### 部署TC服务
+
+1)准备数据库表
+
+seata-tc.sql 运行初始化脚本
+
+
+
+2)准备配置文件
+
+
+
+3)Docker部署
+
+```yml
+seeta-server:
+ image: seataio/seata-server:1.5.2
+ container_name: seata-server
+ restart: unless-stopped
+ depends_on:
+ - mysql
+ - nacos
+ environment:
+ # 指定 Seata 注册中心和配置中心地址
+ - SEATA_IP=192.168.0.107 # IDEA 可以访问到的宿主机 IP
+ - SEATA_SERVICE_PORT=17099
+ - SEATA_CONFIG_TYPE=file
+ # 可视情况再加:SEATA_NACOS_SERVER_ADDR=nacos:8848
+ networks:
+ - hmall-net
+ ports:
+ - "17099:7099" # TC 服务端口
+ - "8099:8099" # 服务管理端口(Console)
+ volumes:
+ - ./seata:/seata-server/resources
+```
+
+
+
+### 微服务集成Seata
+
+1)引入依赖
+
+```xml
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-config
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-bootstrap
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-seata
+
+```
+
+2)在nacos上添加一个共享的seata配置,命名为`shared-seata.yaml`,你在bootstrap中引入该配置即可:
+
+```yaml
+seata:
+ registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址
+ type: nacos # 注册中心类型 nacos
+ nacos:
+ server-addr: 192.168.0.107:8848 # 替换为自己的nacos地址
+ namespace: "" # namespace,默认为空
+ group: DEFAULT_GROUP # 分组,默认是DEFAULT_GROUP
+ application: seata-server # seata服务名称
+ username: nacos
+ password: nacos
+ tx-service-group: hmall # 事务组名称
+ service:
+ vgroup-mapping: # 事务组与tc集群的映射关系
+ hmall: "default"
+```
+
+这段配置是告诉你的微服务如何去「找到并使用」Seata 的 TC(Transaction Coordinator)服务,以便在本地发起、提交或回滚分布式事务。
+
+
+
+### XA模式
+
+
+
+`XA`模式的优点是什么?
+
+- 事务的**强一致性**,满足ACID原则
+- 常用数据库都支持,实现简单,并且没有代码侵入
+
+`XA`模式的缺点是什么?
+
+- 因为**一阶段需要锁定数据库资源,等待二阶段结束才释放**,性能较差
+- 依赖关系型数据库实现事务
+
+
+
+**实现方式**
+
+1)在Nacos中的共享shared-seata.yaml配置文件中设置:
+
+```yaml
+seata:
+ data-source-proxy-mode: XA
+```
+
+2)利用`@GlobalTransactional`标记分布式事务的入口方法
+
+```java
+@GlobalTransactional
+public Long createOrder(OrderFormDTO orderFormDTO) {
+ ...
+}
+```
+
+3)子事务中方法前添加`@Transactional` ,方便回滚
+
+
+
+### AT模式
+
+
+
+简述`AT`模式与`XA`模式最大的区别是什么?
+
+- `XA`模式一阶段不提交事务,锁定资源;`AT`模式一阶段直接提交,不锁定资源。
+- `XA`模式依赖数据库机制实现回滚;`AT`模式利用数据快照实现数据回滚。
+- `XA`模式强一致;`AT`模式最终一致(存在短暂不一致)
+
+
+
+实现方式:
+
+1)为需要的微服务数据库中**创建undo_log表**
+
+```mysql
+-- for AT mode you must to init this sql for you business database. the seata server not need it.
+CREATE TABLE IF NOT EXISTS `undo_log`
+(
+ `branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
+ `xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',
+ `context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
+ `rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
+ `log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
+ `log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
+ `log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
+ UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 1
+ DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
+
+```
+
+2)微服务的配置中设置(其实不设置,默认也是AT模式)
+
+```
+seata:
+ data-source-proxy-mode: AT
+```
+
diff --git a/自学/消息队列MQ.md b/自学/消息队列MQ.md
new file mode 100644
index 0000000..bc6a39f
--- /dev/null
+++ b/自学/消息队列MQ.md
@@ -0,0 +1,64 @@
+# 消息队列MQ
+
+## 初识MQ
+
+### **同步调用**
+
+
+
+同步调用有3个问题:
+
+- **拓展性差**,每次有新的需求,现有支付逻辑都要跟着变化,代码经常变动
+- **性能下降**,每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和
+- **级联失败**,当交易服务、通知服务出现故障时,整个事务都会回滚,交易失败。
+
+
+
+### 异步调用
+
+
+
+
+
+### 技术选型
+
+
+
+
+
+## RabbitMQ
+
+### 部署
+
+```yml
+mq:
+ image: rabbitmq:3.8-management
+ container_name: mq
+ restart: unless-stopped
+ hostname: mq
+ environment:
+ RABBITMQ_DEFAULT_USER: admin
+ RABBITMQ_DEFAULT_PASS: "admin"
+ RABBITMQ_PLUGINS_DIR: "/plugins:/custom-plugins"
+ ports:
+ - "15672:15672"
+ - "5672:5672"
+ volumes:
+ - ./mq-plugins:/custom-plugins
+ networks:
+ - hmall-net
+```
+
+http://localhost:15672/ 访问控制台
+
+
+
+### 架构图
+
+
+
+- **`publisher`**:生产者,发送消息的一方
+- **`consumer`**:消费者,消费消息的一方
+- **`queue`**:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理
+- **`exchange`**:交换机,负责消息路由。生产者发送的消息由交换机决定投递到哪个队列。**不存储**
+- **`virtual host`**:虚拟主机,起到数据隔离的作用。每个虚拟主机相互独立,有各自的exchange、queue
\ No newline at end of file