1 Star 0 Fork 2

cckwzmc / 分布式幂等组件用redis的setnx特性

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

接口幂等性切面

介绍

一、什么是幂等性
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();
    }
}

空文件

简介

分布式幂等组件利用redis的setnx特性保证唯一 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/cckwzcm/saas-idemfactor.git
git@gitee.com:cckwzcm/saas-idemfactor.git
cckwzcm
saas-idemfactor
分布式幂等组件用redis的setnx特性
master

搜索帮助