Rabbitmq 消息中间件 秒杀问题思考

本文探讨了在处理秒杀等高并发场景时,如何利用消息中间件RabbitMQ进行流量控制。提出了通过限制队列长度来防止超负荷,但测试发现RabbitMQ的overflow参数并未按预期工作,始终丢弃最新消息。同时,尝试通过Redis自增操作控制队列消息数,以降低消费端压力,该方法在实践中表现良好。文章强调了源头控制队列的重要性,并指出Redis原子性操作在此类问题中的优势。
摘要由CSDN通过智能技术生成

对于秒杀类似的高并发大流量处理问题,采用消息中间件处理比较合适。网上大部分解决方式似乎都在消费者端,采用basicQos限制消息取出个数,basicAck手动处理执行结果。其实很大部分不需要到消费者来处理,直接限制死队列的消息数,拒绝超过指定消息数的请求。可以考虑使用控制队列长度来完成。rabbitmq默认是超过数量的先废弃或进入死信,文档有个overflow的参数可以指定废弃的顺序,默认dropHead,改为reject-publish后会废弃最新的消息。

    public Queue queue() {
        return QueueBuilder
                .nonDurable("mk")  
                .maxLength(3)
                .overflow(QueueBuilder.Overflow.rejectPublish)
                .build();
    }

 然而,通过测试发现,不管设置reject-publish或drop-head均没效果,都是采用废弃最新的消息,这样就无法满足我们秒杀的排队规则。也试过使用每次获取队列数量来控制队列消息数,但测试发现耗时太高。

    public void getMessageCount() {
        long a = ToolKang.getUnixTimeDateMillisecond();
        String queue = "mk";
        AMQP.Queue.DeclareOk declareOk = template.execute(new ChannelCallback<AMQP.Queue.DeclareOk>() {
            public AMQP.Queue.DeclareOk doInRabbit(Channel channel) throws Exception {
                return channel.queueDeclarePassive(queue);
            }
        });
        long b = ToolKang.getUnixTimeDateMillisecond();
    }

Redis自增key 的好处

原子性(atomicity):一个事务是一个不可分割的最小工作单位,事务中包括的诸操作要么都做,要么都不做。
Redis所有单个命令的执行都是原子性的,这与它的单线程机制有关;
Redis命令的原子性使得我们不用考虑并发问题,可以方便的利用原子性自增操作
简单解释就是你的服务即使是多机器多进程的,incr也能保证每次返回的结果不会出现相同的值。

通过自增来实现队列数量的控制,效果比较好,同时也减轻消费端的压力,在源头就限制了队列消息数量。(虽然消费端也控制了读取数量)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值