Commit on 2025/05/27 周二 20:43:37.87

This commit is contained in:
zhangsan 2025-05-27 20:43:37 +08:00
parent 1e70e3f311
commit 376e78117c
2 changed files with 271 additions and 4 deletions

View File

@ -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让它返回默认值。
<img src="https://pic.bitday.top/i/2025/05/26/yu026z-0.png" alt="image-20250526210626857" style="zoom:80%;" />
**步骤一**在hm-api模块中给`ItemClient`定义降级处理类,实现`FallbackFactory`
<img src="https://pic.bitday.top/i/2025/05/26/x2wpbf-0.png" alt="image-20250526200028905" style="zoom:80%;" />
@ -1343,3 +1347,202 @@ public interface ItemClient {
```
重启后,再次测试
#### 熔断器
![image-20250527101557002](https://pic.bitday.top/i/2025/05/27/gswod2-0.png)
<img src="https://pic.bitday.top/i/2025/05/27/guf1mx-0.png" alt="image-20250527101856284" style="zoom:80%;" />
## 分布式事务
场景:订单服务依次调用了购物车服务和库存服务,它们各自操作不同的数据库。当清空购物车操作成功、库存扣减失败时,订单服务能捕获到异常,却无法通知已完成操作的购物车服务,导致数据不一致。虽然每个微服务内部都能保证本地事务的 ACID 特性,但跨服务调用**缺乏全局协调**,无法实现端到端的一致性。
<img src="https://pic.bitday.top/i/2025/05/27/hbf2ke-0.png" alt="image-20250527104713275" style="zoom:80%;" />
### Seeta
要解决这个问题,只需引入一个统一的**事务协调者**,负责跟每个分支通信,检测状态,并统一决定全局提交或回滚。
在 Seata 中,对应三大角色:
- **TCTransaction Coordinator事务协调者**
维护全局事务和各分支事务的状态,负责发起全局提交或回滚指令。
- **TMTransaction Manager事务管理器**
定义并启动全局事务,最后根据应用调用决定调用提交或回滚。
- **RMResource Manager资源管理器**
嵌入到各微服务中,负责注册分支事务、上报执行结果,并在接到 TC 指令后执行本地提交或回滚。
![image-20250527111935499](https://pic.bitday.top/i/2025/05/27/iif6pd-0.png)
其中TM 和 RM 作为客户端依赖,**直接集成到业务服务里**TC 则是一个**独立部署的微服务**,承担全局协调的职责。这样,无论有多少分支参与,都能保证“要么都成功、要么都回滚”的一致性。
### 部署TC服务
1准备数据库表
seata-tc.sql 运行初始化脚本
![image-20250527113529459](https://pic.bitday.top/i/2025/05/27/irwv9m-0.png)
2准备配置文件
![image-20250527114751539](https://pic.bitday.top/i/2025/05/27/iz6r92-0.png)
3Docker部署
```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
<!--统一配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--读取bootstrap文件-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
```
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 的 TCTransaction Coordinator服务以便在本地发起、提交或回滚分布式事务。
### XA模式
![image-20250527140420062](https://pic.bitday.top/i/2025/05/27/n80a47-0.png)
`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模式
![image-20250527162315431](https://pic.bitday.top/i/2025/05/27/qudips-0.png)
简述`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
```

64
自学/消息队列MQ.md Normal file
View File

@ -0,0 +1,64 @@
# 消息队列MQ
## 初识MQ
### **同步调用**
<img src="https://pic.bitday.top/i/2025/05/27/so4pss-0.png" alt="image-20250527173401081" style="zoom: 67%;" />
同步调用有3个问题
- **拓展性差**,每次有新的需求,现有支付逻辑都要跟着变化,代码经常变动
- **性能下降**,每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和
- **级联失败**,当交易服务、通知服务出现故障时,整个事务都会回滚,交易失败。
### 异步调用
![image-20250527175753038](https://pic.bitday.top/i/2025/05/27/t2dfdb-0.png)
### 技术选型
![image-20250527190824767](https://pic.bitday.top/i/2025/05/27/vk3zfw-0.png)
## 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/ 访问控制台
### 架构图
![image-20250527200935901](https://pic.bitday.top/i/2025/05/27/x8b2ej-0.png)
- **`publisher`**:生产者,发送消息的一方
- **`consumer`**:消费者,消费消息的一方
- **`queue`**:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理
- **`exchange`**:交换机,负责消息路由。生产者发送的消息由交换机决定投递到哪个队列。**不存储**
- **`virtual host`**虚拟主机起到数据隔离的作用。每个虚拟主机相互独立有各自的exchange、queue