• SpringBoot 搭建 Rabbitmq


    本文的Spring boot版本是2.1.7.RELEASE。

    pom.xml

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-amqp</artifactId>
            </dependency>

    application.yml

    
    spring:
      rabbitmq:
        virtual-host: / 
        host: localhost 
        port: 5672
        username: guest
        password: 123456    
        listener:
          simple:
            concurrency: 10
            max-concurrency: 20
            prefetch: 5
    
    mq:
      env: test
    
    cart:
      place:
        order:
          queue: ${mq.env}.cart.place.order.queue
          exchange: ${mq.env}.cart.place.order.exchange
          routing:
            key: ${mq.env}.cart.place.order.routing.key

    Queue.config

    @Configuration
    public class QueueConfig {
    
        @Autowired
        private Environment environment;
    
        /**
         * cart place order apply
         */
    
        /**
         * durable = "true" persistent Rabbitmq does not need to create a new queue when restarting
         */
        @Bean
        public Queue placeOrderQueue() {
            return new Queue(environment.getProperty("cart.place.order.queue"), true);
        }
    
        /**
         *  durable = "true" Rabbitmq does not need to create a new exchange when restarting
         *
         *  1.Direct exchange: relatively simple, the matching rule is: if the routing keys match, the message is delivered to the relevant queue
         *  2.Fanout exchange: There is no concept of routing keys. He sends messages to all queues bound to this exchange.。
         *  3.Topic exchange: uses the principle of fuzzy matching routing keys to forward messages to the queue
         *
         *  Key: The key value of the queue in the direct-exchange. When the message is sent to the specified key in the direct-exchange, the
         *  message will be forwarded to the message queue specified by the queue parameter.
         */
        @Bean
        public DirectExchange placeOrderExchange() {
            return new DirectExchange(environment.getProperty("cart.place.order.exchange"), true, false);
        }
    
        @Bean
        public Binding placeOrderBinding() {
            return BindingBuilder.bind(placeOrderQueue()).to(placeOrderExchange()).with(environment.getProperty("cart.place.order.routing.key"));
        }
    
    }

    Rabbitmq.config

    @Configuration
    public class RabbitmqConfig {
        private static final Logger logger = LogManager.getLogger(RabbitmqConfig.class);
    
        @Autowired
        private Environment environment;
    
        @Autowired
        private CachingConnectionFactory cachingConnectionFactory;
    
        @Autowired
        private SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer;
    
        @Autowired
        private ObjectMapper objectMapper;
    
        /**
         * singleton can't set multi times callback
         * @return
         */
        @Bean
        @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
        public RabbitTemplate rabbitTemplate() {
           cachingConnectionFactory.setPublisherConfirms(true);
           cachingConnectionFactory.setPublisherReturns(true);
    
           RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
           rabbitTemplate.setMandatory(true);
           rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
    
           rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
               if (ack) {
                   logger.info("message send succeed:correlationData({}),ack({}),cause({})",correlationData, ack, cause);
               } else {
                   logger.info("message send failed:correlationData({}),ack({}),cause({})",correlationData, ack, cause);
               }
           });
    
    
           rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
               logger.info("message lose:exchange({}),route({}),replyCode({}),replyText({}),message:{}", exchange, routingKey, replyCode, replyText, message);
           });
    
           return rabbitTemplate;
    
        }
    
        @Bean(name = "singleListenerContainer")
        public SimpleRabbitListenerContainerFactory singleListenerContainer() {
            SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
            factory.setConnectionFactory(cachingConnectionFactory);
            factory.setMessageConverter(new Jackson2JsonMessageConverter());
            factory.setConcurrentConsumers(1);
            factory.setMaxConcurrentConsumers(1);
            factory.setPrefetchCount(1);
            factory.setTxSize(1);
            factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
    
            return factory;
        }
    
        @Bean(name = "multiListenerContainer")
        public SimpleRabbitListenerContainerFactory multiListenerContainer() {
            SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
            factoryConfigurer.configure(factory, cachingConnectionFactory);
            factory.setMessageConverter(new Jackson2JsonMessageConverter());
            factory.setConcurrentConsumers(environment.getProperty("spring.rabbitmq.listener.simple.concurrency", int.class));
            factory.setMaxConcurrentConsumers(environment.getProperty("spring.rabbitmq.listener.simple.max-concurrency", int.class));
            factory.setPrefetchCount(environment.getProperty("spring.rabbitmq.listener.simple.prefetch", int.class));
    
            factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
    
            return factory;
        }
    
        /**
         * Message persistent: Set the deliveryMode of the message to 2 and the consumer can continue to consume
         * the messages after persistence after restarting;
         * Use convertAndSend to send a message. The message is persistent by default. The following is the source code:
         * new MessageProperties() --> DEFAULT_DELIVERY_MODE = MessageDeliveryMode.PERSISTENT --> deliveryMode = 2;
         *
         * @param exchangeName
         * @param routingKeyName
         * @param content
         * @param flag
         * @param messageId
         * @param <T>
         */
        public <T> void sendMessage(String exchangeName, String routingKeyName, T content, boolean flag, String messageId) {
            logger.info("message send :messageId({}), exchangeName({}), routingKeyName({}), content({}), flag({})",
                    messageId, exchangeName, routingKeyName, content);
    
            CorrelationData correlationData = new CorrelationData();
    
            try {
                if (flag) {
                    MessageProperties properties = new MessageProperties();
                    properties.setCorrelationId(messageId);
    
                    correlationData.setId(messageId);
    
                    this.rabbitTemplate().convertAndSend(exchangeName, routingKeyName,
                            MessageBuilder.withBody(objectMapper.writeValueAsBytes(content)).andProperties(properties).build(), correlationData);
                } else {
                    this.rabbitTemplate().convertAndSend(exchangeName, routingKeyName, content, correlationData);
                }
            } catch (Exception e) {
                logger.error("error message :e.getMessage({})", e.getMessage());
            }
    
        }
    
    
    }

    生产者只需要你调取RabbitmqConfig中的sendMessage()方法,其中如果你的消费者需要correlationDataId这个参数,那么就将flag设置成true,messageId设置成correlationDataId,就可以在消费端获取了。

    String messageId = UUID.randomUUID().toString();
    rabbitmqConfig.sendMessage(environment.getProperty("cart.create.order.result.exchange"), environment.getProperty("cart.create.order.result.routing.key"), response, flag, messageId);

    消费者

        @Autowired
        private RabbitmqConfig rabbitmqConfig;
    
        @Autowired
        private ObjectMapper objectMapper;
    
        @RabbitListener(queues = "${cart.place.order.queue}", containerFactory = "multiListenerContainer")
        public void placeOrder(Message message, Channel channel) {
    
            try {
                logger.info("place order : message ({})" + objectMapper.readValue(message.getBody(), RequestInventoryItems.class));
                logger.info("place order : message ({})" + message.getMessageProperties().getCorrelationId());
    //            logger.info("place order : message ({})" + );
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            } catch (Exception es) {
                logger.error("error message :es.getMessage({})", es.getMessage());
                try {
                    //The third parameter is whether to return to the queue.Pay attention to the endless loop.
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
                } catch (Exception e) {
                    logger.error("error message :e.getMessage({})", e.getMessage());
                }
    
            }
    
        }

    以上就是集成Rabbitmq的全部步骤了。

  • 相关阅读:
    递归的一些应用(一)遍历文件夹
    获取指定路径下文件夹所有文件的大小
    JavaScript Color Picker
    在ASP.NET中,用javascript给CuteEditor控件赋值
    通过URL判断文件是否有存在
    语音验证码
    [链接].net 学习网站
    [音乐]梦中的婚礼
    [转载]天堂猎人影院的爱情狩猎
    为应用程序添加消息过滤器
  • 原文地址:https://www.cnblogs.com/daishoucheng/p/11990421.html
Copyright © 2020-2023  润新知