分布式服务接口的幂等性如何设计(比如不能重复扣款)?

作者: Dubbo开发者

面试官心理分析

从这个问题开始,面试官就已经进入了实际的生产问题的面试了。

一个分布式系统中的某个接口,该如何保证幂等性?这个事儿其实是你做分布式系统的时候必须要考虑的一个生产环境的技术问题。啥意思呢?

你看,假如你有个服务提供一些接口供外部调用,这个服务部署在了 5 台机器上,接着有个接口就是付款接口。然后人家用户在前端上操作的时候,不知道为啥,总之就是一个订单不小心发起了两次支付请求,然后这俩请求分散在了这个服务部署的不同的机器上,好了,结果一个订单扣款扣两次。

或者是订单系统调用支付系统进行支付,结果不小心因为网络超时了,然后订单系统走了前面我们看到的那个重试机制,咔嚓给你重试了一把,好,支付系统收到一个支付请求两次,而且因为负载均衡算法落在了不同的机器上,尴尬了。。。

所以你肯定得知道这事儿,否则你做出来的分布式系统恐怕容易埋坑。

面试题剖析

这个不是技术问题,这个没有通用的一个方法,这个应该结合业务来保证幂等性。

所谓幂等性,就是说一个接口,多次发起同一个请求,你这个接口得保证结果是准确的,比如不能多扣款、不能多插入一条数据、不能将统计值多加了 1。这就是幂等性。

其实保证幂等性主要是三点:

  • 对于每个请求必须有一个唯一的标识,举个栗子:订单支付请求,肯定得包含订单 id,一个订单 id 最多支付一次,对吧。
  • 每次处理完请求之后,必须有一个记录标识这个请求处理过了。常见的方案是在 mysql 中记录个状态啥的,比如支付之前记录一条这个订单的支付流水。
  • 每次接收请求需要进行判断,判断之前是否处理过。比如说,如果有一个订单已经支付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水,orderId 已经存在了,唯一键约束生效,报错插入不进去的。然后你就不用再扣款了。

实际运作过程中,你要结合自己的业务来,比如说利用 Redis,用 orderId 作为唯一键。只有成功插入这个支付流水,才可以执行实际的支付扣款。

要求是支付一个订单,必须插入一条支付流水,order_id 建一个唯一键 unique key 。你在支付一个订单之前,先插入一条支付流水,order_id 就已经进去了。你就可以写一个标识到 Redis 里面去, set order_id payed ,下一次重复请求过来了,先查 Redis 的 order_id 对应的 value,如果是 payed 就说明已经支付过了,你就别重复支付了。

更多推荐

更多
  • Pharo敏捷人工智能-第一部分:神经网络
    Apache CN

  • Pharo敏捷人工智能-第二部分:遗传算法
    Apache CN

  • Pharo敏捷人工智能-# 第三部分:神经进化 第三部分:神经进化
    Apache CN

  • Docker Kubenetes微服务-十四、在多节点集群上安装 Kubernetes 多节点集群的组件,设置环境,安装主节点,测试单节点集群,添加工作节点,测试 Kubernetes 集群,在群集上运行应用,将应用公开为服务,在浏览器中测试应用,扩展应用,摘要,设置 flannels 和 etcd,启动 Kubernet
    Apache CN

  • Docker Kubenetes微服务-十三、创建多容器 Pod 如何找到一个箱中的容器数量?,使用多容器 Pod 的应用类型,设置环境,创建服务,描述服务,创建复制容器,列出 POD,列出 Docker 容器,创建复制控制器后描述服务,在命令行上调用 Hello World 应用,启动交互式 She
    Apache CN

  • Docker Kubenetes微服务-十一、使用 Apache Solr 设置环境,创建服务,列出服务端点,描述服务,创建复制控制器,列出 POD,描述复制控制器,列出日志,启动交互式 Shell,创建 Solr 核心,索引文档,使用 REST 客户端在命令行上访问 Solr,设置端口转发,在管理控制台中访问
    Apache CN

  • Docker Kubenetes微服务-十二、使用 ApacheKafka 设置环境,修改 Docker 映像,创建服务,创建复制控制器,列出 POD,描述一个 Pod,启动交互式 Shell,启动 Kafka 服务器,创建主题,创建 Kafka 制作人,启动 Kafka 消费者,生产和消费消息,扩展集群,删除
    Apache CN

  • Docker Kubenetes微服务-十、使用 Apache Hadoop 生态系统 设置环境,以声明方式创建 Apache Hadoop 集群,运行蜂箱,运行 HBase,删除复制控制器和服务,创建 Apache Hadoop 集群势在必行,摘要,创建服务,创建复制控制器,列出 POD,列出日志,扩展集群,启动交互式
    Apache CN

  • Docker Kubenetes微服务-九、使用 Couchbase 设置环境,以声明方式创建 Couchbase 集群,强制创建 Couchbase 集群,摘要,创建 Pod,创建服务,创建复制控制器,列出 POD,列出日志,描述服务,列出端点,设置端口转发,登录 Couchbase Web 控制台,配
    Apache CN

  • Docker Kubenetes微服务-八、使用 Apache Cassandra 数据库 设置环境,以声明方式创建 Cassandra 集群,创建 Cassandra 集群势在必行,摘要,创建服务,创建复制控制器,扩展数据库,描述 Pod,启动交互式 Shell,启动 CQL Shell,创建密钥空间,更改密钥空间,使用密钥
    Apache CN

  • 近期文章

    更多
    文章目录

      推荐作者

      更多