20190719 接口的幂等性

接口幂等性

1、当前接口设计的时候,是否要考虑接口的幂等性?

2、在高并发的核心技术中如何实现幂等性?对外提供的Api如何保证幂等?

3、后端处理前端的重复请求?

 

为了解决以上问题,就需要保证接口的幂等性,接口的幂等性实际上就是接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。有些接口可以天然的实现幂等性,比如查询接口,对于查询来说,你查询一次和两次,对于系统来说,没有任何影响,查出的结果也是一样。除了查询功能具有天然的幂等性之外,增加、更新、删除都要保证幂等性。那么如何来保证幂等性呢?

 

幂等性实现策略

1、通过分布式缓存(如redis)做已处理标识位(全局唯一id),每次处理消息的时候都去check一下。当前接口是否调用过? 在项目中定义全局唯一id,然后保存到redis中。

1)从redis中查询当前业务是否处理过?如果没有对应的key?说明没有调用过;

2)如果没有处理过,就处理业务逻辑,处理成功后,存入redis,并把数据返回给前端。

​
    /**
     * 接口幂等性处理
     *
     * @param hospitalId
     * @return
     */
    @PostMapping(value = "/repeat")
    public BaseResult<String> processRepeatRequest(@RequestParam("hospitalId") int hospitalId) {
        if (StringUtils.isEmpty(redisUtils.get("cache_repeat_" + hospitalId))) {
            //1)如果没有处理过,进行处理
            String result = null;
            //2)返回给前端的同时,把数据存到redis中
            redisUtils.set("cache_repeat_" + hospitalId, result);
            return BaseResult.buildSuccess(result);
        } else {
            //如果处理过,直接返回值
            return BaseResult.buildSuccess(redisUtils.get("cache_repeat_" + hospitalId));
        }
    }

​

注册接口如何实现幂等性处理?

写入数据的时候需要考虑接口的幂等性,比如注册接口,可能因为网络抖动前端调用了多次接口。使用异常捕获机制删除redis中的标记。

1、使用redis进行标记处理,如果代码执行失败,捕获异常,并删除缓存中的键。

2、如果在手机号列使用唯一索引,失效后的手机号就不能重复注册了

写数据是否需要进行接口幂等处理?可能因为网络抖动前端调用了多次接口。

如果没有try的话,出现异常会导致程序崩溃。而try则可以保证程序的正常运行下去

 

2、多版本控制

这种方法适合在更新的场景中,比如我们要更新商品的名字,这时我们就可以在更新的接口中增加一个版本号(新增一个字段),来做幂等。(数据表中添加一个version字段,来标记数据更新的版本)

    /**
     * 通过版本号处理幂等
     *
     * @param id
     * @param name
     * @param version
     * @return
     */
    public boolean updateGoodsInfo(int id, String name, int version) {
        //对应的数据库中的sql:第一次版本号加1,后面不处理
        //update goods set name=#{name},version=version+1,where id=#{id} and version=#{version}
        return true;
    }

3、通过唯一索引实现

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

-- 插入时,主键冲突了。
-- Duplicate entry '1' for key 'PRIMARY'
-- 通过唯一索引解决此问题
insert into p_doctor(id,sex,delete_flag,creat_id,creat_time,modify_id,modify_time) values(3,1,1,1,now(),1,now()) 
-- 为了不抛出异常,当插入已存在主键的记录时,将插入操作变为修改更新操作
insert into p_doctor(id,sex,delete_flag,creat_id,creat_time,modify_id,modify_time) values(3,1,1,1,now(),1,now()) on DUPLICATE KEY UPDATE modify_time=now()

幂等性应该是合格程序员的一个基因,在设计系统时,是首要考虑的问题,尤其是在像支付宝,银行,互联网金融公司等涉及的都是钱的系统,既要高效,数据也要准确,所以不能出现多扣款,多打款等问题,这样会很难处理,用户体验也不好。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值