RabbitMQ初识

关于AMQP协议

AMQP(高级消息队列协议)是一个网络协议,它支持符合要求的客户端应用(application)和消息中间件代理(messaging middleware broker)之间进行通信

消息代理和他们所扮演的角色

消息代理(message brokers)从发布者(publishers)亦称生产者(producers)那儿接收消息,并根据既定的路由规则把接收到的消息发送给处理消息的消费者(consumers)。
由于AMQP是一个网络协议,所以这个过程中的发布者,消费者,消息代理 可以存在于不同的设备上。

RabbitMQ内部结构

在这里插入图片描述

重要概念

1.Broker:队列服务器实体。
2.Virtual host:虚拟主机,表示一批交换器,消息队列和相关对象
在这里插入图片描述
3.Connection:网络连接
4.Channel:信道,对于操作系统,建立销毁TCP都是很贵的开销,所以引入信道,AMQP都通过信道发出去(发消息、订阅队列、接消息等)
5.Exchange:交换机,接收消息,将消息发给队列
6.Queue:队列,消息容器
7.Binding:队列和交换机绑定
8.Message:消息
9.Publisher:消息生产者
10.Consumer:消费者,获取消息

在这里插入图片描述

1.简单队列

一个生产者对应一个消费者,不适用Exchange(在多消费者的时候不适用),消息message在通道Channel中进行传递
在这里插入图片描述
消息队列queue,图中红色部分,类似于邮箱,生产者向其中投递消息,消费者从中取出消息

//创建mq的连接工厂对象
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置连接rabbitmq主机
        connectionFactory.setHost("");
        //设置端口号
        connectionFactory.setPort(5672);
        //设置连接哪个虚拟主机
        connectionFactory.setVirtualHost("/");
        //设置访问虚拟主机的用户名密码
        connectionFactory.setUsername("");
        connectionFactory.setPassword("");
        //获取连接对象
        Connection connection = connectionFactory.newConnection();
        //获取连接中的通道
        Channel channel = connection.createChannel();
        //通道绑定对应的消息队列
        //参数1:队列名称,如果队列不存在自动创建
        //参数2: durable用来定义队列的特性是否要持久化 true:持久化队列    false:不持久化
        //参数3:exclusive 是否独占队列  true:独占队列  false:不独占
        //参数4:autodelete 是否在消费完成后删除队列  true:自动删除  false:不自动删除
        //参数5:额外参数
        channel.queueDeclare("hello",false,false,false,null);

        //发布消息
        //参数1:交换机名称
        //参数2:队列名称
        //参数3:传递消息的额外设置    可以设置队列中消息的持久化(MessageProperties.PERSISTENT_TEXT_PLAIN)
        //参数4:消息的具体内容
        channel.basicPublish("","hello", MessageProperties.PERSISTENT_TEXT_PLAIN,"hello_rabbitmq".getBytes());
        channel.close();
        connection.close();
ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("");
        connectionFactory.setPassword("");
        //创建连接对象
        Connection connection = connectionFactory.newConnection();
        //创建通道
        Channel channel = connection.createChannel();
        //通道绑定队列
        channel.queueDeclare("hello",false,false,false,null);
        //消费消息
        //参数1:消费哪个队列的消息 队列名称
        //参数2:开启消息的自动确认机制
        //参数3:消费时的回调接口
        channel.basicConsume("hello",true,new DefaultConsumer(channel){
            @Override//最后一个参数:消息队列中取出的消息
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消息1:"+new String(body));
            }
        });

2.work(Round-Robin轮询分发)

一个生产者对应多个消费者,但是只有一个生产者获得消息
在这里插入图片描述
这种模型消费者消费消息默认是均衡的,那么如何让消费快的多消费,实现能者多劳呢?
1.可以设置channel.basicQos(perfetch=1);同一时刻只发给消费者一条消息,直到它已经处理上一条消息并且做出响应,MQ才会把下一条消息分发消费者。
2.消息自动确认设置成false,改成手动确认

 channel.basicQos(1);//每一次消费一个消息
//参数2:消息自动确认:true代表消费者自动向rabbitMQ确认消息消费了  推荐使用false
//参数2:消息自动确认:true代表消费者自动向rabbitMQ确认消息消费了  推荐使用false
channel.basicConsume("work",false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者-1:"+new String(body));
                //手动确认: 参数1:手动确认消息标识
                // 参数2:是否开启多个消息同事确认   false 每次确认一个
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });

3.发布/订阅

1、1个生产者,多个消费者
2、每一个消费者都有自己的一个队列
3、生产者没有将消息直接发送到队列,而是发送到了交换机
4、每个队列都要绑定到交换机(这里的X交换机为fanout)
5、生产者发送的消息,经过交换机,到达队列,实现,一个消息被多个消费者获取的目的
在这里插入图片描述

4.路由direct

生产者发送消息到direct交换器,交换器和队列绑定时有路由key,生产者会指定路由key,消息只会发到对应的队列(routingkey完全相等)
在这里插入图片描述

topic(通配符)

*:匹配一个单词
#:匹配多个单词
routingkey:order.*匹配一个
order.#匹配多个(比如生产者发送的routingkey是order.add或者order.update,消费者设置order.#都可以接收到)
在这里插入图片描述
provider:

channel.exchangeDeclare("topics","topic");
String routeKey = "user.save.all";
channel.basicPublish("topics",routeKey,null,("这里是topic动态路由模型,routekey:["+routeKey+"]").getBytes());

consumer:

channel.exchangeDeclare("topics","topic");
//创建临时队列
String queue = channel.queueDeclare().getQueue();
//绑定交换机   routekey使用通配符表示
channel.queueBind(queue,"topics","user.*");
channel.basicConsume(queue,true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
            System.out.println("消费者1:"+new String(body));
        }
});

consumer2:

channel.exchangeDeclare("topics","topic");
//创建临时队列
String queue = channel.queueDeclare().getQueue();
//绑定交换机   routekey使用通配符表示
channel.queueBind(queue,"topics","user.#");
channel.basicConsume(queue,true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
            System.out.println("消费者2:"+new String(body));
      }
});

这里只有消费者2能收到消息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值