代码拉取完成,页面将自动刷新
同步操作将从 我叫张梦来/分布式幂等组件用redis的setnx特性 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
一、什么是幂等性
HTTP/1.1中对幂等性的定义是: 一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外)。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同。
这里需要关注几个重点:
1.幂等不仅仅只是一次(或多次)请求对资源没有副作用(比如查询数据库操作,没有增删改,因此没有对数据库有任何影响)。
2.幂等还包括第一次请求的时候对资源产生了副作用,但是以后的多次请求都不会再对资源产生副作用。
3.幂等关注的是以后的多次请求是否对资源产生的副作用,而不关注结果。
4.网络超时等问题,不是幂等的讨论范围。
5.幂等性是系统服务对外一种承诺(而不是实现),承诺只要调用接口成功,外部多次调用对系统的影响是一致的。声明为幂等的服务会认为外部调用失败是常态,并且失败之后必然会有重试。
二、有哪些场景需要用到幂等性
业务开发中,经常会遇到重复提交的情况,无论是由于网络问题无法收到请求结果而重新发起请求,或是前端的操作抖动而造成重复提交情况。 在交易系统,支付系统这种重复提交造成的问题有尤其明显,比如:
1.用户在APP上连续点击了多次提交订单,后台应该只产生一个订单;
2.向支付宝发起支付请求,由于网络问题或系统BUG重发,支付宝应该只扣一次钱。 很显然,声明幂等的服务认为,外部调用者会存在多次调用的情况,为了防止外部多次调用对系统数据状态的发生多次改变,将服务设计成幂等。
三、幂等性如何实现
1.首先去查询上一次的执行状态,如果没有则认为是第一次请求
2.在服务改变状态的业务逻辑前,保证防重复提交的逻辑
四、幂等性的不足
1.增加了额外控制幂等的业务逻辑,复杂化了业务功能;
2.把并行执行的功能改为串行执行,降低了执行效率。
所以,幂等是为了简化客户端逻辑处理,却增加了服务提供者的逻辑和成本,是否有必要,需要根据具体场景具体分析,因此除了业务上的特殊要求外,尽量不提供幂等的接口。
1.需要引入maven包
<dependency>
<artifactId>paas-idemfactor-sdk</artifactId>
<groupId>com.example</groupId>
<version>1.0.0</version>
</dependency>
2.启动类加入注解
@EnableIdemfactor3
public class AppBootstrap {}
3.本项目依赖redis组件,使用前需要先配置好redis
spring:
redis:
port: 6379
host: 127.0.0.1
# password: 123456
database: 5
4.使用时需要在方法上加入注解@Idemfactor,案例如下
@RestController
@RequestMapping("/idempotent")
public class IdmtController {
@GetMapping(value = "/test01")
@Idemfactor(expireTime = 20l)
public String test01() {
return "test01";
}
// http://127.0.0.1:8080/idempotent/test02?msg=ssssss
@GetMapping(value = "/test02")
@Idemfactor(expireTime = 20l,key="'test02:msg='+#msg")
public String test02(String msg) {
if (StringUtils.isNotBlank(msg)) {
System.out.println(msg);
}
return "test02";
}
// http://127.0.0.1:8080/idempotent/test03?name=1&age=2
@GetMapping(value = "/test03")
@Idemfactor(key = "'test03:age='+#testVo.age+';name='+#testVo.name",expireTime = 20l)
public String test03(TestVo testVo) {
System.out.println(testVo);
return "test03";
}
// http://127.0.0.1:8080/idempotent/test04?text=sdasda
@RequestMapping(value = "/test04", method = RequestMethod.GET)
@Idemfactor(fallback = StringIdmtFallbackImpl.class,expireTime = 20l,key="'text='+#text")
public String test04(String text) {
return "test04";
}
// http://127.0.0.1:8080/idempotent/test05?name=1&age=2
@GetMapping(value = "/test05")
@Idemfactor(keyGenerator = "myKeyGenerator",expireTime = 20l)
public String test05(TestVo testVo) {
System.out.println(testVo.toString());
return "test05";
}
}
5.其中test04和test05需要实现接口,具体案例如下
// 自定义回调方法
@Component
public class StringIdmtFallbackImpl implements IdemFallback<String> {
@Override
public String callback() {
return "降级方法";
}
}
// 自定义key
@Component
public class MyKeyGenerator implements IdemKeyGenerator {
@Override
public String generate(Object target, Method method, Object... params) {
return target.getClass().getSimpleName()+"."+method.getName();
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。