(1)RabbitMQ入门

rabbitMQ模型
在这里插入图片描述

初识RabbitMQ:

rabbitMQ是一个开源的消息代理和队列服务器,通过AMQP协议来完成不同应用之间的数据共享。
rabbitMQ是通过elang语言来开发。

什么是AMQP协议

(Advanced message queue protocol)高级消息队列
1)是一个二进制协议
2)AMQP是一个应用层协议的规范,可以有很多不同的消息中间件产品(中间件都需要遵循改规范)
server:是消息队列节点
virtual host:虚拟主机
exchange:交换机(消息投递到交换机上)
message queue:消息队列(被消费者监听消费)
交换机和消息队列有一个绑定关系

AMQP的核心概念

1.server:又称broker,接收客户端连接,实现AMQP实体服务
2.Connection:连接,应用程序与server/broker建立网络连接
3.channel:网络通道,几乎所有的操作都是在channel中进行的,是进行消息对象的通道,客户端可以建立多个channel,每一个channel表示一个会话任务
4.message:服务器与应用程序之间传递数据的载体,有properties(消息属性,用来修饰消息,比如消息的优先级,延时投递等)和Body(消息体)
5.virtual host:虚拟主机
6.exchange:交换机,消息直接投递到交换机上,然后交换机根据消息的路由key来路由到对应绑定的队列上
7.queue:队列,用来保存消息的载体,有消费者监听,然后消费消息
8.bingding:绑定exchange和queue的虚拟连接,bingding中可以包含route_key
9.route_key:路由key,他的作用是在交换机上通过route_key来把消息路由到哪个队列上

RabbitMQ安装教程
https://segmentfault.com/a/1190000018916099?utm_source=tag-newest

简单使用RabbitMQ

生产者:消息生产者

public class RabbitMQProducter {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        //2.设置连接工厂属性
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("test-virtual");
        connectionFactory.setUsername("yihao");
        connectionFactory.setPassword("yihao");

        //3.通过连接工厂创建连接对象
        Connection connection = connectionFactory.newConnection();

        //4.通过连接创建channel
        Channel channel = connection.createChannel();

        //通过channel发送消息
        for (int i=0;i<10;i++){
            String message = "hello yihao------"+i;
            //void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException;
            /**
             * exchange:交换机名称(这里我没有指定交换机,那我们的消息会发送到默认的交换机上)
             * routingKey:路由key
             * props:消息属性
             * body:消息体
             */
            channel.basicPublish("","yihao-queue",null,message.getBytes());
        }
        channel.close();
        connection.close();
    }
}

消费者
消息消费者

public class RabbitMQConsumer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        //2.设置连接工厂属性
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("test-virtual");
        connectionFactory.setUsername("yihao");
        connectionFactory.setPassword("yihao");

        //3.通过连接工厂创建连接对象
        Connection connection = connectionFactory.newConnection();

        //4.通过连接创建channel
        Channel channel = connection.createChannel();

        //声明队列
        String queueName ="yihao-queue";
        /**
         *queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
         *Map<String, Object> arguments) throws IOException;
         * queue:队列名称
         * durable:是否持久化,队列的声明默认是保存在内存中的,如果rabbitMQ重启会丢失,如果想重启之后还存在则开启持久化
         * exclusive:当连接关闭时,该队列是否会自动删除
         * autoDelete:是否自动删除,如最后一个消费者断开连接之后队列是否自动被删除
         * arguments:队列的其他属性,是map
         */
        channel.queueDeclare(queueName,true,false,true,null);

        //将消费者与channel绑定
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
		    StringBuilder sb = new StringBuilder();
                for (byte b : body) {
                    sb.append((char) b);
                }
                System.out.println(sb.toString());
                //channel.basicAck(envelope.getDeliveryTag(), false);//这个可以确认是否处理消息
            }
        }); 
    }
}

效果展示
在这里插入图片描述

交换机属性详解

1.作用:接受生产者的消息,然后根据路由键,把消息投递到跟交换机绑定的对应的队列上

2.交换机的属性:
name:交换机的名称
Type:交换机的类型(direct,topic,fanout,hreaders)
Durability:是否需要持久化
autoDelete:假如没有队列绑定到该交换机,那么该交换机是否自动删除
Internal:不常用,默认为false
argurements:扩展参数,用户扩展AMQP定制化协议

3.交换机的类型
3.1直接交换机
所有发送到direct exchange的消息都被被投递到与routekey名称相同的queue上。
在 direct模式下,可以使用自带的默认的exchange,即default exchange,所以不需要交换机和任何队列绑定,消息将会投递到route_key名称和队列相同的队列上。
在这里插入图片描述

**代码演示:
直连交换机生产者 DirectExchangeProducter**
public class DirectExchangeProducter {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接
        Connection connection = MyConnectionFactory.getConnection();

        //创建channel
        Channel channel = connection.createChannel();

        //定义交换机名称
        String exchangeName="yihao.directExchange";

        //定义路由key
        String routingKey="yihao.directExchange.key";

        //消息定义
        String messageBody="hello yihao";
        channel.basicPublish(exchangeName,routingKey,null,messageBody.getBytes());

        channel.close();
        connection.close();
    }
}

直连交换机消费者DirectExchangeConsumer

public class DirectExchangeConsumer {
    public static void main(String[] args) throws IOException {
        //创建连接
        Connection connection = MyConnectionFactory.getConnection();

        //创建通道
        Channel channel = connection.createChannel();

        //定义交换机名称
        String exchangeName="yihao.directExchange";

        //交换机类型
        String exchangeType="direct";

        //队列名称
        String queueName="yihao.directQueue";

        //定义路由key
        String routingKey="yihao.directExchange.key";

        //声明一个交换机
        channel.exchangeDeclare(exchangeName,exchangeType,true,false,null);

        //声明一个队列
        channel.queueDeclare(queueName,true,false,false,null);

        //交换机和队列绑定(根据队列名称和交换机名称,通过路由key绑定)
        channel.queueBind(queueName,exchangeName,routingKey);

        //将消费者与channel绑定
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                StringBuilder sb = new StringBuilder();
                for (byte b : body) {
                    sb.append((char) b);
                }
                System.out.println(sb.toString());
                //channel.basicAck(envelope.getDeliveryTag(), false);//这个可以确认是否处理消息
            }
        });
    }
}

3.2主题交换机topic exchange
就是在队列上设置绑定到topic交换机上的路由key,可以通过通配符来匹配。规则是:
比如:log.#:可以匹配一个单词,也可以匹配多个单词,比如可以匹配到log.a,log.b,log.a.b;
log.*:可以匹配一个单词,比如log.a,log.b,但是不能匹配log.a.b
在这里插入图片描述

代码示例:
主题交换机生产者TopicExchangeProducter:

public class TopicExchangeProducter {
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = MyConnectionFactory.getConnection();

        Channel channel = connection.createChannel();

        String topicExchangeName="topic.exchange";

        String routingKey1="topic.key.1";

        String routingKey2="topic.key.2";

        channel.basicPublish(topicExchangeName,routingKey1,null,"topic测试交换机1".getBytes());

        channel.basicPublish(topicExchangeName,routingKey2,null,"topic测试交换机2".getBytes());

        channel.close();
        connection.close();
    }
}

主题交换机消费者TopicExchangeConsumer

public class TopicExchangeConsumer {

    public static void main(String[] args) throws IOException {
        Connection connection = MyConnectionFactory.getConnection();
        Channel channel = connection.createChannel();
        String topicExchangeName="topic.exchange";
        String queueName="topic.queue";
        String exchangeType="topic";
        String routingKey="topic.#";
        //声明交换机
        channel.exchangeDeclare(topicExchangeName,exchangeType,true,true,false,null);
        //声明一个队列
        channel.queueDeclare(queueName,true,false,true,null);
        //队列绑定到交换机
        channel.queueBind(queueName,topicExchangeName,routingKey);

        //将消费者与channel绑定
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                StringBuilder sb = new StringBuilder();
                for (byte b : body) {
                    sb.append((char) b);
                }
                System.out.println(sb.toString());
                //channel.basicAck(envelope.getDeliveryTag(), false);//这个可以确认是否处理消息
            }
        });
    }
}

3.3扇形交换机 fanout exchange
就是消息通过从交换机到队列上不会通过路由key,所以该模式是最快的,只要和交换机绑定的,那么消息就会分发到与之绑定的队列上
在这里插入图片描述

代码演示
扇形交换机消息生产者FanoutExchangeProducter

public class FanoutExchangeProducter {
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = MyConnectionFactory.getConnection();
        Channel channel = connection.createChannel();

        String fanoutExchangeName="fanout.exchange";

        String routingKey="fanout.key";

        channel.basicPublish(fanoutExchangeName,routingKey,null,"fanout测试扇形交换机".getBytes());

        channel.close();

        connection.close();

    }
}

扇形交换机消息消费者FanoutExchangeConsumer

public class FanoutExchangeConsumer {
    public static void main(String[] args) throws IOException {
        Connection connection = MyConnectionFactory.getConnection();
        Channel channel = connection.createChannel();
        String fanoutExchangeName="fanout.exchange";
        String exchangeType="fanout";
        String queueName ="";
        //这里的routingKey是什么都无所谓,不会起作用到
        String routingKey="";
        channel.exchangeDeclare(fanoutExchangeName,exchangeType,true,true,false,null);
        channel.queueDeclare(queueName,true,false,true,null);
        channel.queueBind(queueName,fanoutExchangeName,routingKey);
        //将消费者与channel绑定
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                StringBuilder sb = new StringBuilder();
                for (byte b : body) {
                    sb.append((char) b);
                }
                System.out.println(sb.toString());
                //channel.basicAck(envelope.getDeliveryTag(), false);//这个可以确认是否处理消息
            }
        });
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值