Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wushizhenking
advanced-java
提交
7148987f
A
advanced-java
项目概览
wushizhenking
/
advanced-java
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
advanced-java
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
7148987f
编写于
11月 28, 2018
作者:
Y
yanglbme
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
docs(idempotency): add distributed-system-idempotency.md
上级
acb8bd8c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
28 addition
and
1 deletion
+28
-1
README.md
README.md
+1
-1
docs/distributed-system/distributed-system-idempotency.md
docs/distributed-system/distributed-system-idempotency.md
+27
-0
未找到文件。
README.md
浏览文件 @
7148987f
...
...
@@ -18,7 +18,7 @@
-
[
Dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢?
](
/docs/distributed-system/dubbo-load-balancing.md
)
-
[
Dubbo 的 spi 思想是什么?
](
/docs/distributed-system/dubbo-spi.md
)
-
[
如何基于 Dubbo 进行服务治理、服务降级、失败重试以及超时重试?
](
/docs/distributed-system/dubbo-service-management.md
)
-
分布式服务接口的幂等性如何设计(比如不能重复扣款)?
-
[
分布式服务接口的幂等性如何设计(比如不能重复扣款)?
](
/docs/distributed-system/distributed-system-idempotency.md
)
-
分布式服务接口请求的顺序性如何保证?
-
如何自己设计一个类似 Dubbo 的 rpc 框架?
...
...
docs/distributed-system/distributed-system-idempotency.md
0 → 100644
浏览文件 @
7148987f
## 面试题
分布式服务接口的幂等性如何设计(比如不能重复扣款)?
## 面试官心理分析
从这个问题开始,面试官就已经进入了
**实际的生产问题**
的面试了。
一个分布式系统中的某个接口,该如何保证幂等性?这个事儿其实是你做分布式系统的时候必须要考虑的一个生产环境的技术问题。啥意思呢?
你看,假如你有个服务提供一个接口,结果这服务部署在了 5 台机器上,接着有个接口就是
**付款接口**
。然后人家用户在前端上操作的时候,不知道为啥,总之就是一个订单
**不小心发起了两次支付请求**
,然后这俩请求分散在了这个服务部署的不同的机器上,好了,结果一个订单扣款扣两次。
或者是订单系统调用支付系统进行支付,结果不小心因为
**网络超时**
了,然后订单系统走了前面我们看到的那个重试机制,咔嚓给你重试了一把,好,支付系统收到一个支付请求两次,而且因为负载均衡算法落在了不同的机器上,尴尬了。。。
所以你肯定得知道这事儿,否则你做出来的分布式系统恐怕容易埋坑。
## 面试题剖析
这个不是技术问题,这个没有通用的一个方法,这个应该
**结合业务**
来保证幂等性。
所谓
**幂等性**
,就是说一个接口,多次发起同一个请求,你这个接口得保证结果是准确的,比如不能多扣款、不能多插入一条数据、不能将统计值多加了 1。这就是幂等性。
其实保证幂等性主要是三点:
-
对于每个请求必须有一个唯一的标识,举个栗子:订单支付请求,肯定得包含订单 id,一个订单 id 最多支付一次,对吧。
-
每次处理完请求之后,必须有一个记录标识这个请求处理过了。常见的方案是在 mysql 中记录个状态啥的,比如支付之前记录一条这个订单的支付流水。
-
每次接收请求需要进行判断,判断之前是否处理过。比如说,如果有一个订单已经支付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水,orderId 已经存在了,唯一键约束生效,报错插入不进去的。然后你就不用再扣款了。
实际运作过程中,你要结合自己的业务来,比如说利用 redis,用 orderId 作为唯一键。只有成功插入这个支付流水,才可以执行实际的支付扣款。
要求是支付一个订单,必须插入一条支付流水,order_id 建一个唯一键
`unique key`
。你在支付一个订单之前,先插入一条支付流水,order_id 就已经进去了。你就可以写一个标识到 redis 里面去,
`set order_id payed`
,下一次重复请求过来了,先查 redis 的 order_id 对应的 value,如果是
`payed`
就说明已经支付过了,你就别重复支付了。
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录