Maven写rabbitMQ教程01

Maven写rabbitMQ教程

提示:如果有不知道rabbitMQ的朋友建议先去看看相关教程
先上一个RabbitMQ的工作原理图
在这里插入图片描述
组成部分说明如下:
Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue。
Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑
Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。
Producer:消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。
Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。
消息发布接收流程:
-----发送消息-----
1、生产者和Broker建立TCP连接。
2、生产者和Broker建立通道。
3、生产者通过通道消息发送给Broker,由Exchange将消息进行转发。
4、Exchange将消息转发到指定的Queue(队列)

----接收消息-----
1、消费者和Broker建立TCP连接
2、消费者和Broker建立通道
3、消费者监听指定的Queue(队列)
4、当有消息到达Queue时Broker默认将消息推送给消费者。
5、消费者接收到消息。

用maven项目书写rabbitMQ的思路:


一丶简单模式Hello World
功能:一个生产者P发送消息到队列Q,一个消费者C接收
功能:一个生产者P发送消息到队列Q,一个消费者C接收

1.先引入jar包导入相关的依赖;

		<dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
        </dependency>

2.创建两个项目,一个提供者和一个消费者
在这里插入图片描述

3.在测试类里面写代码
先上producer的代码

public class providucer01 {
    private static final String QUEUE= "helloworld";
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建connectionfactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");//设置
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务
        //因为最后需要关闭连接所以定义到外面
        Connection connection = null;
        Channel channel = null;
        try {
            //通过connectionfactory获取connection
           connection = connectionFactory.newConnection();
           //获取Exchange通道
           channel = connection.createChannel();
            /**
             *声明队列,如果Rabbit中没有此队列将自动创建
             *param1:队列名称
             *param2:是否持久化
             *param3:队列是否独占此连接
             *param4:队列不再使用时是否自动删除此队列
             *param5:队列参数
             */
            channel.queueDeclare(QUEUE,true,false,false,null);
            //自定义消息
            String massage = "helloMQ"+System.currentTimeMillis();
            /**
             *消息发布方法
             *param1:Exchange的名称,如果没有指定,则使用Default Exchange
             *param2:routingKey,消息的路由Key,是用于Exchange(交换机)将消息转发到指定的消息队列
             *param3:消息包含的属性
             *param4:消息体
             *这里没有指定交换机,消息将发送给默认交换机,每个队列也会绑定那个默认的交换机,但是不能显  示绑定或解除绑定
             *默认的交换机,routingKey等于队列名称
             */
            channel.basicPublish("",QUEUE,null,massage.getBytes("utf-8"));
            System.out.println("send massage: ----"+massage);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }finally {

                if(channel != null)
                {
                    channel.close();
                }
                if(connection != null)
                {
                    connection.close();
                }
        }
    }
}

再上customer的代码

public class customer01 {
    private static final String QUEUE = "helloworld";

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建connectionfactory
        ConnectionFactory factory = new ConnectionFactory();
        //设置MabbitMQ所在服务器的ip和端口
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        //获取connection
        Connection connection = factory.newConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUE, true, false, false, null);
        //定义消费方法
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            /**
             *消费者接收消息调用此方法
             *@param consumerTag 消费者的标签,在channel.basicConsume()去指定
             *@param  envelope  消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)
             *@param properties
             *@param body
             *@throws IOException
             **/
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)throws IOException {
                //交换机
                String exchange = envelope.getExchange();
                //路由key
                String routingKey = envelope.getRoutingKey();
                //消息id
                long deliveryTag = envelope.getDeliveryTag();
                //消息内容
                String msg = new String(body, "utf-8");
                System.out.println("receive message:" + msg);
            }


        };
        /**
         *监听队列String queue, boolean autoAck,Consumer callback
         *参数明细
         *1、队列名称
         *2、是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置  为false则需要手动回复
         *3、消费消息的方法,消费者接收到消息后调用此方法
         */
        channel.basicConsume(QUEUE, false, consumer);
    }}

总结:
1、发送端操作流程
1)创建连接
2)创建通道
3)声明队列
4)发送消息
2、接收端
1)创建连接
2)创建通道
3)声明队列
4)监听队列
5)接收消息
6)ack回复


二丶工作队列模式Work Queue
在这里插入图片描述
功能:一个生产者,多个消费者,每个消费者获取到的消息唯一,多个消费者只有一个队列

任务队列:避免立即做一个资源密集型任务,必须等待它完成,而是把这个任务安排到稍后再做。我们将任务封装为消息并将其发送给队列。后台运行的工作进程将弹出任务并最终执行作业。当有多个worker同时运行时,任务将在它们之间共享。应用场景:对于 任务过重或任务较多情况使用工作队列可以提高任务处理的速度。
思路:
work queues与入门程序相比,多了一个消费端,两个消费端共同消费同一个队列中的消息。
测试:
1、使用入门程序,把customer01copy一下启动多个消费者。
2、生产者发送多个消息。结果:
1、一条消息只会被一个消费者接收;
2、rabbit采用轮询的方式将消息是平均发送给消费者的;
3、消费者在处理完某条消息后,才会收到下一条消息。


三丶发布/订阅模式Publish/Subscribe
在这里插入图片描述
功能:一个生产者发送的消息会被多个消费者获取。一个生产者、一个交换机、多个队列、多个消费者

生产者:可以将消息发送到队列或者是交换机。

消费者:只能从队列中获取消息。

如果消息发送到没有队列绑定的交换机上,那么消息将丢失。

交换机不能存储消息,消息存储在队列中

代码可以想象成银行业务用户通知,当用户充值成功或转账完成系统通知用户,通知方式有短信、邮件多种方法 。

生产者:
声明Exchange_fanout_inform交换机。
声明两个队列并且绑定到此交换机,绑定时不需要指定routingkey 发送消息时不需要指定routingkey
代码如下:

public class providucer01 {
    //    private static final String QUEUE = "helloworld";
    private static final String QUEUE_EMAIL = "queue_email";
    private static final String QUEUE_SMS = "queue_sms";
    private static final String EXCHANGEE_INFORM = "exchange_inform";

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建connectionfactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");//设置
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务
        //因为最后需要关闭连接所以定义到外面
        Connection connection = null;
        Channel channel = null;
        try {
            //通过connectionfactory获取connection
            connection = connectionFactory.newConnection();
            //获取Exchange通道
            channel = connection.createChannel();
            //声明交换机 String exchange, BuiltinExchangeType type
            /**
             *参数明细
             *1、交换机名称
             *2、交换机类型,fanout、topic、direct、headers
             */
            channel.exchangeDeclare(EXCHANGEE_INFORM, BuiltinExchangeType.FANOUT);

            /**
             *声明队列,如果Rabbit中没有此队列将自动创建
             *param1:队列名称
             *param2:是否持久化
             *param3:队列是否独占此连接
             *param4:队列不再使用时是否自动删除此队列
             *param5:队列参数
             */
            channel.queueDeclare(QUEUE_EMAIL, true, false, false, null);
            channel.queueDeclare(QUEUE_SMS, true, false, false, null);
            //交换机和队列绑定String queue, String exchange, String routingKey
            /**
             *参数明细
             *1、队列名称
             *2、交换机名称
             *3、路由key
             */
            channel.queueBind(QUEUE_EMAIL,EXCHANGEE_INFORM,"");
            channel.queueBind(QUEUE_SMS,EXCHANGEE_INFORM,"");
            //自定义消息

            /**
             *消息发布方法
             *param1:Exchange的名称,如果没有指定,则使用Default Exchange
             *param2:routingKey,消息的路由Key,是用于Exchange(交换机)将消息转发到指定的消息队列
             *param3:消息包含的属性
             *param4:消息体
             */
            for (int i = 0; i < 5; i++) {
                String massage = "helloMQ!第"+i+"次";
                channel.basicPublish(EXCHANGEE_INFORM, "", null, massage.getBytes("utf-8"));
                System.out.println("send massage: ----" + massage);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        } finally {

            if (channel != null) {
                channel.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
}

customer代码:

public class customer01 {
    private static final String QUEUE_EMAIL = "queue_email";
    private static final String EXCHANGEE_INFORM = "exchange_inform";


    public static void main(String[] args) throws IOException, TimeoutException {
        //创建connectionfactory
        ConnectionFactory factory = new ConnectionFactory();
        //设置MabbitMQ所在服务器的ip和端口
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        //获取connection
        Connection connection = factory.newConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //声明交换机 String exchange, BuiltinExchangeType type
        /**
         *参数明细
         *1、交换机名称
         *2、交换机类型,fanout、topic、direct、headers
         */
        channel.exchangeDeclare(EXCHANGEE_INFORM,BuiltinExchangeType.FANOUT);
        //声明队列
        channel.queueDeclare(QUEUE_EMAIL, true, false, false, null);
        //定义消费方法
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            /**
             *消费者接收消息调用此方法
             *@param consumerTag 消费者的标签,在channel.basicConsume()去指定
             *@param  envelope  消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)
             *@param properties
             *@param body
             *@throws IOException
             **/
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)throws IOException {
                //交换机
                String exchange = envelope.getExchange();
                //路由key
                String routingKey = envelope.getRoutingKey();
                //消息id
                long deliveryTag = envelope.getDeliveryTag();
                //消息内容
                String msg = new String(body, "utf-8");
                System.out.println("receive message:" + msg);
            }
        };
        /**
         *监听队列String queue, boolean autoAck,Consumer callback
         *参数明细
         *1、队列名称
         *2、是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置  为false则需要手动回复
         *3、消费消息的方法,消费者接收到消息后调用此方法
         */
        channel.basicConsume(QUEUE_EMAIL, false, consumer);
    }
}

另一个消费者代码与这个基本一样,只需要改下参数即可,我就不在这里粘贴代码了。
接下来去rabbitMQ管理界面查看我们的交换机,点击刚创建的交换机
在这里插入图片描述
点击bindings查看绑定状况
在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值