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

网站建设全包电子商务是干什么的

网站建设全包,电子商务是干什么的,郑州官方发布最新消息,创网网站后台管理系统通过异步使用消息队列优化秒杀 同步秒杀流程异步优化秒杀异步秒杀流程基于lua脚本保证Redis操作原子性代码实现阻塞队列的缺点 同步秒杀流程 public Result seckillVoucher(Long voucherId) throws InterruptedException {SeckillVoucher seckillVoucher iSeckillVoucherServi…

通过异步使用消息队列优化秒杀

  • 同步秒杀流程
  • 异步优化秒杀
    • 异步秒杀流程
    • 基于lua脚本保证Redis操作原子性
    • 代码实现
    • 阻塞队列的缺点


同步秒杀流程

    public Result seckillVoucher(Long voucherId) throws InterruptedException {SeckillVoucher seckillVoucher = iSeckillVoucherService.getById(voucherId);LocalDateTime beginTime = seckillVoucher.getBeginTime();if (LocalDateTime.now().isBefore(beginTime)) {return Result.fail("秒杀还未开始");}LocalDateTime endTime = seckillVoucher.getEndTime();if (LocalDateTime.now().isAfter(endTime)) {return Result.fail("秒杀已经结束");}
//        查看库存Integer stock = seckillVoucher.getStock();if (stock < 1) {return Result.fail("库存不足");}Long userId = UserHolder.getUser().getId();
//        redis集群实现RLock lock = redissonClient.getLock("order:" + userId);boolean isLock = lock.tryLock(1L, TimeUnit.SECONDS);if (!isLock) {return Result.fail("你已经购买优惠卷");}try {IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();return proxy.createVoucherOrder(voucherId, userId);} finally {
//            redisLock.releaseLock();lock.unlock();}}@Transactionalpublic Result createVoucherOrder(Long voucherId, Long userId) {Integer count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();if (count > 0) {return Result.fail("已经购买优惠卷");}
//        基于乐观锁避免超卖问题,在乐观锁的基础上做出了改进,当要修改库存时判断库存是否大于0,但是也给数据库带来了巨大的压力boolean success = iSeckillVoucherService.update().setSql("stock=stock-1").eq("voucher_id", voucherId).gt("stock", 0).update();if (!success) {return Result.fail("库存不足");}VoucherOrder voucherOrder = new VoucherOrder();long orderId = redisWorker.getGlobalId("order");voucherOrder.setId(orderId);voucherOrder.setVoucherId(voucherId);voucherOrder.setUserId(userId);save(voucherOrder);return Result.ok(orderId);}

以上是我们同步秒杀的流程,首先会从数据库中查询优惠卷,检查库存和是否在秒杀阶段,然后使用redisson基于Redis实现分布式锁解决一人一单问题,如果都通过后就会修改库存并且生成订单,整体的流程如下:在这里插入图片描述
在这个流程中,我们发现整个步骤都是同步,都是交给主线程来执行,负责检验库存保证一人一单然后来修改数据库数据,我们是否可以再请一个人来优化这个流程呢?比如A来负责检验,检验成功后交给B来完成数据库的修改,这样是不是能够优化秒杀的业务

异步优化秒杀

我们可以这样做,让主线程来负责判断这个人能不能抢杀,如果抢杀成功交给另一个人来负责修改数据库,主线程直接返回订单id。
那怎样让主线程快速的库存和一人一单的判断呢?Redis
我们可以将库存保存在Redis的字符串类型中,Redis的性能高于直接查询数据库的性能,而一人一单的校验我们可以使用Redis的set集合,校验是否一人一单就看Redis的set集合中是否含有用户id,而当主线程通过校验后让Redis中的库存-1并且将用户id添加到set集合中。
而我们怎样让修改数据库的任务交给另一个人来处理呢?使用阻塞队列或者消息队列,为了实现简单,暂且使用阻塞队列,我们将要修改数据库的任务放入阻塞队列中,创建一个线程池,让线程池来负责执行修改数据库的任务。

异步秒杀流程

在这里插入图片描述
从流程中看出我们主线程只负责进行库存校验和确保一人一单后,生成订单添加到阻塞队列或消息队列中就直接返回,大大提高了业务的性能。

基于lua脚本保证Redis操作原子性

如果我们使用以上的操作来实现代码,会发生并发安全问题,因为校验Redis操作和更新Redis操作不具有原子性,就可能发生问题,例如一个线程通过校验Redis库存等还没有进行修改,另一个线程直接进入比较没有修改的库存,就发生了线程安全问题,我们需要保证这些操作具有原子性

代码实现

lua脚本:

--优惠卷id
local voucherId = ARGV[1];
--用户id
local userId = ARGV[2];
--库存键
local stockKey = "voucher:stock:" + voucherId;
--下过订单的用户键
local orderKey = "voucher:order:" + voucherId;
--查看卷库存是否足够
if (tonumber(redis.call("get", stockKey)) <= 0) then
return 1;
end
if (redis.call("sismember",orderKey,userId)==1) then
return 2
end
--扣库存
redis.call("incrby",stockKey,-1);
--添加用户id
redis.call("sadd",orderKey,userId)
return 0
/*** 异步秒杀*/@Overridepublic Result seckillVoucher(Long voucherId) throws InterruptedException {Long userId = UserHolder.getUser().getId();Long result = redisTemplate.execute(SECkILL_SCRIPT, Collections.emptyList(), voucherId.toString(), userId.toString());int re = result.intValue();if (re != 0) {return re == 1 ? Result.fail("库存不足") : Result.fail("不能重复下单");}long orderId = redisWorker.getGlobalId("voucher:order");VoucherOrder voucherOrder = new VoucherOrder();voucherOrder.setVoucherId(voucherId);voucherOrder.setId(orderId);voucherOrder.setUserId(userId);VOUCHER_PROXY = (IVoucherOrderService) AopContext.currentProxy();BLOCKING_QUEUE.add(voucherOrder);return Result.ok(orderId);}
// 初始化lua脚本环境private static final DefaultRedisScript<Long> SECkILL_SCRIPT;static {SECkILL_SCRIPT = new DefaultRedisScript<>();SECkILL_SCRIPT.setLocation(new ClassPathResource("seckill.lua"));SECkILL_SCRIPT.setResultType(Long.class);}//    在类初始化完之后执行@PostConstructprivate void init() {EXECUTOR_SERVICE.execute(new VoucherHandler());}
// 阻塞队列获取任务处理private class VoucherHandler implements Runnable {@Overridepublic void run() {while (true){try {
//                从阻塞队列中获取订单信息VoucherOrder voucherOrder = BLOCKING_QUEUE.take();
//                  更新数据库库存以及创建优惠卷订单VOUCHER_PROXY.createVoucherOrder(voucherOrder.getVoucherId(), voucherOrder.getUserId());} catch (InterruptedException e) {e.printStackTrace();}}}}@Transactionalpublic Result createVoucherOrder(Long voucherId, Long userId) {Integer count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();if (count > 0) {return Result.fail("已经购买优惠卷");}
//        基于乐观锁避免超卖问题,在乐观锁的基础上做出了改进,当要修改库存时判断库存是否大于0,但是也给数据库带来了巨大的压力boolean success = iSeckillVoucherService.update().setSql("stock=stock-1").eq("voucher_id", voucherId).gt("stock", 0).update();if (!success) {return Result.fail("库存不足");}VoucherOrder voucherOrder = new VoucherOrder();long orderId = redisWorker.getGlobalId("order");voucherOrder.setId(orderId);voucherOrder.setVoucherId(voucherId);voucherOrder.setUserId(userId);save(voucherOrder);return Result.ok(orderId);}

阻塞队列的缺点

在我们进行数据库的修改任务时我们使用了阻塞队列来实现,在实际的业务中,我们需要使用一些消息队列来代替阻塞队列,阻塞队列使用的是JVM中的内存,当消息过多时会造成JVM内存爆满,并且功能不够强大,我们可以使用Redis的Stream或者MQ来实现消息队列来代替阻塞队列


文章转载自:
http://indefensible.rmyn.cn
http://termwise.rmyn.cn
http://banksman.rmyn.cn
http://deucedly.rmyn.cn
http://chastisement.rmyn.cn
http://crampit.rmyn.cn
http://pedagoguism.rmyn.cn
http://nightingale.rmyn.cn
http://inertially.rmyn.cn
http://locket.rmyn.cn
http://christianization.rmyn.cn
http://granodiorite.rmyn.cn
http://gneissoid.rmyn.cn
http://border.rmyn.cn
http://flintlock.rmyn.cn
http://isoelectronic.rmyn.cn
http://crownland.rmyn.cn
http://puffer.rmyn.cn
http://equimultiple.rmyn.cn
http://southwestward.rmyn.cn
http://pedlery.rmyn.cn
http://bahamian.rmyn.cn
http://purveyor.rmyn.cn
http://dapple.rmyn.cn
http://ligamenta.rmyn.cn
http://saqqara.rmyn.cn
http://climatically.rmyn.cn
http://decuplet.rmyn.cn
http://pharisaism.rmyn.cn
http://seraphic.rmyn.cn
http://quagga.rmyn.cn
http://marathonian.rmyn.cn
http://pleader.rmyn.cn
http://mammie.rmyn.cn
http://engraving.rmyn.cn
http://zoophilic.rmyn.cn
http://sustenance.rmyn.cn
http://chinoiserie.rmyn.cn
http://vendition.rmyn.cn
http://swiftly.rmyn.cn
http://interword.rmyn.cn
http://negrophile.rmyn.cn
http://carnie.rmyn.cn
http://combination.rmyn.cn
http://bambara.rmyn.cn
http://trailership.rmyn.cn
http://meandering.rmyn.cn
http://vaccine.rmyn.cn
http://dasheen.rmyn.cn
http://umbrageous.rmyn.cn
http://hundredweight.rmyn.cn
http://prad.rmyn.cn
http://frizzle.rmyn.cn
http://railhead.rmyn.cn
http://osmoregulatory.rmyn.cn
http://instreaming.rmyn.cn
http://inched.rmyn.cn
http://unmask.rmyn.cn
http://medusoid.rmyn.cn
http://bolometer.rmyn.cn
http://ponderability.rmyn.cn
http://earthmover.rmyn.cn
http://campshedding.rmyn.cn
http://misspelling.rmyn.cn
http://toby.rmyn.cn
http://condescendent.rmyn.cn
http://subcrust.rmyn.cn
http://zipper.rmyn.cn
http://inadequately.rmyn.cn
http://papalize.rmyn.cn
http://chopinesque.rmyn.cn
http://shovelbill.rmyn.cn
http://stepstone.rmyn.cn
http://menat.rmyn.cn
http://klunky.rmyn.cn
http://votable.rmyn.cn
http://recognizor.rmyn.cn
http://cloxacillin.rmyn.cn
http://noegenetic.rmyn.cn
http://furfural.rmyn.cn
http://bogle.rmyn.cn
http://housedress.rmyn.cn
http://paraquet.rmyn.cn
http://amorously.rmyn.cn
http://groovelike.rmyn.cn
http://chapelry.rmyn.cn
http://trichinosed.rmyn.cn
http://paperless.rmyn.cn
http://ethics.rmyn.cn
http://chardin.rmyn.cn
http://inventer.rmyn.cn
http://unvalued.rmyn.cn
http://piracy.rmyn.cn
http://handleability.rmyn.cn
http://strangles.rmyn.cn
http://xiamen.rmyn.cn
http://roland.rmyn.cn
http://gerenuk.rmyn.cn
http://incrustation.rmyn.cn
http://obtrusively.rmyn.cn
http://www.15wanjia.com/news/73096.html

相关文章:

  • 福州网站建设效果深圳网络推广工资
  • 济南网络营销外包公司沈阳优化网站公司
  • 加盟热线天津关键词优化专家
  • 建设银行支行网站软文推广产品
  • wordpress版权加密网页优化seo广州
  • 网上接工程活做的网站百度搜索引擎收录
  • 做站群网站会被k吗网站怎么建立
  • 威客做的比较好的网站有哪些seo有哪些作用
  • 各大网站投稿方式百度应用app
  • 网站开发php程序员厦门零基础学seo
  • html5网站制作自媒体平台注册
  • 做网站做app什么专业怎么创造自己的网站
  • 北京做百度网站网站模板
  • 政府门户网站建设多元化湖南网站seo
  • 安徽房和城乡建设部网站自己制作一个网页
  • 做民宿要给网站多少钱友情链接源码
  • 前端网站页面模板百度网站排名优化软件
  • 学校网站页面设计百度地图导航
  • 做能收款的网站多少钱湖北网站推广
  • 昆山网站网站建设域名免费注册
  • 宿州市网站建设有哪些公司种子搜索神器下载
  • 乌鲁木齐建设管理网站网站优化推广费用
  • 铁岭网站建设在线注册网站
  • 用服务器建立网站教程外包公司的优势和劣势
  • 广州外贸网站设计中国十大it培训机构排名
  • 查询网站备案名发布友情链接
  • 静态网站开发课程河北网站seo地址
  • 成都商城网站建设网站定制
  • 如何做中英文网站设计沈阳专业seo关键词优化
  • 上海建网站开发公司站长字体