当前位置: 首页 > wzjs >正文

在凡科做网站百度seo公司

在凡科做网站,百度seo公司,亚马逊a+页面模板,厦门企业网站制作建议先看完第1期和第2期: 基于Redis实现优惠券秒杀——第1期(解决超卖问题、一人一单问题)-CSDN博客 基于Redis实现优惠券秒杀——第2期(分布式锁)-CSDN博客 上一期我们说到,使用分布式锁可能存在一下问…

建议先看完第1期和第2期:

基于Redis实现优惠券秒杀——第1期(解决超卖问题、一人一单问题)-CSDN博客

基于Redis实现优惠券秒杀——第2期(分布式锁)-CSDN博客

上一期我们说到,使用分布式锁可能存在一下问题:

  • 基于SETNX实现的分布式锁存在以下问题
    1. 重入问题
      • 重入问题是指获取锁的线程,可以再次进入到相同的锁的代码块中,可重入锁的意义在于防止死锁,例如在HashTable这样的代码中,它的方法都是使用synchronized修饰的,加入它在一个方法内调用另一个方法,如果此时是不可重入的,那就死锁了。所以可重入锁的主要意义是防止死锁,我们的synchronized和Lock锁都是可重入的
    2. 不可重试
      • 我们编写的分布式锁只能尝试一次,失败了就返回false,没有重试机制。但合理的情况应该是:当线程获取锁失败后,他应该能再次尝试获取锁
    3. 超时释放
      • 我们在加锁的时候增加了TTL,这样我们可以防止死锁,但是如果卡顿(阻塞)时间太长,也会导致锁的释放。虽然我们采用Lua脚本来防止删锁的时候,误删别人的锁,但现在的新问题是没锁住,也有安全隐患
    4. 主从一致性
      • 如果Redis提供了主从集群,那么当我们向集群写数据时,主机需要异步的将数据同步给从机,万一在同步之前,主机宕机了(主从同步存在延迟,虽然时间很短,但还是发生了),那么又会出现死锁问题

Redisson入门 

  1. 导入依赖
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.6</version>
</dependency>

2.配置Redisson客户端,在config包下新建RedissonConfig

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RedissonConfig {@Beanpublic RedissonClient redissonClient() {Config config = new Config();config.useSingleServer().setAddress("redis://101.XXX.XXX.160:6379").setPassword("root");return Redisson.create(config);}
}

3.使用Redisson的分布式锁

@Resource
private RedissonClient redissonClient;@Test
void testRedisson() throws InterruptedException {//获取可重入锁RLock lock = redissonClient.getLock("anyLock");//尝试获取锁,三个参数分别是:获取锁的最大等待时间(期间会重试),锁的自动释放时间,时间单位boolean success = lock.tryLock(1,10, TimeUnit.SECONDS);//判断获取锁成功if (success) {try {System.out.println("执行业务");} finally {//释放锁lock.unlock();}}
}

4.替换我们上一期自己写的分布式锁

@Resource
private RedissonClient redissonClient;
@Override
public Result seckillVoucher(Long voucherId) {LambdaQueryWrapper<SeckillVoucher> queryWrapper = new LambdaQueryWrapper<>();//1. 查询优惠券queryWrapper.eq(SeckillVoucher::getVoucherId, voucherId);SeckillVoucher seckillVoucher = seckillVoucherService.getOne(queryWrapper);//2. 判断秒杀时间是否开始if (LocalDateTime.now().isBefore(seckillVoucher.getBeginTime())) {return Result.fail("秒杀还未开始,请耐心等待");}//3. 判断秒杀时间是否结束if (LocalDateTime.now().isAfter(seckillVoucher.getEndTime())) {return Result.fail("秒杀已经结束!");}//4. 判断库存是否充足if (seckillVoucher.getStock() < 1) {return Result.fail("优惠券已被抢光了哦,下次记得手速快点");}Long userId = UserHolder.getUser().getId();RLock redisLock = redissonClient.getLock("order:" + userId);boolean isLock = redisLock.tryLock();if (!isLock) {return Result.fail("不允许抢多张优惠券");}try {IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();return proxy.createVoucherOrder(voucherId);} finally {redisLock.unlock();}
}

Redisson可重入锁原理

为了保证原子性,所以流程图中的业务逻辑也是需要我们用Lua来实现的

  • 获取锁的逻辑
local key = KEYS[1]; -- 锁的key
local threadId = ARGV[1]; -- 线程唯一标识
local releaseTime = ARGV[2]; -- 锁的自动释放时间
-- 锁不存在
if (redis.call('exists', key) == 0) then-- 获取锁并添加线程标识,state设为1redis.call('hset', key, threadId, '1');-- 设置锁有效期redis.call('expire', key, releaseTime);return 1; -- 返回结果
end;
-- 锁存在,判断threadId是否为自己
if (redis.call('hexists', key, threadId) == 1) then-- 锁存在,重入次数 +1,这里用的是hash结构的incrby增长redis.call('hincrby', key, thread, 1);-- 设置锁的有效期redis.call('expire', key, releaseTime);return 1; -- 返回结果
end;
return 0; -- 代码走到这里,说明获取锁的不是自己,获取锁失败
  • 释放锁的逻辑
local key = KEYS[1];
local threadId = ARGV[1];
local releaseTime = ARGV[2];
-- 如果锁不是自己的
if (redis.call('HEXISTS', key, threadId) == 0) thenreturn nil; -- 直接返回
end;
-- 锁是自己的,锁计数-1,还是用hincrby,不过自增长的值为-1
local count = redis.call('hincrby', key, threadId, -1);
-- 判断重入次数为多少
if (count > 0) then-- 大于0,重置有效期redis.call('expire', key, releaseTime);return nil;
else-- 否则直接释放锁redis.call('del', key);return nil;
end;

下一期我们继续来讲:

基于Redis实现优惠券秒杀--秒杀优化

http://www.dtcms.com/wzjs/375850.html

相关文章:

  • 上海环球金融中心是日本人建的吗网站排名优化培训电话
  • 只做一种产品的网站凡科建站怎么收费
  • 青岛网站建设推广优化seo排名快速刷
  • 有网站做淘宝客沈阳网站关键字优化
  • 广东广东网站建设工作磁力岛引擎
  • 公司海外网站建设微信公众号怎么做文章推广
  • 云浮市哪有做网站的短视频推广渠道
  • wordpress响应式图片主题搜索引擎优化期末考试答案
  • 网站建设的原则 流程seo系统优化
  • ssm框架做网站的优势网上营销推广
  • 如何利用阿里云做网站百度网站收录提交
  • 做返利网站如何操作搜索引擎培训班
  • .net域名 可以做公司网站吗申请自媒体平台注册
  • 重庆网站平台建设河南专业网络推广公司
  • 佛山智能建站百度指数网页版
  • 新人跑业务怎么找客户青岛自动seo
  • 机械免费网站制作百度推广怎么操作
  • 网站布局模板外链seo服务
  • 手机网站弹出层插件有哪些营销策略都有哪些
  • 做网站常见程序火星时代教育培训机构学费多少
  • 深圳建网站找哪家win7优化软件
  • cms网站建设的方法房地产营销策略有哪些
  • 1688做网站需要多少钱深圳整站seo
  • 用网站源码做网站高端定制网站建设公司
  • 嵌入式培训机构排名信阳seo公司
  • 有什么做任务的网站吗手机建站
  • 高端网站设计报价表互联网推广软件
  • wordpress模板无法复制文件路径西安网站seo外包
  • 福州网站设计公司seo优化网络推广
  • 网站分几种类型公众号微博seo