zoukankan      html  css  js  c++  java
  • 幂等性

    幂等性的概念

    对于同一操作发起的请求(一次或者多次请求),任意多次执行对资源本身产生的影响均与一次执行产生的影响相同,不会因为多次相同操作而产生副作用。

    比如一个用户注册,点击“注册”,由于某些原因(比如服务器负载大),长时间转圈圈,你多次点击“注册”,这多次请求都是完全相同的,应该只插入一条用户记录,而不是点多次“注册”每次都插入一条用户记录。

    比如下单购买,点击“提交”,卡住了,什么破手机|网络,疯狂点“提交”,这多次请求完全相同,应该只产生一个订单,而不是每次点击都产生一个订单。

    http请求方式(restful)

    在其他条件不变的情况下(资源没有被其它操作修改):

    • get  查询,相同的查询操作,比如select username where id=1  from tb_user;执行多次,查询到的结果都是相同的,get是幂等的
    • post  插入,相同的插入操作,比如insert into tb_order (...) values (...);  执行多次,虽然可能会因为主键已存在、某个字段的值要唯一等原因插入失败,但每次都会尝试插入一条新纪录,如果满足约束,每次都会插入一条记录,结果可能不同(产生了新纪录),post不是幂等的
    • put  更新,相同的更新操作,比如update tb_user username='chy',age=20 where id=1;  不管执行多少次,id=1的这条记录,name都是chy,age都是20,结果都是相同的,put是幂等的
    • delete  删除,相同的删除操作,比如delete from tb_user where id=1 ,不管执行多少次,结果都是删除了id=1的记录,结果相同,delete是幂等的

    消息消费者与幂等性

    消息可能会被重复投递、消费,比如第一次投递的消息还在queue中,为确保消息投递的可靠性,延时又投递了一次消息,消费者应确保同一消息只进行一次消费。


    幂等常见的实现方式

    核心思想:

    使用唯一的业务单号来标识一个业务,如果业务单号相同,就认为是同一笔业务,只执行一次。(去掉重复的业务)

    存储执行过的业务的业务单号,先根据业务单号查询这笔业务是否已经执行过了,如果没执行过,才执行。

    如果系统是单线程的,查询单号、执行这笔业务2个过程都不用加锁;如果过多个线程并发访问执行过的业务单号(有读有写),就需要给执行过的业务单号加锁(幂等是查询时加锁),执行过程往往也需要给共享数据加锁。

    业务单号可以用流水号,也可以唯一id+指纹码,总之要能唯一标识一笔业务。

    比如order的id,只用id是可以唯一标识一个订单,但不能标识是这个order的增改删查哪个业务,也不能标识是这个order的第几次修改操作。需要再加一个指纹码,比如时间戳、业务规则什么的。

    1、数据库主键去重

    单独用一张tb_order_ handled来存储执行过的订单的业务单号,使用列no存储业务单号(主键、unique约束),外键order_id关联order表的id,

    执行业务时先select count(*) from tb_order_handled where no=xxx; 根据业务单号查询这笔业务是否已执行,数量为1表示有这条记录,这笔业务已处理过,不再处理;为0表示没处理过,就处理这笔业务。

    这种方式的缺点是增加了数据库IO次数,数据库性能很容易成为系统性能的瓶颈,往往需要分库分表把业务单号所在的表拆分出来,来提升数据库性能。

     如果这个服务只有数据库更新操作的话,也可以使用数据库的乐观锁(版本号机制)。

    2、分布式锁(推荐)

    把处理过的业务单号作为键值对的key,存储在redis上,处理业务时先查询redis上有没有这个key,有就说明处理过了,不再处理,没有就说明这笔业务没有处理过,开始处理。

    简单、且性能高,推荐。

    3、缓冲区

    把一段时间内要处理的业务都放到缓冲区中,先去掉重复的业务,再执行。

    缺点:处理有时延、不能马上返回处理结果。不太常用。

  • 相关阅读:
    TreeView的自定义绘制图标处理
    业务逻辑层的封装设计
    记一次CS系统与BS的对接集成
    cmd命令使用备忘
    如何有效管理员工
    代码可维护性重要吗?
    Oracle GoldenGate Director安装备忘
    浅析C#深拷贝与浅拷贝
    一首同音叠字诗“石室诗士施氏”
    Ajax原生使用
  • 原文地址:https://www.cnblogs.com/chy18883701161/p/12561765.html
Copyright © 2011-2022 走看看