Commit on 2025/05/27 周二 20:43:37.87
This commit is contained in:
parent
1e70e3f311
commit
376e78117c
211
自学/微服务.md
211
自学/微服务.md
@ -977,7 +977,7 @@ hm:
|
|||||||
|
|
||||||
示例:购物车中的商品上限数量需动态调整。
|
示例:购物车中的商品上限数量需动态调整。
|
||||||
|
|
||||||
1)在nacos中添加配置
|
**1)在nacos中添加配置**
|
||||||
|
|
||||||
在nacos中添加一个配置文件,将购物车的上限数量添加到配置中:
|
在nacos中添加一个配置文件,将购物车的上限数量添加到配置中:
|
||||||
|
|
||||||
@ -1001,7 +1001,7 @@ hm:
|
|||||||
maxAmount: 1 # 购物车商品数量上限
|
maxAmount: 1 # 购物车商品数量上限
|
||||||
```
|
```
|
||||||
|
|
||||||
2)在微服务中配置
|
**2)在微服务中配置**
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@Data
|
@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,可以对远程调用的异常做处理。
|
触发限流或熔断后的请求不一定要直接报错,也可以返回一些默认数据或者友好提示,采用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`:
|
**步骤一**:在hm-api模块中给`ItemClient`定义降级处理类,实现`FallbackFactory`:
|
||||||
|
|
||||||
<img src="https://pic.bitday.top/i/2025/05/26/x2wpbf-0.png" alt="image-20250526200028905" style="zoom:80%;" />
|
<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 {
|
|||||||
```
|
```
|
||||||
|
|
||||||
重启后,再次测试
|
重启后,再次测试
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 熔断器
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<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 中,对应三大角色:
|
||||||
|
|
||||||
|
- **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
|
||||||
|
<!--统一配置管理-->
|
||||||
|
<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 的 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
|
||||||
|
```
|
||||||
|
|
||||||
|
64
自学/消息队列MQ.md
Normal file
64
自学/消息队列MQ.md
Normal 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个问题:
|
||||||
|
|
||||||
|
- **拓展性差**,每次有新的需求,现有支付逻辑都要跟着变化,代码经常变动
|
||||||
|
- **性能下降**,每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和
|
||||||
|
- **级联失败**,当交易服务、通知服务出现故障时,整个事务都会回滚,交易失败。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 异步调用
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 技术选型
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 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
|
Loading…
x
Reference in New Issue
Block a user