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

2015微信网站设计广州公司网站提供

2015微信网站设计,广州公司网站提供,潍坊网站建设求职简历,毕业设计怎么做网站各位小伙伴们大家好#xff0c;欢迎来到这个小扎扎的Redis 6专栏#xff0c;在这个系列专栏中我对B站黑马的Redis教程进行一个总结#xff0c;鉴于 看到就是学到、学到就是赚到 精神#xff0c;这波依然是血赚 ┗|#xff40;O′|┛ #x1f4a1;Redis知识点速览#… 各位小伙伴们大家好欢迎来到这个小扎扎的Redis 6专栏在这个系列专栏中我对B站黑马的Redis教程进行一个总结鉴于 看到就是学到、学到就是赚到 精神这波依然是血赚 ┗|O′|┛ Redis知识点速览 全局唯一ID 业务逻辑分析 代码实现 优惠券秒杀 业务逻辑分析 代码实现 定量商品多卖问题 业务逻辑分析 乐观锁与悲观锁 乐观锁代码实现 一个用户限买一单 业务逻辑分析 代码实现 全局唯一ID 业务逻辑分析 全局唯一ID是针对销量比较大的一些商品而言的这类商品的成交量比较多用户购买成功就会生成对应订单信息并保存到一张表中而订单表的id如果使用数据库自增ID就存在一些问题比如说id的规律性太强导致安全性极低还有如果订单数量太多一张表存不下分成多张表存储的话就会出现ID冲突问题于是我们需要一个全局ID生成器保证ID在全局中都是唯一的 使用Redis即可完成这种全局ID生成器的功能具体实现就是一种类雪花算法也就是符号位、时间戳、序列号三部分拼接形成一个ID逻辑就是符号位0代表整数时间戳确定具体到下订单的时候是哪一秒至于序列号就是用于区分这一秒的订单序列号使用redis的值自增来保证所有序列号不一致原则上一秒中最多可以有232个不同的ID 代码实现 /*** author : mereign* date : 2022/5/11 - 14:06* desc : 全局ID生成器*/Component public class RedisIdGenerator {/*** 构造方法注入stringRedisTemplate对象*/private StringRedisTemplate stringRedisTemplate;public RedisIdGenerator(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate stringRedisTemplate;}// 定义序列号的位数private static final int COUNT_BITS 30;public long nextId(String keyPrefix) {// 生成从指定时间到现在的时间戳LocalDateTime beginTime LocalDateTime.of(2022, 1, 1, 0, 0, 0);long beginTimeStamp beginTime.toEpochSecond(ZoneOffset.UTC);long endTimeStamp LocalDateTime.now().toEpochSecond(ZoneOffset.UTC);long timeStamp endTimeStamp - beginTimeStamp;/*** 生成序列号 使用redis的incr方法 K值为icr: keyPrefix : date* 也就是按照日期作为K 每下一次单V就自增1作为序列号添加到后面* 这样的话既避免了K固定带来的V超过最大阈值(redis中的V最大为2^64)* 而且还方便了统计一天、一个月、一年的订单量在这段时间内最大的序列号就是它的最多订单数*/String date LocalDateTime.now().format(DateTimeFormatter.ofPattern(yyyy:MM:dd));Long sequenceId stringRedisTemplate.opsForValue().increment(icr: keyPrefix : date);// 拼接生成全局唯一ID并返回 两个二进制的拼接可以使用前一个数左移一定位数 后一个数与位移后的进行或运算return timeStamp COUNT_BITS | sequenceId;} }优惠券秒杀 业务逻辑分析 用户对秒杀商品下单的时候后台业务需要先完成对商品时间的判断判断该商品的秒杀活动是否开始或者有没有结束但凡还未开始或者已经结束都无法下单时间信息正确的话就判断该商品的活动库存还有没有剩余如果已经卖完的话也无法下单。时间和库存的判断都是通过前端传过来的优惠券id查出来该优惠券的时间和库存信息如果条件都满足的话将该商品券的库存扣除然后创建订单返回订单id 代码实现 controller层主要就是调用service接口里的secKillVoucher方法所以整个业务逻辑代码全部都在接口的实现类中完成 Resource private ISeckillVoucherService seckillVoucherService;Resource private RedisIdGenerator generator;Override Transactional public Result secKillVoucher(Long voucherId) {// 查询优惠券SeckillVoucher seckillVoucher seckillVoucherService.getById(voucherId);// 获取时间 判断秒杀活动是否开始或者结束if (seckillVoucher.getBeginTime().isAfter(LocalDateTime.now())) {return Result.fail(活动暂未开始);} else if (seckillVoucher.getEndTime().isBefore(LocalDateTime.now())) {return Result.fail(活动已经结束);}// 判断库存是否充足if (seckillVoucher.getStock() 1) {return Result.fail(库存不足活动结束);}// 扣减库存seckillVoucherService.update().setSql(stock stock - 1).eq(voucher_id, voucherId).update();// 创建订单 并返回idVoucherOrder order new VoucherOrder();// 订单id(redis全局唯一id) 下单用户id(拦截器中做登录验证的用户id) 优惠券id(直接传过来的id)long orderId generator.nextId(order);order.setId(orderId);order.setUserId(UserHolder.getUser().getId());order.setVoucherId(voucherId);save(order);return Result.ok(orderId); }定量商品多卖问题 业务逻辑分析 像上面的优惠券秒杀的业务优惠券或者商品的数量一般都是固定的如果把这些数量都卖完之后应该就结束这个活动。但是现实中的秒杀业务都是多线程的很多的用户同时等着活动开启一起点击下单这样的话就极有可能出现线程安全问题也就是说最终成交的数量要多于活动商品的数量 上述问题出现的原因就是多线程之间的执行顺序所引起我们的秒杀业务里面是先查询库存数量大于1就产生订单但是多线程之间的执行不会严格的按照这个顺序执行而是交叉执行如果最后只剩一张票的时候进来了两个线程ABA查完B查AB查询结果都可以下单A产生订单B再产生订单此时就已经产生超卖 乐观锁与悲观锁 解决线程问题的最好方法就是加锁但是锁也分为悲观锁和乐观锁悲观锁认为线程安全问题一定会发生因此在操作数据之前先获取锁确保线程串行执行例如Synchronized、Lock等。乐观锁认为线程安全问题不一定会发生因此不加锁只是在更新数据时去判断有没有其它线程对数据做了修改如果没有修改则更新数据修改说明发生了安全问题 很显然乐观锁的性能要显著高于悲观锁因此采用乐观锁保证线程的原子性。乐观锁又有两种解决方案版本号是指对修改的数据附带一个version字段值每次更新的时候判断修改时的version与查询的时候是否一致一致则修改。CAS机制全称为Compare And Swap译为先比较再交换也就是将修改的数据本身作为版本号每次更新的时候判断修改时的数据值与查询时的值是否相同相同则修改不同就说明发生了线程安全问题在我们的这个售卖业务中可以设置成只要库存大于0就可以执行成功 乐观锁代码实现 乐观锁的核心就是在更新数据的时候(也就是减少库存)判断一下库存是否大于0如果判断失败的话也应该使该线程任务失败 // 扣减库存 boolean update seckillVoucherService.update().setSql(stock stock - 1).eq(voucher_id, voucherId).gt(stock, 0).update(); // 更新失败说明在扣除库存的时候 库存小于等于0 if (!update) {return Result.fail(库存不足); }一个用户限买一单 业务逻辑分析 按照正常的业务逻辑秒杀应该限制一个用户只能购买一次该商品最简单的方法就是对user_id使用唯一索引如果user_id重复就会抛出相关异常但是这需要修改表结构。如果不修改标结果的话就需要扣除库存之前根据voucher_id和user_id查询订单表如果存在的话就返回错误否则说明该用户还未购买 代码实现 单机(服务部署在一台tomcat服务器)的情况下加synchronized 锁即可解决查询判断用户是否下单和创建订单业务的线程安全问题但是这种情况就只能 // 单用户id(拦截器中做登录验证的用户id) Long userId UserHolder.getUser().getId();// 根据user_id加锁 intern方法是去字符常量池中查找值相同的不加的话字符串值一样的地址不一样也会加上锁 synchronized (userId.toString().intern()) {// 查询优惠券// 判断库存是否充足// user_id和voucher_id联合查询订单数Integer count query().eq(user_id, userId).eq(voucher_id, voucherId).count();// 订单数为1 就说明已经下过单了if (count.equals(1)) {return Result.fail(您已经购买过该商品了);}// 扣减库存 创建订单return Result.ok(orderId); }以上加synchronized 锁的解决方案只适用于单机模式下此时所有的请求过来都会按照userId去常量池中查找是否一致一致的话就锁在一起防止一个用户购买多单。但是集群模式下所有的请求会经过Nginx的负载均衡轮询发送到集群上的所有服务器如果一个用户的多个请求被分配到不同的服务器上的话不同服务器中的JVM虚拟机里的静态常量池中的内容是不同步的这样的话就会导致虽然userId一致但是各自所在的静态常量池中都没有于是这个用户就可以在不同的服务器分别下单了。如果有用户使用脚本同时发送很多的下单请求那么就会有极大的可能在每一个服务器中都下一单那么如何解决这个问题呢那就要学习分布式锁的内容了
http://www.zqtcl.cn/news/468616/

相关文章:

  • 上海网站排名团队推广链接跳转
  • 寻找郑州网站优化公司上海高端网站定制
  • 网站关键词排名优化长城建设投资有限公司网站
  • 网站专题优化电子商务网站运营方案
  • 唐山建网站公司湖南网站制作电话
  • 做神马网站优化合肥城乡建设局官网
  • 网站开发与管理心得体会建设高流量网站
  • 网站安全建设的重要性减粘装置设备设计要点
  • 建设一个网站的所有代码Django和wordpress速度
  • 临沂市建设局网站公示php建站系统
  • 有哪些好的做问卷调查的网站好学的专业是编课 网站开发英语翻译
  • 个人网站免费推广广饶网站制作
  • 怎么检测网站是否安全拍卖网站开发
  • 沂源网站制作自建网站的流程
  • 网站关键词收录查询网站最好服务器
  • 做百度移动网站优网站建设类论文选题
  • 自己做的网站怎样让百度搜到长沙专业外贸建站公司
  • 上海缔客网站建设公司网站策划书内容不包括什么
  • 找团队做网站网站建设 通知
  • 网站标题上的小图标怎么做的霞浦建设局网站
  • 国外那些网站做展厅比较好vp代理商网站管理系统
  • 广州最大网站建设wordpress数字超市
  • 怎么提高网站seo优化关键字排名wordpress媒体库搜索
  • 伊春网站制作怎么做视频网站赚钱吗
  • 前端网站开发邹城住房城乡建设部网站
  • 淘宝u站怎么做网站的网站建设费 科研 类
  • 代点任意广告链接网站怎样做才能让百度搜到网站产品
  • 宿迁网站搭建南宁建设局
  • app官网入口昆明排名优化
  • 新乡网站建设开发wordpress如何添加一个文章列表页