易学笔记-RabbitMQ教程2:一个生产者和多个消费者

  • RabbitMQ教程2:一个生产者和多个消费者
  1. 代码基础: 易学笔记-RabbitMQ教程1:一个生产者和一个消费者
  2. 新建生产者类:
    package OneProductMulConsume;
    
    import java.io.IOException;
    import java.util.concurrent.TimeoutException;
    
    import com.rabbitmq.client.ConnectionFactory;
    import com.rabbitmq.client.Connection;
    import com.rabbitmq.client.Channel;
    import com.rabbitmq.client.MessageProperties;
    
    public class OneProductSend {
    
    	private static final String TASK_QUEUE_NAME = "task_queue";
    
    	public static void main(String[] argv) throws java.io.IOException,
    			TimeoutException {
    
    		ConnectionFactory factory = new ConnectionFactory();
    		factory.setHost("192.168.65.129");
    		Connection connection = factory.newConnection();
    		Channel channel = connection.createChannel();
    
    		/**
    		 * 第二个参数为true表示队列持久化
    		 */
    		channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
    
    		for (int i = 0; i < 10; i++) {
    
    			String message = "X";
    			for (int j = 0; j < i; j++) {
    				message += ".";
    			}
    			
    			message = message + "(" + i + ")";
    			
    			/**
    			 * MessageProperties.PERSISTENT_TEXT_PLAIN:表示消息持久化
    			 */
    			channel.basicPublish("", TASK_QUEUE_NAME,
    					MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
    			System.out.println(" [x] Sent '" + message + "'");
    		}
    
    		channel.close();
    		connection.close();
    	}
    	// ...
    }
    1. 消息持久化

      /**

                       * MessageProperties.PERSISTENT_TEXT_PLAIN:表示消息持久化

                       */

                      channel.basicPublish("", TASK_QUEUE_NAME,

                                MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());

    队列持久化:

    /**

                * 第二个参数为true表示队列持久化

                */

               channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);

  3. 新建消费者类:
    package OneProductMulConsume;
    
    import com.rabbitmq.client.*;
    
    import java.io.IOException;
    
    public class MulConsumeRecv {
      private static final String TASK_QUEUE_NAME = "task_queue";
    
      public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.65.129");
        final Connection connection = factory.newConnection();
        final Channel channel = connection.createChannel();
    
        channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
    
        /**
         * 表示每次只从消息队列中获取一条消息,等处理完成后通知服务端再发送下一条消息
         */
        channel.basicQos(1);
    
        final Consumer consumer = new DefaultConsumer(channel) {
          @Override
          public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
            String message = new String(body, "UTF-8");
    
            System.out.println(" [x] Received '" + message + "'");
            try {
              doWork(message);
            } finally {
              System.out.println(" [x] Done");
              /**
               * 处理完成后通知服务端
               */
              channel.basicAck(envelope.getDeliveryTag(), false);
            }
          }
        };
        /**
         * 第二个参数为false表示处理完成后通知服务端,以便服务端进行确认
         */
        boolean autoAck = false;
        channel.basicConsume(TASK_QUEUE_NAME, autoAck, consumer);
      }
    
      private static void doWork(String task) {
        for (char ch : task.toCharArray()) {
          if (ch == '.') {
            try {
              Thread.sleep(1000);
            } catch (InterruptedException _ignored) {
              Thread.currentThread().interrupt();
            }
          }
        }
      }
    }
    
    1. 设置消费者返回明确的处理结果标志

       /**

           * 第二个参数为false表示处理完成后通知服务端,以便服务端进行确认

           */

          boolean autoAck = false;

          channel.basicConsume(TASK_QUEUE_NAME, autoAck, consumer);

    2. 消费者返回结果处理标识

        /**

                 * 处理完成后通知服务端

                 */

                channel.basicAck(envelope.getDeliveryTag(), false);

    每次只接受1个消息

     /**

         * 表示每次只从消息队列中获取一条消息,等处理完成后通知服务端再发送下一条消息

         */

        channel.basicQos(1);

  4. 测试
    1. 循环分发:两个工作者循环获取消息并处理(总共10个消息
      1. 先启动工作者1:处理了8个消息

         [*] Waiting for messages. To exit press CTRL+C

         [x] Received 'X(0)'

         [x] Done

         [x] Received 'X.(1)'

         [x] Done

         [x] Received 'X..(2)'

         [x] Done

         [x] Received 'X...(3)'

         [x] Done

         [x] Received 'X....(4)'

         [x] Done

         [x] Received 'X.....(5)'

         [x] Done

         [x] Received 'X.......(7)'

         [x] Done

         [x] Received 'X.........(9)'

         [x] Done

      2. 后启动工作者2:处理了2个消息

         [*] Waiting for messages. To exit press CTRL+C

         [x] Received 'X......(6)'

         [x] Done

         [x] Received 'X........(8)'

         [x] Done

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易学笔记(qq:1776565180)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值