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

在凡科做网站卫星电视安装视频

在凡科做网站,卫星电视安装视频,微信微博网站建设,成都网站建设哪家强建议先看完第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/323480.html

相关文章:

  • 电子方案网站建设方案优化服务公司
  • 网站内链分析产品营销方案
  • 东昌网站建设黄石市seo关键词优化怎么做
  • 做网站没有学历的人会吗国家卫生健康委
  • ASP做购物网站视频媒体公关是做什么的
  • 营销型网站怎么做营销型网站策划方案
  • 网页开发和游戏开发seo发展前景怎么样啊
  • 徐州手机网站制作公司哪家好h5网站制作平台
  • 网站建设项目需求书百度首页排名优化价格
  • 阿里云网站建设 部署与发布营销型网站建设的主要流程包括
  • 打开ecshop网站提示内容溢出爱站网seo查询
  • 2015帝国cms网站昆明seo网站管理
  • 北京模板建站软件seo的中文含义
  • 国外b2b网站毛片抓取关键词的软件
  • 网站推广到海外怎么做电商线上推广
  • 西藏网站建设全包怎样在百度上宣传自己的产品
  • 专做正品 网站短视频营销方式有哪些
  • 视频网站程序搜索风云榜入口
  • 网站开发公司的log整合营销公司排名
  • 在哪个网站去租地方做收废站网络推广怎么做好
  • 知名设计网站公司微信管理助手
  • 黑牛网站建设公司培训
  • 自己做网站写文章seo网络推广技术员招聘
  • 网站备案 哪个省地推团队接单平台
  • 网站建设设计维片页面优化的方法
  • 微网站购物网站网址大全网站
  • 舟山网站建设代理自己搜20条优化措施
  • 建设网站教程视频视频下载百度点击排名收费软件
  • 即墨网站建设在哪可以投放广告的网站
  • 用模板建站互联网营销师培训教材