• Redis快速上手篇八(redission完善分布式锁)


    Redisson

    Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。简单说就是redis在分布式系统上工具的集合,Redission提供了分布式锁的多种多样的功能.

    使用redission

    自定义redis分布式锁无法自动续期,比如,一个锁设置了1分钟超时释放,如果拿到这个锁的线程在一分钟内没有执行完毕,那么这个锁就会被其他线程拿到,可能会导致严重的线上问题,在秒杀场景下,很容易因为这个缺陷导致的超卖了。

    redission 超时时间1m 执行逻辑的时候3m

    Redisson 锁加锁流程:

    线程去获取锁,获取成功则执行lua脚本,保存数据到redis数据库。如果获取失败: 一直通过while循环尝试获取锁(可自定义等待时间,超时后返回失败)。Redisson提供的分布式锁是支持锁自动续期的,也就是说,如果线程仍旧没有执行完,那么redisson会自动给redis中的目标key延长超时时间,这在Redisson中称之为 Watch Dog 机制。

    java中的使用

    引入redisson相关jar

    1. org.springframework.boot
    2. spring-boot-starter-data-redis
    3. org.redisson
    4. redisson-spring-boot-starter
    5. 3.12.5

    application文件

    1. # 设置redis的信息
    2. spring.redis.host=192.168.253.16
    3. spring.redis.database=0
    4. spring.redis.password=root
    5. spring.redis.port=6379

    配置类:

    1. import org.redisson.Redisson;
    2. import org.redisson.api.RedissonClient;
    3. import org.redisson.config.Config;
    4. import org.springframework.beans.factory.annotation.Value;
    5. import org.springframework.context.annotation.Bean;
    6. import org.springframework.context.annotation.Configuration;
    7. @Configuration
    8. public class RedissonConfig {
    9. @Value("${spring.redis.host}")
    10. private String host;
    11. @Value("${spring.redis.port}")
    12. private String port;
    13. @Value("${spring.redis.password}")
    14. private String redisPassword;
    15. @Bean
    16. public RedissonClient getRedisson(){
    17. Config config = new Config();
    18. // //多节点config.useClusterServers()
    19. //单机模式 依次设置redis地址和密码
    20. config.useSingleServer().
    21. setAddress("redis://" + host + ":" + port).
    22. setPassword(redisPassword);
    23. return Redisson.create(config);
    24. }
    25. }

    controller(控制层)

    1. import org.redisson.api.RLock;
    2. import org.redisson.api.RedissonClient;
    3. import org.springframework.data.redis.core.StringRedisTemplate;
    4. import org.springframework.web.bind.annotation.PostMapping;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import org.springframework.web.bind.annotation.RestController;
    7. import javax.annotation.Resource;
    8. import java.util.Objects;
    9. @RestController
    10. @RequestMapping("/redisLock")
    11. public class RedisLockController {
    12. @Resource
    13. private StringRedisTemplate stringRedisTemplate;
    14. @Resource
    15. private RedissonClient redisson;
    16. private static final String REDIS_KEY = "redis_test";
    17. private static final int MAX_SIZE = 10;
    18. /**
    19. * 初始化库存
    20. */
    21. @PostMapping("/init")
    22. public void init() {
    23. stringRedisTemplate.opsForValue().set(REDIS_KEY, String.valueOf(MAX_SIZE));
    24. }
    25. /**
    26. * 扣库存业务
    27. */
    28. @PostMapping("/test")
    29. public void exportInventory() {
    30. String lockKey = "product001";
    31. RLock lock = redisson.getLock(lockKey);
    32. try {
    33. lock.lock();
    34. int s = Integer.parseInt(Objects.requireNonNull(stringRedisTemplate.opsForValue().get(REDIS_KEY)));
    35. System.out.printf("1号服务:库存当前为:" + s + "\n");
    36. //stringRedisTemplate.opsForValue().set(REDIS_KEY, String.valueOf(s));
    37. if(s>0) {
    38. stringRedisTemplate.opsForValue().decrement(REDIS_KEY);
    39. }
    40. } catch (Exception e) {
    41. } finally {
    42. lock.unlock();
    43. }
    44. }
    45. }

    使用jmeter测试:

    写两个一模一样的项目 通过jmeter访问 redisLock/test

    两个服务中的数据不重复即可

  • 相关阅读:
    zfaka 虎皮椒微信+支付宝插件(内附说明)
    泰迪智能科技企业数据挖掘平台使用场景
    elasticsearch分词器
    本地部署AutoGPT
    UG NX二次开发(C++)-采用NXOpen方法创建同步建模中的偏置曲面
    《前端》css总结(上)
    《网络安全笔记》第十四章:交换机的工作原理
    《数据结构、算法与应用C++语言描述》-队列的应用-图元识别问题
    HIve 分桶表及作用
    Python编程 元组的创建
  • 原文地址:https://blog.csdn.net/Z15800020057/article/details/134083837