zoukankan      html  css  js  c++  java
  • 20200512:哪些场景需要幂等性?怎么保证幂等性?

    福哥答案2020-05-12:

    答案仅供参考:
    2.需要幂等的场景
    可能会发生重复请求或消费的场景,在微服务架构中是随处可见的。以下是笔者梳理的几个常见场景:

    网络波动:
    因网络波动,可能会引起重复请求

    分布式消息消费:
    任务发布后,使用分布式消息服务来进行消费,参考【消息总线真的能保证幂等?】

    用户重复操作:
    用户在使用产品时,可能会误操作而触发多笔交易,或者因为长时间没有响应,而有意触发多笔交易。

    未关闭的重试机制:
    技术人员人为的错误,因开发人员、测试人员或运维人员没有检查出来,而开启的重试机制(如Nginx重试、RPC通信重试或业务层重试等)

    4.幂等实现方法:
    4.1 全局唯一ID
    如果使用全局唯一ID,就是根据业务的操作和内容生成一个全局ID,在执行操作前先根据这个全局唯一ID是否存在,来判断这个操作是否已经执行。如果不存在则把全局ID,存储到存储系统中,比如数据库、Redis等。如果存在则表示该方法已经执行。

    使用全局唯一ID是一个通用方案,可以支持插入、更新、删除业务操作。但是这个方案看起来很美但是实现起来比较麻烦,下面的方案适用于特定的场景,但是实现起来比较简单。

    4.2 去重表
    这种方法适用于在业务中有唯一标的插入场景中,比如在以上的支付场景中,如果一个订单只会支付一次,所以订单ID可以作为唯一标识。这时,我们就可以建一张去重表,并且把唯一标识作为唯一索引,用以记录订单支付信息,在我们实现时,把创建支付单据和写入去去重表,放在一个事务中,如果重复创建,数据库会抛出唯一约束异常,操作就会回滚。这个方法其实也是用到唯一ID,与上面全局唯一ID不同的是,他是针对具体单个业务流程的,实现起来相对简单。

    4.3 插入或更新
    这种方法插入并且有唯一索引的情况,比如我们要关联商品品类,其中商品的ID和品类的ID可以构成唯一索引,并且在数据表中也增加了唯一索引。这时就可以使用InsertOrUpdate操作。在mysql数据库中如下:

    insert into goods_category
    (goods_id,category_id,create_time,update_time)
    values(#{goodsId},#{categoryId},now(),now())
    on DUPLICATE KEY UPDATE update_time=now()
    4.4 多版本控制
    这种方法适合在更新的场景中,比如我们要更新商品的名字,这时我们就可以在更新的接口中增加一个版本号,来做幂等:

    boolean updateGoodsName(int id,String newName,int version);
    在实现时可以如下:

    update goods set name=#{newName},version=#{version} where
    id=#{id} and version<${version}
    4.5 状态机控制
    这种方法适合在有状态机流转的情况下,比如就会订单的创建和付款,订单的付款肯定是在之前,这时我们可以通过在设计状态字段时,使用int类型,并且通过值类型的大小来做幂等,比如订单的创建为0,付款成功为100,付款失败为99。在做状态机更新时,我们就这可以这样控制:

    update goods_order set status=#{status} where id=#{id} and
    status<#{status}
    以上就是保证接口幂等性的一些方法。

    5.总结
    幂等性设计不能脱离业务来讨论,一般情况下,去重表同时也是业务数据表,而针对分布式的去重ID,可以参考以下几种方式:

    UUID
    Snowflake
    数据库自增ID
    业务本身的唯一约束
    业务字段+时间戳拼接

  • 相关阅读:
    《杜教筛》
    《洛谷P4213 【模板】杜教筛(Sum)》
    《洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB》
    《纸牌问题》
    《洛谷P2522 [HAOI2011]Problem b》
    使用urlretrieve下载图片
    scrapy初探
    爬豆瓣电影名
    直接插入排序
    Windows python 3 安装OpenCV
  • 原文地址:https://www.cnblogs.com/waitmoon/p/13441319.html
Copyright © 2011-2022 走看看