首页
  • 2024.1.1.0
  • 2024.1.1.1
  • 2024.1.2.0
  • 2024.1.3.0
  • Java
  • Linux
  • Deploy
  • Application
关于
友情链接
GitHub (opens new window)

Xiao ku

板砖师傅
首页
  • 2024.1.1.0
  • 2024.1.1.1
  • 2024.1.2.0
  • 2024.1.3.0
  • Java
  • Linux
  • Deploy
  • Application
关于
友情链接
GitHub (opens new window)
  • 版本日志
  • 贡献清单
  • 2024.1.3.0

  • 2024.1.2.0

  • 2024.1.1.1

  • 2024.1.1.0

    • Simple-Starter概述
    • 自动装配模块

      • simple-starter-web
      • simple-starter-redisson
        • 简介
        • 分布式幂等和锁的主要区别
        • 引入依赖
        • 配置项
        • 功能项
          • 注解
          • 分布式幂等
          • 使用示例
          • 各字段说明
          • key说明
          • MD5说明
          • 解锁说明
          • 使用说明
          • 分布式锁
          • 使用示例
          • 各字段说明
          • key说明
          • MD5说明
          • 解锁说明
          • 分布式限流器
          • 使用示例
          • 各字段说明
          • key说明
          • MD5说明
          • 限流类型
          • 服务类
          • 分布式锁服务类
          • 缓存服务类
          • 获取Redisson客户端
          • redisson连接类型
          • 使用注解Cacheable
      • simple-starter-s3
      • simple-starter-socket
      • simple-starter-grpc
      • simple-starter-datasource
      • simple-starter-freemarker
      • simple-starter-cloud
      • simple-starter-encrypt
      • simple-starter-dict
      • simple-starter-email
      • simple-starter-gateway
      • simple-starter-package
    • 服务类模块

  • OpenSource
  • 2024.1.1.0
  • 自动装配模块
xiaoku
2023-03-31
目录

simple-starter-redisson

# 简介

提供 注解简化使用:分布式锁、分布式幂等、分布式限流器
提供 分布式加锁、解锁等服务类
提供 常用的对象缓存的常用操作服务类
提供 CacheManager并配置Cacheable注解常用配置及自定义CacheName对应配置

# 分布式幂等和锁的主要区别

- 锁 分布式幂等
目的 保护资源完整性,防止多线程导致数据竞争 用于保证操作的一致性,防止重复请求影响系统状态
范围 同步机制,用于控制对共享资源的并发访问 分布式系统设计理念,用于处理分布式系统中的重复请求

# 引入依赖

    <dependencies>
        <dependency>
            <groupId>cn.iosd</groupId>
            <artifactId>simple-starter-redisson</artifactId>
            <version>Version</version>
        </dependency>
    </dependencies>
1
2
3
4
5
6
7

# 配置项

simple:
  redisson:
    #分布式锁 缺省项为false
    enabled: true
    type: standalone
    config:
      ## 单体模式
      standalone:
        address: redis://127.0.0.1:6379
        password:
        database: 0
      ## 主从模式
      masterSlave:
        masterAddress: redis://127.0.0.1:6379
        slaveAddresses:
          - redis://127.0.0.1:6379
        password:
        database: 0
      ## 哨兵配置
      sentinel:
        sentinelMasterName: myMaster
        sentinelAddresses:
          - redis://127.0.0.1:26379
          - redis://127.0.0.2:26379
        password:
        database: 0
      ## 集群方式
      cluster:
        clusterAddresses:
          - redis://127.0.0.1:7000
          - redis://127.0.0.1:7001
          - redis://127.0.0.2:7000
        password:
    #Cacheable注解自定义配置
    cacheable:
      #缺省项为false,优先级小于simple.redisson.enabled
      enabled: true
      config:
        #自定义cacheName及过期时间
        cacheExpiresAfterFiveMinutes:
          ttl: 300000
          maxIdleTime: 300000
        cacheExpiresAfterTenSecond:
          ttl: 10000
          maxIdleTime: 10000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

# 功能项

# 注解

# 分布式幂等

注解: @DistributedIdempotent

# 使用示例
@DistributedIdempotent

@DistributedIdempotent(value = "drp", message = "请求重复!", expireTime = 5)

@DistributedIdempotent(param = "#keyName", includePointMd5 = false, message = "请求重复!", expireTime = 5, executionFinishedUnlock = false)
public Response<?> decrement(String keyName) {
   return Response.ok();
}
1
2
3
4
5
6
7
8
# 各字段说明
  • value:key固定值
  • param:key动态参数值,支持el表达式,默认为空不拼接(若el获取不到对应值默认:DV)
  • includePointMd5:key后缀,是否拼接MD5(从切点获取方法参数和实例字符串生成对象,转为md5)
  • message:失败的提示信息
  • acquireTimeout:获取锁的最长等待时间 默认0
  • expireTime:获取后持有锁的最长时间 默认10
  • unit:时间单位 默认秒
  • executionFinishedUnlock:是否在业务执行结束后解锁,默认true(false:若干时间内防重复提交功能 true:业务逻辑执行期间内防重复提交功能)
# key说明

includePointMd5为true:前缀+固定值+动态参数值+md5.get()
includePointMd5为true且param不传:前缀+固定值+md5.get()

includePointMd5为false:前缀+固定值+动态参数值
includePointMd5为false且param不传:前缀+固定值
eg:

前缀为 SimpleRI:

SimpleRI:固定值:动态参数值:c5a2e....4a0
SimpleRI:固定值:c5a2e....4a0

SimpleRI:固定值:动态参数值
SimpleRI:固定值
1
2
3
4
5
6
7
# MD5说明

从切点获取方法参数和实例字符串生成对象,转为md5
生成对象:MethodContext

MethodContext[argMap={keyName=cda6666}, name=public cn.iosd.starter.web.domain.Response<?> cn.iosd.demo.redisson.controller.AnnotationIdempotentController.decrementReqPara(java.lang.String)]
1

生成md5:

 Supplier<String> md5 = () -> DigestUtils.md5DigestAsHex(context.toString().getBytes());
1
# 解锁说明

executionFinishedUnlock

等于true时: 业务执行结束后解锁:业务逻辑执行期间内防重复提交功能  
等于false时:业务执行结束后不解锁,等待自动过期:若干时间内防重复提交功能  
1
2
# 使用说明

直接使用注解无需为各字段赋值即可保证分布式幂等:

    主要原因:默认开启了md5,md5由切点获取方法参数和实例字符串生成 
key为 	SimpleRI:IC:c5a2e****
1
2

入参为实体,为实体对象的单个参数(前提参数值不为空,否则生成的key可能重复)保证分布式幂等: 注解字段使用param,并且关闭md5

    /**
     * key动态参数值,支持el表达式
     *
     * <pre>
     *  1.获取方法参数中的某个值
     *      void test(String id)  => #id
     *  2.获取对象参数中的某个值
     *      void test(Vo vo)  => #vo.id
     *  3.参数值获取不到,默认为:DV
     *      void test(String id)  => #im
     *  4.默认空,不拼接到key中
     * </pre>
     */
    String param() default "";
1
2
3
4
5
6
7
8
9
10
11
12
13
14

入参为实体,为实体对象的单个参数(参数值可能为空)保证分布式幂等: 注解字段使用value,param,并且关闭md5

value:key固定值 自定义取值全局唯一
1

# 分布式锁

注解: @DistributedLock

# 使用示例
@DistributedLock

@DistributedLock(value = "demo", param = "#keyName", leaseTime = 105)

1
2
3
4
# 各字段说明
  • value:key固定值
  • param:key动态参数值,支持el表达式,默认为空不拼接(若el获取不到对应值默认:DV)
  • includePointMd5:key后缀,是否拼接MD5(从切点获取方法参数和实例字符串生成对象,转为md5)
  • leaseTime:锁的有效时间-秒
# key说明

includePointMd5为true:前缀+固定值+动态参数值+md5.get()
includePointMd5为true且param不传:前缀+固定值+md5.get()

includePointMd5为false:前缀+固定值+动态参数值
includePointMd5为false且param不传:前缀+固定值
eg:

前缀为 SimpleRL:

SimpleRL:固定值:动态参数值:c5a2e....4a0
SimpleRL:固定值:c5a2e....4a0

SimpleRL:固定值:动态参数值
SimpleRL:固定值
1
2
3
4
5
6
7
# MD5说明

如上

# 解锁说明

leaseTime

在获取到锁之后,该锁会在指定的leaseTime时间后自动释放,即锁的持有时间。
如果在这个时间内业务执行完毕,那么在finally块中的lock.unlock()会手动释放锁,如果在这个时间内业务没有执行完毕,锁也会自动释放
1
2

# 分布式限流器

注解:@DistributedRateLimiter

# 使用示例
@DistributedRateLimiter

@DistributedRateLimiter(type = RateType.PER_CLIENT)

1
2
3
4
# 各字段说明
  • value:key固定值
  • param:key动态参数值,支持el表达式,默认为空不拼接(若el获取不到对应值默认:DV)
  • includePointMd5:key后缀,是否拼接MD5(从切点获取方法参数和实例字符串生成对象,转为md5)
  • rate:速率(即:在有效时间单位内通过的数量)
  • rateTime:有效时间 默认1
  • timeUnit:时间单位 默认秒
  • message:失败提示信息
  • type:限流类型 默认全局
# key说明

includePointMd5为true:前缀+固定值+动态参数值+md5.get()
includePointMd5为true且param不传:前缀+固定值+md5.get()

includePointMd5为false:前缀+固定值+动态参数值
includePointMd5为false且param不传:前缀+固定值
eg:

前缀
单客户端  SimpleRRC: 
全局      SimpleRRG:
1
2
3
# MD5说明

如上

# 限流类型

使用org.redisson.api.RateType 区分为单客户端、全局

# 服务类

# 分布式锁服务类

注入使用

    @Autowired(required = false)
    private RedissonLockService redissonLockService;
1
2

加锁操作

    /**
     * 加锁操作 (设置锁的有效时间)
     *
     * @param lockName  锁名称
     * @param leaseTime 锁有效时间-秒
     */
     redissonLockService.lock(lockName, leaseTime);

    /**
     * 加锁操作(tryLock锁,有等待时间)
     *
     * @param lockName  锁名称
     * @param leaseTime 锁有效时间
     * @param waitTime  等待时间
     */
     redissonLockService.tryLock(lockName, leaseTime, waitTime)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

解锁操作

    /**
     * 解锁
     *
     * @param lockName 锁名称
     */
     redissonLockService.unlock(lockName);
1
2
3
4
5
6

# 缓存服务类

注入使用

    @Autowired(required = false)
    private RedissonCacheService redissonCacheService;
1
2

常用示例代码

  @Operation(summary = "Object-获取")
    @GetMapping("/object/{key}")
    public Response<PersonVo> getObject(@PathVariable String key) {
        return Response.ok(redissonCacheService.getObject(key));
    }

    @Operation(summary = "Object-保存")
    @PostMapping("/object/{key}")
    public Response<?> setObject(@PathVariable String key, @RequestBody PersonVo value) {
        redissonCacheService.setObject(key, value);
        return Response.ok();
    }

    @Operation(summary = "List-获取")
    @GetMapping("/list/{key}")
    public Response<List<PersonVo>> getList(@PathVariable String key) {
        return Response.ok(redissonCacheService.getList(key));
    }

    @Operation(summary = "List-保存")
    @PostMapping("/list/{key}")
    public Response<?> setList(@PathVariable String key, @RequestBody List<PersonVo> value) {
        redissonCacheService.setList(key, value);
        return Response.ok();
    }

    @Operation(summary = "Map-获取")
    @GetMapping("/map/{key}")
    public Response<Map<String, PersonVo>> getMap(@PathVariable String key) {
        return Response.ok(redissonCacheService.getMap(key));
    }

    @Operation(summary = "Map-保存")
    @PostMapping("/map/{key}")
    public Response<?> setMap(@PathVariable String key, @RequestBody PersonVo value) {
        Map save = new HashMap(2);
        save.put(key, value);
        redissonCacheService.setMap(key, save);
        return Response.ok();
    }

    @Operation(summary = "删除")
    @DeleteMapping("/{key}")
    public Response<?> delete(@PathVariable("key") String key) {
        redissonCacheService.delete(key);
        return Response.ok();
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 获取Redisson客户端

注入

    @Autowired(required = false)
    private RedissonManager redissonManager;
1
2

获取客户端

    redissonManager.getRedisson()
1

# redisson连接类型

支持:standalone、sentinel、cluster、masterSlave

simple:
  redisson:
    #缺省项为false
    enabled: true
    type: standalone
    config:
      ## 单体模式
      standalone:
        address: redis://127.0.0.1:6379
        password:
        database: 0
      ## 主从模式
      masterSlave:
        masterAddress: redis://127.0.0.1:6379
        slaveAddresses:
          - redis://127.0.0.1:6379
        password:
        database: 0
      ## 哨兵配置
      sentinel:
        sentinelMasterName: myMaster
        sentinelAddresses:
          - redis://127.0.0.1:26379
          - redis://127.0.0.2:26379
        password:
        database: 0
      ## 集群方式
      cluster:
        clusterAddresses:
          - redis://127.0.0.1:7000
          - redis://127.0.0.1:7001
          - redis://127.0.0.2:7000
        password:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 使用注解Cacheable

已提供的cacheName及对应过期时间配置

cacheExpiresAfterTenMinutes:缓存时间10分钟
cacheExpiresAfterOneHour:缓存时间60分钟
cacheNeverExpires:未设置缓存失效时间
1
2
3

可在配置文件中设置自定义cacheName及对应过期时间配置
如下自定义cacheExpiresAfterFiveMinutes:缓存时间5分钟
自定义cacheExpiresAfterTenSecond:缓存时间10秒
例:

simple:
  redisson:
    enabled: true
    type: standalone
    config:
      ## 单体模式
      standalone:
        address: redis://127.0.0.1:6379
        password:
        database: 0
    #Cacheable注解自定义配置
    cacheable:
      #缺省项为false,优先级小于simple.redisson.enabled
      enabled: true
      config:
        #自定义cacheName及过期时间
        cacheExpiresAfterFiveMinutes:
          ttl: 300000
          maxIdleTime: 300000
        cacheExpiresAfterTenSecond:
          ttl: 10000
          maxIdleTime: 10000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

在服务层中使用示例:

    @Cacheable(key = "#keyName + 'FiveMinutes'", cacheNames = "cacheExpiresAfterFiveMinutes", condition = "#keyName.length()>2")
    public String annotateTestCacheNameFiveMinutes(String keyName) {
        log.info("cacheExpiresAfterFiveMinutes:{}", keyName);
        return keyName;
    }

    @Cacheable(key = "#keyName + 'TenSecond'", cacheNames = "cacheExpiresAfterTenSecond", condition = "#keyName.length()>2")
    public String annotateTestCacheNameTenSecond(String keyName) {
        log.info("cacheExpiresAfterTenSecond:{}", keyName);
        return keyName;
    }
1
2
3
4
5
6
7
8
9
10
11
上次更新: 2024/03/25, 02:28:08
simple-starter-web
simple-starter-s3

← simple-starter-web simple-starter-s3→

Copyright © 2019-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式