当涉及业务数据的变更,不是简单的数据查询时, 在调用方相同条件有效重复请求时,就需要保持业务系统数据之间的一致性,不管请求多少次都会返回相同的结果。
比如一个订单支付接口,第一次请求返回支付成功,,即使后面的请求没有实际的支付行为,也应该返回查询到的支付成功的结果。如果拦截并抛出异常,就可能造成一端支付失败,一端支付成功的情况;如果第一次返回支付失败,就不需要幂等,因为支付失败在该业务场景下是无效的。
如何确定是相同的请求重复发送,就需要调用方带上一个请求的唯一标识,如订单号,数据库主键,或由数据库主键组合而成的编号,不能是每次随机生成guid。
防并发当客户端高频率重复请求,或者在分布式系统架构中,代理(网关)没正确分发报文,如某一节点超时没有正常响应,导致报文被分发到多个节点,且间隔时间较短,就容易产生并发问题。高级别的防重就是在防并发。
如何防重页面限制,如限制按钮点击,强制页面刷新
代码层面数据查询判重
并发加(分布式)锁
数据库唯一约束(不能只依赖数据库,数据库重复插入抛出的异常会影响客户端的处理)
基本校验流程与单例代码流程相似
两次数据库判重,避免每次都要获取分布式锁
将第二次数据库判重改为捕获异常DuplicateKeyException来节省数据库链接(可用AOP实现)
一次都不判重,直接捕获异常DuplicateKeyException
/*方案一*/ if(...)/*参数简单校验*/ { return ...; } if (...)/*数据库判重*/ { return ...; } using (var distributeLock=new ...)/*分布式锁*/ { if (...)/*数据库二次判重*/ { return ...; } //todo } 超时很多系统的网关,代理都会设置超时时间,过了时间链接就会自动断开,当数据量过大时,就容易出现超时,影响正常业务流程。所以接口的性能非常重要,明确单一职责,尽量做最少,最简单的事情。
同步改异步数据库,流,调用第三方服务等费时操作改为异步方法。
流程由同步改为异步,如服务端只记录请求,直接返回客户端处理中,后续流程使用定时任务或消息队列处理,然后客户端进行轮询或服务端回调通知。异步流程会增加系统的复杂度,开发成本,但相对应也提高了系统的稳定性和扩展性。
Web API接口设计注意事项(一)幂等、超时优化
标签:
原文地址:https://www.cnblogs.com/zk-ljc/p/12248652.html