代码编织梦想

一人一单优惠卷秒杀问题

(1)当用户抢购时,就会生成订单并保存到tb_voucher_order这张表中,而订单表如果使用数据库自增ID就存在一些问题:

  • id的规律性太明显
  • 受单表数据量的限制

场景分析:如果我们的id具有太明显的规则,用户或者说商业对手很容易猜测出来我们的一些敏感信息,比如商城在一天时间内,卖出了多少单,这明显不合适。

场景分析二:随着我们商城规模越来越大,mysql的单表的容量不宜超过500W,数据量过大之后,我们要进行拆库拆表,但拆分表了之后,他们从逻辑上讲他们是同一张表,所以他们的id是不能一样的, 于是乎我们需要保证id的唯一性。

全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具,一般要满足下列特性:
全局ID生成器**,是一种在分布式系统下用来生成全局唯一ID的工具,一般要满足下列特性:

在这里插入图片描述

为了增加ID的安全性,我们可以不直接使用Redis自增的数值,而是拼接一些其它信息:
在这里插入图片描述

ID的组成部分:符号位:1bit,永远为0

时间戳:31bit,以秒为单位,可以使用69年

序列号:32bit,秒内的计数器,支持每秒产生2^32个不同ID

-Redis实现全局唯一Id

@Component
public class RedisIdWorker {
    /**
     * 开始时间戳
     */
    private static final long BEGIN_TIMESTAMP = 1640995200L;
    /**
     * 序列号的位数
     */
    private static final int COUNT_BITS = 32;

    private StringRedisTemplate stringRedisTemplate;

    public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public long nextId(String keyPrefix) {
        // 1.生成时间戳
        LocalDateTime now = LocalDateTime.now();
        long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
        long timestamp = nowSecond - BEGIN_TIMESTAMP;

        // 2.生成序列号
        // 2.1.获取当前日期,精确到天
        String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        // 2.2.自增长
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);

        // 3.拼接并返回
        return timestamp << COUNT_BITS | count;
    }
}

(2)库存超卖问题分析

     假设线程1过来查询库存,判断出来库存大于1,正准备去扣减库存,但是还没有来得及去扣减,此时线程2过来,线程2也去查询库存,发现这个数量一定也大于1,那么这两个线程都会去扣减库存,最终多个线程相当于一起去扣减库存,此时就会出现库存的超卖问题。
     超卖问题是典型的多线程安全问题,针对这一问题的常见解决方案就是加锁:而对于加锁,我们通常有两种解决方案:见下图:
     ![在这里插入图片描述](https://img-blog.csdnimg.cn/eb168a544ae54aa99b70808644a06167.png#pic_center)

悲观锁:

悲观锁可以实现对于数据的串行化执行,比如syn,和lock都是悲观锁的代表,同时,悲观锁中又可以再细分为公平锁,非公平锁,可重入锁,等等

乐观锁:

乐观锁:会有一个版本号,每次操作数据会对版本号+1,再提交回数据时,会去校验是否比之前的版本大1 ,如果大1 ,则进行操作成功,这套机制的核心逻辑在于,如果在操作过程中,版本号只比原来大1 ,那么就意味着操作过程中没有人对他进行过修改,他的操作就是安全的,如果不大1,则数据被修改过,当然乐观锁还有一些变种的处理方式比如cas(比较和设置,无锁化机制加锁)

(3)优惠券秒杀-一人一单

需求:修改秒杀业务,要求同一个优惠券,一个用户只能下一单

现在的问题在于:

优惠卷是为了引流,但是目前的情况是,一个人可以无限制的抢这个优惠卷,所以我们应当增加一层逻辑,让一个用户只能下一个单,而不是让一个用户下多个单

具体操作逻辑如下:比如时间是否充足,如果时间充足,则进一步判断库存是否足够,然后再根据优惠卷id和用户id查询是否已经下过这个订单,如果下过这个订单,则不再下单,否则进行下单

存在问题: 现在的问题还是和之前一样,并发过来,查询数据库,都不存在订单,所以我们还是需要加锁,但是乐观锁比较适合更新数据,而现在是插入数据,所以我们需要使用悲观锁操作,在tianjia 方法上添加了一把synchronized 锁

但是这样添加锁,锁的粒度太粗了,在使用锁过程中,控制锁粒度 是一个非常重要的事情,因为如果锁的粒度太大,会导致每个线程进来都会锁住,所以我们需要去控制锁的粒度,以下这段代码需要修改为:只对当前用户对象访问此方法加锁,一个用户加一把锁。
intern() 这个方法是从常量池中拿到数据,如果我们直接使用userId.toString(),他拿到的对象实际上是不同的对象,new出来的对象,我们使用锁必须保证锁必须是同一把,所以我们需要使用intern()方法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/UpClear/article/details/127991315

java研发项目中遇到得问题_追梦的搬运工的博客-爱代码爱编程_项目中遇到的问题

   最近发现自己懒惰了,很久没有一直更新CSDN了。也不是说工作中项目很忙,而是自己没有按照自己得规定来做,以前说得是一天更新一篇文章,后来,发现一天更新,自己更加没有精力去弄。就说一周更新一天,发现还是无法去实践。但是为了让自己能力提升,还是需要严格得要求自己,提升自己。毕竟从毕业到现在也是四年多了,从事JAVA开发也是五年多,如果对自己能力没有提升得

软件项目管理存在的问题及改进措施_weixin_38813065的博客-爱代码爱编程_项目管理的不足及改进的地方

软件项目管理存在的问题及改进措施 随着计算机应用范围的日益广泛深人,应用软件的规模及复杂程度也日趋大型化、复杂化,这就导致软件开发的方式也从早期的单兵作战式或手工作坊式渐渐转变为集团

项目开发过程中遇到的问题_mayue_csdn的博客-爱代码爱编程_项目开发中遇到的问题

问题分类: 1、逻辑问题:结构、处理流程的设计有问题,尤其在多线程操作同一个对象时; 2、接口定义和使用问题:例如接口结构或返回情况改了,未及时编译或更改其他模块的调用; 3、对接问题:对讲问题不是你的问题,就是我的问题,需

项目中遇到的问题及解决方式_行万里路,读万卷书的博客-爱代码爱编程_在项目中遇到的问题和解决方案

问题一:下位机反馈的数据显示不实时 解决方案: (1)先测试上位机发送的指令包是否正确(可以用弹框或打印指令包的方式检测) (2)在1的基础上,再检查上位机的指令包是否能下发到下位机(即网络是否畅通,下位机软件添加探针显示上

vue项目总结,项目期间遇到的问题、难点等。【暂停更新】-爱代码爱编程

近期一直在做一个xxx中心的项目,先来吐槽下内心的想法, 要开发的项目需求很不明确,需求两周两周的更改,感觉每天并没有特别多实际的产出,总是感觉有点儿浪费时间。 虽然这样,但是作为开发,我们只能服从上级命令,好了,进入正题。 但是对我来说,感觉还好,需求的更改,对我来说又是新的开发,新的接触,同时也是在锻炼我的耐心和耐性。 ------------

浅谈个人前端项目中遇到的问题-爱代码爱编程

该文章中我吧自己在做项目中的问题、如何解决方式以及一些经验分享给大家。问题一:没有随手写上注释的习惯 一个项目中的代码是非常之多的,当你需要找到某些代码的时候没有注释的帮助会很麻烦,从而会影响心情导致思路不流畅。所以给自己的每一段代码写上注释就会显得很方便,问题二:没有边写边看的习惯。 前端工程师比较忌讳先写完整体html代码再写CSS及JS,因为那样会导

React项目中遇到的问题及部分优化-爱代码爱编程

React项目中遇到的问题及部分优化 问题: 1、错误:Unable to preventDefault inside passive event listener invocation. 意思是:无法防止被动事件侦听器调用中的默认值。 解决办法:将相关代码注释掉 2、 解决方案 去掉 React.StrictMode 改为 3、当点击分类是,跳转到分

java开发中遇到的问题及解决方法-爱代码爱编程

一、文件路径问题大集合 1、System.getProperty("user.dir")    #获取当前项目文件夹在磁盘上的绝对路径(java命令执行的地方) 2、File tmpFile = new File("/tmp/tomcat");   #这样会在当前项目所在磁盘的根路径下创建该文件夹 3、File tmpFile = new File(

做前端项目遇到的一些问题及解决办法-爱代码爱编程

前端开发遇到的一些问题 一、怎样才能让select里的内容居中显示?二、点击一个select里面的一个option,向另一个select添加一组option用js怎么实现?三、点击select里不同的option时如何显示不同的内容(文本、表格、echarts图表等)? 一、怎样才能让select里的内容居中显示? 最近在做一个可视化项目,有

java项目遇到难题_Java项目遇到的常见问题-爱代码爱编程

做Java算是新手吧,难免会遇到一些问题,生活中不乏各种各样的问题,乏的是记录下来的博客O(∩_∩)O 问题一、 DescriptionResourcePathLocationType Java compiler level does not match the version of the instal 解决: 一、设置jdk版本,windo

java 项目中遇到的问题 和解决方案_Java开发遇到的问题及解决方案-爱代码爱编程

一、java.lang.OutOfMemoryError 问题:myeclipse 内存不足,又显示内存溢出等问题怎么回事?(java.lang.OutOfMemoryError: PermGen space及其解决方法) 解决: myeclipse内存溢出之后,可以通过修改虚拟内存大小来解决,步骤如下: 1、设置Default VM

被问到项目亮点、难点、遇到的问题、解决思路-爱代码爱编程

面试中被问到你的项目亮点、难点、遇到的问题、解决思路是不是很蒙,现在我拆分一下问题 什么是项目亮点: 你负责的业务是什么?(学会发现问题) 你真的想过业务是什么吗?有为业务想过什么吗?有了你,业务有什么不同吗?能不能几分钟说明白,你负责的业务是什么?可有想过有没有说到位,甚至答非所问这里谈谈我个人对业务的理解,或许没有普遍意义,所以仅供参考。 提示

react项目中遇到的几个问题-爱代码爱编程

react项目中遇到的几个问题 前言 由于我之前有过react经验,同事之前做react项目时问了我一些问题,其中几个问题虽然常见,但时间长了还是容易忘记,这里简单总结一下 问题一: 如何保证定时器(setTimeout与setInterval)每次执行与下一次执行都保证相同的间隔时间,不管前一次运行了多长时间 场景: 例如需要每间隔1

项目中常出现的问题及解决-爱代码爱编程

常见的问题及风险点 在项目进行中甲方或是内部人员不断提出新需求。活动并行对工作范围不熟悉或WBS不熟悉项目经理或团队人员签订项目文档某些问题过了很久才发现项目经理编写发布项目章程发布外包商交付结果不及期望技术人员产出成果情况不及期望核心人员离职项目成员身兼数职士气低落客户投诉项目中发生争吵赶工,加班一类时间/工期紧张推诿扯皮项目成员出现不满意的状况验收不

前端人真实项目中遇到的问题总结-爱代码爱编程

// 以下题目有简单也有难的(具体看你怎么定义)。 // 如果能做到立马想出答案的,则前端算是学的不错的了。 // 如果需要百度才能做出来(直接百度答案的,我就只能说你开心就好),那么也说明一般。 // 如果一点都不会并且百度都不会,那就自己问一下自己究竟学了啥? // 以下都是两年前端人真实项目中遇到的问题(在此只是抽取出来了),在此分享给各位学弟学妹,

java面试问项目中遇到的问题,涨知识-爱代码爱编程

前言 很多人面试之前,可能没有在互联网公司工作过或者说工作过但年头较短,不知道互联网公司技术面试都会问哪些问题? 再加上可能自己准备也不充分,去面试没几个回合就被面试官几个问题打蒙了,最后以惨败收场。针对这些的同学,在这分享总结的Java面试的高频面试题(包括了Java集合,JVM,并发与多线程,Spring,MyBaits,微服务,Dubbo,Kakf

前段项目中遇到的最大问题是什么,该如何回答_m-codes的博客-爱代码爱编程

1 业务简单 由于之前的业务呢,相对来说比较常规,没有遇到太大的困难呢。但是比较期待在今后的工作中遇到一些难题,因为这样才能使我成长 2 业务复杂 不能说的特别简单 uni-app刚出来的时候,官方文档和软件bug很多,没有相关文档告知bug如何解决, 小程序,微信端嵌入HTML网页跳转链接URL参数丢失问题。解决方法:对