springboot和rabbitmq整合

參考: https://blog.csdn.net/u013871100/article/details/82982235

1 起步依賴
pom.xml中 引入rabbitmq依賴

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

2 配置文件
application.properties中添加下面配置

# rabbitmq配置
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port= 5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.listener.concurrency=1
spring.rabbitmq.listener.max-concurrency=2
spring.rabbitmq.listener.prefetch=5

#rabbitmq隊列、交換器、routingkey配置 (下面是其中一個queue的配置)
rabbitmq.mq.person.handler.exchange=whir.test.boot.event.person.exchange
rabbitmq.mq.person.handler.queue=whir.test.boot.event.person.queue
rabbitmq.mq.person.handler.routingkey=whir.test.boot.event.person.routingkey

說明:
其中concurrency爲併發消費者初始值,max-concurrency爲併發消費者最大值,prefetch爲每個消費者每次監聽時可以拉取處理的消息數量。

3 消息發送組件、監聽器容器實現

@Configuration
public class RabbitmqConfig {
    /**
     * 併發消費者初始值
     */
    @Value("${spring.rabbitmq.listener.concurrency}")
    private Integer rabbitMqConcurrency;

    /**
     * 併發消費者最大值
     */
    @Value("${spring.rabbitmq.listener.max-concurrency}")
    private Integer maxMqConcurrency;

    /**
     * 每個消費者每次監聽時可拉取處理的消息數量
     */
    @Value("${spring.rabbitmq.listener.prefetch}")
    private Integer prefetch;

    @Autowired
    private CachingConnectionFactory connectionFactory;

    @Autowired
    private SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer;

    @Autowired
    private RabbitConfirmCallback rabbitConfirmCallback;

    /**
    * RabbitTemplate是消息發送組件
    */
    @Bean
    public RabbitTemplate rabbitTemplate(){
        //消息發佈成功後是否有回調
        connectionFactory.setPublisherConfirms(Boolean.TRUE);
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //mandatory參數爲true時,如果消息無法匹配到queue,消息會返回給消息發送者
        rabbitTemplate.setMandatory(Boolean.TRUE);

        //消息發送成功後的回調
        rabbitTemplate.setConfirmCallback(rabbitConfirmCallback);
        return rabbitTemplate;
    }

    /**
    * SimpleRabbitListenerContainerFactory是監聽器容器
    */
    @Bean("multiListenerContainer")
    public SimpleRabbitListenerContainerFactory multiListenerContainer(){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factoryConfigurer.configure(factory,connectionFactory);
        //消息轉換器
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setAcknowledgeMode(AcknowledgeMode.NONE);
        factory.setConcurrentConsumers(rabbitMqConcurrency);
        factory.setMaxConcurrentConsumers(maxMqConcurrency);
        factory.setPrefetchCount(prefetch);
        return factory;

    }
}
/**
* 消息發送成功後callback實現類
*
**/
@Component
public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback {
    private static final Logger log = LoggerFactory.getLogger(RabbitConfirmCallback.class);

    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        log.info("消息發送成功:correlationData={},ack={},cause={}",correlationData,b,s);

    }
}

說明: RabbitTemplate是消息發送組件,SimpleRabbitListenerContainerFactory是監聽器容器,用來存放實例化的監聽器。

4 聲明隊列並綁定交換器

/**
 * @description: Person處理隊列聲明配置類
 * @create: 2019-12-03 11:50
 **/
@Configuration
public class PersonHandlerQueueDeclare {

    @Value("${rabbitmq.mq.person.handler.queue}")
    private String personQueueName;

    @Value("${rabbitmq.mq.person.handler.exchange}")
    private String personExchangeName;

    @Value("${rabbitmq.mq.person.handler.routingkey}")
    private String personRoutingKey;

    @Bean("personHandlerQueue")
    public Queue personHandlerQueue(){
        return new Queue(personQueueName);
    }

    @Bean("personHandlerExchange")
    public DirectExchange personHandlerExchange(){
       return new DirectExchange(personExchangeName);
    }

    @Bean("personHandlerBinding")
    public Binding personHandlerBinding(){
        return BindingBuilder.bind(personHandlerQueue()).to(personHandlerExchange()).with(personRoutingKey);
    }
}

說明: PersonHandlerQueueDeclare聲明queue、exchange,並把queue綁定到exchange上, 綁定之後隊列和交換器就可以在rabbitmq管理後臺查看到。

5 消費者監聽消息

/**
 * @description: Person處理消費者
 * @create: 2019-12-03 12:18
 **/
@Component
public class PersonHandlerConsume {
    private Logger log = LoggerFactory.getLogger(PersonHandlerConsume.class);

    @Autowired
    private ObjectMapper objectMapper;

    @RabbitListener(queues = "${rabbitmq.mq.person.handler.queue}",containerFactory = "multiListenerContainer")
    public void handler(@Payload byte[] message){
        Person person = null;
        try {
            person = objectMapper.readValue(message, Person.class);
            log.info("監聽到消息,age={},name={},id={}", person.getAge(),person.getName(),person.getId());
        } catch (IOException e) {
            log.warn("監聽消息異常",e);
        }


    }
}

6 生產者消息發送

@RestController
@RequestMapping("/mq")
public class QueueController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private Environment env;

    @Autowired
    private ObjectMapper objectMapper;

    @RequestMapping("/test")
    public String mqSend(){
        //初始化數據
        Person person = new Person();
        person.setName("zhangsan");
        person.setAge(123);
        person.setId(2);


        Message message= null;
        try {
            //發送消息
            rabbitTemplate.setExchange(env.getProperty("rabbitmq.mq.person.handler.exchange"));
            rabbitTemplate.setRoutingKey(env.getProperty("rabbitmq.mq.person.handler.routingkey"));
            rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
            CorrelationData correlationData = new CorrelationData();
            correlationData.setId(String.valueOf(person.getId()));

            message = MessageBuilder.withBody(objectMapper.writeValueAsBytes(person)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build();
            message.getMessageProperties().setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME, MessageProperties.CONTENT_TYPE_JSON);
            rabbitTemplate.convertAndSend(env.getProperty("rabbitmq.mq.person.handler.routingkey"),message,correlationData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "123";
    }
}

7 演示
請求地址:http://localhost:8080/mq/test

控制檯打印日誌如下:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章