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

891

被折叠的 条评论
为什么被折叠?



