zoukankan      html  css  js  c++  java
  • 集成RabbitMQ做秒杀

    由于秒杀的并发量太大,所以仅仅使用缓存是不够的,还需要用到RabbitMQ。

    这里推荐一款用于分库分表的中间件:mycat

    解决超卖的问题(看第五章节):

    秒杀接口优化:

          

    实操:

    然后把下载好的文件上传到服务器上:

    验证一下:

    OK,到这一步,erlang安装好了。

    启动rabbitMQ:

    关闭:

    或者:

    配置环境变量:

    在末尾加上:

    使环境变量失效:

    SpringBoot集成RabbitMQ:
    添加依赖:

    application.properties中配置:

    #rabbitmq
    spring.rabbitmq.host=10.110.3.62
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=guest
    spring.rabbitmq.password=guest
    spring.rabbitmq.virtual-host=/
    #u6D88u8D39u8005u6570u91CF
    spring.rabbitmq.listener.simple.concurrency= 10
    spring.rabbitmq.listener.simple.max-concurrency= 10
    #u6D88u8D39u8005u6BCFu6B21u4ECEu961Fu5217u83B7u53D6u7684u6D88u606Fu6570u91CF
    spring.rabbitmq.listener.simple.prefetch= 1
    #u6D88u8D39u8005u81EAu52A8u542Fu52A8
    spring.rabbitmq.listener.simple.auto-startup=true
    #u6D88u8D39u5931u8D25uFF0Cu81EAu52A8u91CDu65B0u5165u961F
    spring.rabbitmq.listener.simple.default-requeue-rejected= true
    #u542Fu7528u53D1u9001u91CDu8BD5
    spring.rabbitmq.template.retry.enabled=true 
    spring.rabbitmq.template.retry.initial-interval=1000 
    spring.rabbitmq.template.retry.max-attempts=3
    spring.rabbitmq.template.retry.max-interval=10000
    spring.rabbitmq.template.retry.multiplier=1.0

    另外如果想用guest登录远程的rabbitMQ,必须设置如下:

    代码部分:

    MQConfig:

    package com.imooc.miaosha.rabbitmq;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.FanoutExchange;
    import org.springframework.amqp.core.HeadersExchange;
    import org.springframework.amqp.core.Queue;
    import org.springframework.amqp.core.TopicExchange;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MQConfig {
        
        public static final String MIAOSHA_QUEUE = "miaosha.queue";
        public static final String QUEUE = "queue";
        public static final String TOPIC_QUEUE1 = "topic.queue1";
        public static final String TOPIC_QUEUE2 = "topic.queue2";
        public static final String HEADER_QUEUE = "header.queue";
        public static final String TOPIC_EXCHANGE = "topicExchage";
        public static final String FANOUT_EXCHANGE = "fanoutxchage";
        public static final String HEADERS_EXCHANGE = "headersExchage";
        
        /**
         * Direct模式 交换机Exchange
         * */
        @Bean
        public Queue queue() {
            return new Queue(QUEUE, true);
        }
        
        /**
         * Topic模式 交换机Exchange
         * */
        @Bean
        public Queue topicQueue1() {
            return new Queue(TOPIC_QUEUE1, true);
        }
        @Bean
        public Queue topicQueue2() {
            return new Queue(TOPIC_QUEUE2, true);
        }
        @Bean
        public TopicExchange topicExchage(){
            return new TopicExchange(TOPIC_EXCHANGE);
        }
        @Bean
        public Binding topicBinding1() {
            return BindingBuilder.bind(topicQueue1()).to(topicExchage()).with("topic.key1");
        }
        @Bean
        public Binding topicBinding2() {
            return BindingBuilder.bind(topicQueue2()).to(topicExchage()).with("topic.#");
        }
        /**
         * Fanout模式 交换机Exchange
         * */
        @Bean
        public FanoutExchange fanoutExchage(){
            return new FanoutExchange(FANOUT_EXCHANGE);
        }
        @Bean
        public Binding FanoutBinding1() {
            return BindingBuilder.bind(topicQueue1()).to(fanoutExchage());
        }
        @Bean
        public Binding FanoutBinding2() {
            return BindingBuilder.bind(topicQueue2()).to(fanoutExchage());
        }
        /**
         * Header模式 交换机Exchange
         * */
        @Bean
        public HeadersExchange headersExchage(){
            return new HeadersExchange(HEADERS_EXCHANGE);
        }
        @Bean
        public Queue headerQueue1() {
            return new Queue(HEADER_QUEUE, true);
        }
        @Bean
        public Binding headerBinding() {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("header1", "value1");
            map.put("header2", "value2");
            return BindingBuilder.bind(headerQueue1()).to(headersExchage()).whereAll(map).match();
        }
        
        
    }

    MQSender:

    package com.imooc.miaosha.rabbitmq;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.amqp.core.AmqpTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.imooc.miaosha.redis.RedisService;
    
    @Service
    public class MQSender {
    
        private static Logger log = LoggerFactory.getLogger(MQSender.class);
        
        @Autowired
        AmqpTemplate amqpTemplate ;
        
        public void sendMiaoshaMessage(MiaoshaMessage mm) {
            String msg = RedisService.beanToString(mm);
            log.info("send message:"+msg);
            amqpTemplate.convertAndSend(MQConfig.MIAOSHA_QUEUE, msg);
        }
        
    //    public void send(Object message) {
    //        String msg = RedisService.beanToString(message);
    //        log.info("send message:"+msg);
    //        amqpTemplate.convertAndSend(MQConfig.QUEUE, msg);
    //    }
    //    
    //    public void sendTopic(Object message) {
    //        String msg = RedisService.beanToString(message);
    //        log.info("send topic message:"+msg);
    //        amqpTemplate.convertAndSend(MQConfig.TOPIC_EXCHANGE, "topic.key1", msg+"1");
    //        amqpTemplate.convertAndSend(MQConfig.TOPIC_EXCHANGE, "topic.key2", msg+"2");
    //    }
    //    
    //    public void sendFanout(Object message) {
    //        String msg = RedisService.beanToString(message);
    //        log.info("send fanout message:"+msg);
    //        amqpTemplate.convertAndSend(MQConfig.FANOUT_EXCHANGE, "", msg);
    //    }
    //    
    //    public void sendHeader(Object message) {
    //        String msg = RedisService.beanToString(message);
    //        log.info("send fanout message:"+msg);
    //        MessageProperties properties = new MessageProperties();
    //        properties.setHeader("header1", "value1");
    //        properties.setHeader("header2", "value2");
    //        Message obj = new Message(msg.getBytes(), properties);
    //        amqpTemplate.convertAndSend(MQConfig.HEADERS_EXCHANGE, "", obj);
    //    }
    
        
        
    }

    MQReceiver:

    package com.imooc.miaosha.rabbitmq;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.imooc.miaosha.domain.MiaoshaOrder;
    import com.imooc.miaosha.domain.MiaoshaUser;
    import com.imooc.miaosha.redis.RedisService;
    import com.imooc.miaosha.service.GoodsService;
    import com.imooc.miaosha.service.MiaoshaService;
    import com.imooc.miaosha.service.OrderService;
    import com.imooc.miaosha.vo.GoodsVo;
    
    @Service
    public class MQReceiver {
    
            private static Logger log = LoggerFactory.getLogger(MQReceiver.class);
            
            @Autowired
            RedisService redisService;
            
            @Autowired
            GoodsService goodsService;
            
            @Autowired
            OrderService orderService;
            
            @Autowired
            MiaoshaService miaoshaService;
            
            @RabbitListener(queues=MQConfig.MIAOSHA_QUEUE)
            public void receive(String message) {
                log.info("receive message:"+message);
                MiaoshaMessage mm  = RedisService.stringToBean(message, MiaoshaMessage.class);
                MiaoshaUser user = mm.getUser();
                long goodsId = mm.getGoodsId();
                
                GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
                int stock = goods.getStockCount();
                if(stock <= 0) {
                    return;
                }
                //判断是否已经秒杀到了
                MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
                if(order != null) {
                    return;
                }
                //减库存 下订单 写入秒杀订单
                miaoshaService.miaosha(user, goods);
            }
        
    //        @RabbitListener(queues=MQConfig.QUEUE)
    //        public void receive(String message) {
    //            log.info("receive message:"+message);
    //        }
    //        
    //        @RabbitListener(queues=MQConfig.TOPIC_QUEUE1)
    //        public void receiveTopic1(String message) {
    //            log.info(" topic  queue1 message:"+message);
    //        }
    //        
    //        @RabbitListener(queues=MQConfig.TOPIC_QUEUE2)
    //        public void receiveTopic2(String message) {
    //            log.info(" topic  queue2 message:"+message);
    //        }
    //        
    //        @RabbitListener(queues=MQConfig.HEADER_QUEUE)
    //        public void receiveHeaderQueue(byte[] message) {
    //            log.info(" header  queue message:"+new String(message));
    //        }
    //        
            
    }
  • 相关阅读:
    flowable的多人会签和一票否决
    排序
    Java数组的三种打印方式
    CF446B DZY Loves Modification(优先队列)
    2019CCPC哈尔滨 Interesting Permutation(思维)
    2019沈阳网络赛 Fish eating fruit (换根dp)
    AcWing287 积蓄程度(换根dp)
    CF1358E Are You Fired?(前缀和+贪心)
    android android studio error
    cocos2D-X 打包
  • 原文地址:https://www.cnblogs.com/XJJD/p/8557231.html
Copyright © 2011-2022 走看看