mq使用总结

一、rabbitMq异步消息机制
1、exchange和queue进行绑定,一个exchange可以绑定多个queue。
2、消息生产者produce,将消息发送至exchange,exchange将消息路由至多个queue。
3、exchange路由分为fanout、direct、topic三种模式。
4、消费者customer监听相应的queue,接收消息,触发异步方法。
二、springboot中的使用
1、引入依赖


org.springframework.boot
spring-boot-starter-amqp
2.2.5.RELEASE

2、application.properties中增加相关配置

spring.rabbitmq.virtual-host=lwt
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
spring.rabbitmq.listener.simple.concurrency=10
spring.rabbitmq.listener.simple.max-concurrency=20
spring.rabbitmq.listener.simple.prefetch=50

3、配置rabbitMq

@Configuration
public class RabbitmqConfig {

    private final Logger log = LoggerFactory.getLogger(this.getClass().getName());
    @Autowired
    private CachingConnectionFactory connectionFactory;

    @Autowired
    private SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer;

    @Autowired
    private Environment env;

    /**
     * 单一消费者
     * @return
     */
    @Bean(name = "singleListenerContainer")
    public SimpleRabbitListenerContainerFactory listenerContainer(){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setConcurrentConsumers(1);
        factory.setMaxConcurrentConsumers(1);
        factory.setPrefetchCount(1);
        factory.setTxSize(1);
        return factory;
    }

    /**
     * 多个消费者
     * @return
     */
    @Bean(name = "multiListenerContainer")
    public SimpleRabbitListenerContainerFactory multiListenerContainer(){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factoryConfigurer.configure(factory,connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setAcknowledgeMode(AcknowledgeMode.NONE);
        factory.setConcurrentConsumers(env.getProperty("spring.rabbitmq.listener.simple.concurrency",int.class));
        factory.setMaxConcurrentConsumers(env.getProperty("spring.rabbitmq.listener.simple.max-concurrency",int.class));
        factory.setPrefetchCount(env.getProperty("spring.rabbitmq.listener.simple.prefetch",int.class));
        return factory;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(){
        connectionFactory.setPublisherConfirms(true);
        connectionFactory.setPublisherReturns(true);
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMandatory(true);

        //TODO:面向生产端
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                log.info("消息发送成功:correlationData({}),ack({}),cause({})",correlationData,ack,cause);
            }
        });

        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                log.info("消息丢失:exchange({}),route({}),replyCode({}),replyText({}),message:{}",exchange,routingKey,replyCode,replyText,message);
            }
        });
        return rabbitTemplate;
    }

    //TODO:用户注册消息模型

    @Bean
    public Queue userRegisterQueue(){
        return new Queue("rabbitmq.user.register.queue.name",true);
    }

    @Bean
    public Exchange userRegisterExchange(){
        return new DirectExchange("rabbitmq.user.register.exchange.name",true,false);
    }

    @Bean
    public Binding subContractInvalidBinding(){
        return BindingBuilder.bind(userRegisterQueue()).to(userRegisterExchange()).with("rabbitmq.user.register.routing.key.name").and(null);
    }

3、消息发送

@Autowired
private AmqpTemplate amqpTemplate;
@Autowired
private ObjectMapper objectMapper;
@RequestMapping(value = "/helloSender",method = RequestMethod.POST)
public String HelloSender(@RequestBody String message) throws JsonProcessingException {
    System.out.println(message);
    byte[] byts = objectMapper.writeValueAsBytes(message);
    Message msg= MessageBuilder.withBody(byts).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build();
    amqpTemplate.send("rabbitmq.user.register.exchange.name","rabbitmq.user.register.routing.key.name",msg);
    return "succ";
}

4、消息接收

@Component
public class RabbitmqListener {
    private final Logger log = LoggerFactory.getLogger(this.getClass().getName());

	//监听某一个队列
    @RabbitListener(queues = "rabbitmq.user.register.queue.name",containerFactory = "singleListenerContainer")
    public void consume(Message msg){
        try {
            System.out.println("----------接收成功!!!-------");
            String message = msg.toString();

            log.info("监听到的消息: {} ",message);

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

三、问题与注意事项
1、发送字符串类型的数据信息时,反序列化报错。

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `[B` out of START_OBJECT token
 at [Source: (String)"{"id":1,"userName":"jack","name":"lili"}"; line: 1, column: 1]

解决方案:使用ObjectMapper进行数据格式转换:byte[] byts = objectMapper.writeValueAsBytes(message);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值