文章目录
1. 引言
- 1. 引言
- 2. 幂等性的定义
- 3. 确定需要幂等性的范围
- 3.1 确定大范围
- 3.2 数据访问层-写请求
- 4. 幂等性解决方案
- 4.1 Insert幂等方案
- 4.2 Update计算操作幂等方案
在上一篇博客《微服务轮子项目(08) - 监控架构设计Metrics》,主要简介GPE监控系统,系统架构图如下:
本文讲解下系统幂等性设计。
2. 幂等性的定义定义:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。
举个最简单的例子(支付例子):
- 用户购买商品使用支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额返发现多扣钱了,流水记录也变成了两条。
请求层面:(读请求、写请求)
- 其中读请求没有影响数据变化不需要做幂等性
微服务层面:(负载均衡、api网关、业务逻辑层、数据访问层)
- 其中负载均衡、api网关、业务逻辑层没有影响数据变化不需要做幂等性
上面的范围里只有数据访问层和写请求
3.2 数据访问层-写请求Insert:需要做幂等性 Update:
- 直接更新某个值的:不需要做幂等性
- 累加操作等计算式的更新:需要做幂等性
Delete:重复删除结果是一样:不需要做幂等性
4. 幂等性解决方案没有最优的方案只有最适合的,因为这个和业务的逻辑强相关,所以就简单列举通用的方案。
4.1 Insert幂等方案方式1:数据字段增加唯一索引
- 优点:实现简单方便
- 缺点:影响数据库性能不适合该字段会被频繁更新的场景,唯一索引比普通索引在写操作上开销会大很多
方式2:insert时使用临时表查询判断
insert into sys_user(name,password)
select 'admin', '123456' from dual
where not exists(select 1 from sys_user where name='admin');
- 优点:不需要创建唯一索引,语法相对通用(mysql和oracle)
- 缺点:写操作会增加一次select子查询开销,增加sql语法的复杂度可读性较差
方式3:细粒度分布式锁+select + insert
意思就是先加一个细粒度的分布式锁,然后select查一下是否存在,不存在再insert
- 优点:性能影响较少,使用的是细粒度锁,所以只有重复提交记录时才会阻塞
- 缺点:写操作会增加一次select开销,实现难度相对较大因为需要分布式细粒度锁
这个需要结合具体业务来设计方案,常用的场景可通过版本号的方式来控制在表里面添加version字段
alter table sys_user add version int default 0;
然后更新的时候通过这个version来判断是否为过期无效操作,这是乐观锁的一种思路
update sys_user set age=age+1, version=version+1
where version=xx