mq小记

异步调用对比与同步调用的优势:吞吐量提升,故障隔离,调用没有阻碍,耦合度很低,流量削锋,

springAMQP基于RabbitMQ封装的模板,并且springboot对其实现了自动装配,使用非常方便:SrpingAMQP提供了三个功能:自动声明队列、交换机及其绑定关系、基于注解的监听器模式,异步接收消息、封装了RabbitTemplate工具,用于发送消息

BasicQueue(简单队列模型) 在父工程mq-demo中引入依赖

     <!--AMQP依赖,包含RabbitMQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

修改yml配置文件

spring:
  rabbitmq:
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    host: 192.168.81.100

consumer,publisher都要有以上操作

编写consumer,

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author d2
 * @version 1.0
 * @date 2021/11/6 19:27
 */
@Component
public class SpringRabbitListener {

    /**
     * Basic Queue 1简单队列模型
     * @param mess
     */
    @RabbitListener(queues = "yes.queue")
    public void listenSimpleQueueMessage(String mess){
        System.out.println("test1简单队列模型接收到消息"+mess);

    }

编写publisher

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @author d2
 * @version 1.0
 * @date 2021/11/6 19:28
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitPublisherTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void test1(){
        //设置队列名称
        String queueName = "yes.queue";
        //设置消息内容
        String mess = "简单队列测试";
        rabbitTemplate.convertAndSend(queueName,mess);
    }

使用@RabbitListener如果队列中没有当前的queueName会报错

Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'yes.queu1' in vhost '/', class-id=50, method-id=10)
    at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:517) ~[amqp-client-5.9.0.jar:5.9.0]
    at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:341) ~[amqp-client-5.9.0.jar:5.9.0]
    at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:182) ~[amqp-client-5.9.0.jar:5.9.0]
    at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:114) ~[amqp-client-5.9.0.jar:5.9.0]
    at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:739) ~[amqp-client-5.9.0.jar:5.9.0]
    at com.rabbitmq.client.impl.AMQConnection.access$300(AMQConnection.java:47) ~[amqp-client-5.9.0.jar:5.9.0]
    at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:666) ~[amqp-client-5.9.0.jar:5.9.0]
    ... 1 common frames omitted

 

 首先启动publisher

 

 然后到MQ管理平台看发送的消息

 

 

 

 这里可以看到刚刚往消息队列发送的消息,处于发送未读状态(此时我想到了一款撩骚软件soul)

 

 

consumer端一启动就将此消息输出了

 

 此时回到mq管理端看刚刚发送的消息看不到了

这可以证明消息在mq管理台的消息是已读及焚的

WorkQueue(工作队列):任务模型,简单说就是让多个消费者绑定到一个队列上,共同消费队列中的资源(轮询)

Fanout(广播):1,可以有多个队列,2每个队列都要绑定到交换机,3生产者发送消息只能发送到交换机,4交换机把消息发送到绑定到的所有队列,5订阅的消费者都可以拿到消息

Direct(路由):1队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key,2消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey,3Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息

Topic(订阅):Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符,支持:#.abc、abc.#通配符的的模式给队列发送消息

 

简单总结

simple.queue
work.queue
默认:轮询机制、可以优化:预取量=1(能者多劳)


fanout.queue
发送消息:rabbitTemplate.convertAndSend(exchangeName, "", message);


direct.queue
发送消息:rabbitTemplate.convertAndSend(exchangeName, "log.movement", message);

 

topic.queue
发送消息:rabbitTemplate.convertAndSend(exchangeName, "log.movement", message);

 

以上就是对mq的五种工作模式总结.

posted @ 2021-11-06 20:12  Iamd2  阅读(53)  评论(0)    收藏  举报