• 杨俊
    2019-07-30
    我的理解是库存放缓存,用户提交订单在缓存扣减库存,用户端能够快速返回显示订单提交成功并支付,然后只有支付成功之后才会利用队列实际的扣减数据库库存是吗?要是不支付会在缓存补回库存吧,应该会限时支付吧

    作者回复: 对的

    
     6
  • QQ怪
    2019-07-30
    在网关层中把请求放入到mq中,后端服务从消费队列中消费消息并处理;或者用有固定容量的消费队列的令牌桶,令牌发生器预估预计的处理能力,匀速生产放入令牌队列中,满了直接丢弃,网关收到请求之后消费一个令牌,获得令牌的请求才能进行后端秒杀请求,反之直接返回秒杀失败

    作者回复: 大家都一致想到了限流,限流是非常必要的,无论我们的程序优化的如何,还是有上限的,限流则是一种兜底策略。

    除了这个,我们还可以使用协程来优化线程由于阻塞等待带来的上下文切换性能问题,可以回顾第19讲,我们也用协程实现过生产者消费者模式。

     4
     3
  • Jxin
    2019-07-31
    1.生产消费模式用信号量也能玩。
    2.生产者这边的优化思路应该是提高响应速度和增加资源。提高响应速度就是尽量降低生产逻辑的耗时,增加资源就是根据业务量为该生产者单独线程池并调整线程数。至于限流和令牌桶感觉都是降级处理,属于规避阻塞场景而非解决阻塞场景,应该不在答案范围内吧。
    3.对于进程内生产消费模式,大规模,量大的数据本身就不适合,毕竟内存空间有限,消息堆积有限,所以量级达到一定指标就采用跨进程方式,比如kafka和rocketmq。同时,进程内生产消费模式,异常要处理好,不然可能会出现消息堆积和脏数据,毕竟mq的消费确认和重试机制都是开箱即用,而我们得自己实现和把关。

    作者回复: 看来有实战经验👍🏻

    
     2
  • 撒旦的堕落
    2019-07-30
    网关与服务之间增加令牌桶 或者mq 以保护秒杀服务不会被大的流量压垮 可以么

    作者回复: 可以的,很通用的一种解决方案

    
     1
  • 奋斗的小白鼠
    2019-12-04
    老师,您那个第二个生产者消费者模式实现我运行了会出现线程安全问题的,而且线程还一直阻塞停止不了运行,我感觉您的本意是想实现和LinkedBlockingQueue一样的模式,两把锁,您测试时没出现问题过吗?
    
    
  • neohope
    2019-11-24
    看大家都提到了用令牌筒和MQ做限流和熔断。其实当并发量更大时,还有一种方式,但要牺牲一定的公平性。首先根据一些相对公平的规则,事先做一次资源分配。也就是对用户分组,预先分配一部分资源,每组用户抢夺组内资源。
    
    
  • 赤城
    2019-11-13
    请问老师,电商库存的并发问题是否可以使用CountDownLatch来实现呢,感觉实现起来更简单,毕竟库存只是一个数量,不必用一个数组来表示。
    
    
  • 2102
    2019-10-19
    增加消费者

    作者回复: 增加消费者是一种方式

    
    
  • 哲锄
    2019-09-23
    LinkedList 的 add 和 removeLast 方法都有可能操作 first 引用,存在线程安全问题吧?

    作者回复: LinkedList是非线程安全容器,存在线程安全问题的

    
    
  • 风轻扬
    2019-09-15
    lockInterruptibly()。老师,为啥要用这个API,不用lock。我查了一下,两者的区别是:前者侧重于中断,后者侧重于获取锁。这个地方,您是怎么考虑的呢?
    
    
  • godtrue
    2019-09-12
    课后思考及问题
    我们可以用生产者消费者模式来实现瞬时高并发的流量削峰,然而这样做虽然缓解了消费方的压力,但生产方则会因为瞬时高并发,而发生大量线程阻塞。面对这样的情况,你知道有什么方式可以优化线程阻塞所带来的性能问题吗?
    1:减少生产者的流量压力——限流
    2:视业务场景而定判断是否可以拒绝部分多余流量
    3:使用工业级消息队列中间件
    4:加缓存
    5:加机器
    展开
    
    
  • 十大杰出青年
    2019-08-12
    老师,优化ReentrantLock那里是不是有问题呢,product的修改放在两个不同的锁下,就是说可能会同时有两个线程会修改product这个list,这样是否违反了有序性。
    而且我尝试无限循环运行生产者消费者线程,发现运行久了会出错的,希望老师讲解一下。
    
    
  • K
    2019-08-11
    老师好,我有个问题,就是实际的inventory会不会超过maxInventory啊?

    productLock.lock();    
    try {    
        while (inventory.get() == maxInventory){ //3
            notFullCondition.await();
        }
        product.add(e);    //1

        //producer被唤醒了以后,执行完1,还没执行2,这个时候时间片用完了,所以先停止了。
        //然后另外的线程被唤醒了,在3处的判断逻辑,(上一个线程并没有inventory.incr(),所以while条件不满足,不循环)
        //线程2号执行完代码1,2。
        //当之前一个线程1号醒过来,他也会继续执行代码2。这不是相当于,实际的inventory 肯定超过了maxInventory吗?

        System.out.println(" 放入一个商品库存,总库存为:" + inventory.incrementAndGet());    //2

        //后面的逻辑
        ...
    展开

    作者回复: 这有一个lock锁,不会同时进来两个线程。

    
    
  • 怎☞劰☜叻
    2019-08-09
    老师,我看到你上面说用协程来优化!我们这边有个服务属于业务网关,要聚合多个下有的数据,涉及大量的网络io,之前是使用多线程并行调用多个下有,现在发现线程越来越多,遇到了瓶颈!希望用协程来改进方案~但是我在网上找到的一些java协程开源组件,文档和生态都不是很健全,希望老师能给出一些建议~ 非常感谢

    作者回复: 建议再等等官方的协成组件,或改用go实现,目前Java的一些第三方开源组件的生产环境的实践以及性能验证有待考验,如果不介意当小白鼠,也可以试试这些第三方协成组件。

    
    
  • Aaron
    2019-08-03
    商品从数据库压入redis
    缓存。
    同时库存压入redis,用商品ID作为key,用list模拟队列【1001,1001,1001】用商品🆔做队列元素,100件库存,那就存100个🆔在队列中,扣库存的时候,判断队列大小,可以防止超卖。所有都是靠redis的单线程原子操作保证,可行不
     1
    
  • 晓杰
    2019-07-31
    请问老师在分布式架构中,使用lock和blockqueue实现生产者消费者是不是不适用了

    作者回复: 是的,可以基于消息队列或redis缓存来实现。

    
    
  • JasonK
    2019-07-31
    你好,刘老师,最近生产上一个服务,老是半夜cpu飙升,导致服务死掉,排查问题看了下,都是GC task thread#15 (ParallelGC) 线程占用CPU资源,这是为什么?而且同样的服务我布了两台机器,一台服务会死掉,一台不会。请老师解惑。

    作者回复: 导致CPU飙升只是一个性能的直接表现,是不是有对象一直在创建,所以导致一直在GC。建议打开dump日志查看具体的内存使用情况以及对象的创建分布情况。

     2
    
  • 我已经设置了昵称
    2019-07-31
    kafka也有事务消息

    作者回复: 是的

     1
    
  • nightmare
    2019-07-30
    可以在网关通过令牌桶算法限流,真正执行的生产者一方使用线程池来优化

    作者回复: 限流是一种方式,线程池其实也是一种限流手段。我们在之前协程这一讲中,其实也用协程代替线程实现了生产者消费者模式,这也不乏是一种优化方式。

    
    
  • 明翼
    2019-07-30
    老师,生产者和消费者的锁分开没问题吗?都是用的同一个队列?

    作者回复: 这里同步更新下,新增了以下代码作为实时库存:
    private AtomicInteger inventory = new AtomicInteger(0);

    我们这里是基于LinkedList来存取库存的,虽然LinkedList是非线程安全,但我们新增是操作头部,而消费则是操作队列的尾部,理论上来说没有线程安全问题。而库存的实际数量inventory是基于AtomicInteger(CAS锁)线程安全类实现,即可以保证原子性,也可以保证消费者和生产者之间是可见的。

    
    
我们在线,来聊聊吧