三、RabbitMQのシンプルなキュー(簡易キュー)

簡単な待ち行列モデル

シンプルなキューモデル

  • P(プロデューサー):メーカー - 送信メッセージ
  • Q(キュー):メッセージ・キュー(図赤四角) - 格納されたメッセージ
  • C(消費者):消費者は - メッセージを受け取ります

二、Javaプログラミング

    1、ジャー導入AMQPプロトコルパケット(RabbitMQのAMQPベースの通信プロトコル)。

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

    春-AMQP-1.3.5.RELEASEダウンロード

    2、RabbitMQの接続ツールを作成します。

package com.rabbitMQ.util;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class ConnectionUtils {
	
       /**
         * 获取RabbitMQ的连接
	 * @return Connection  
	 * @author zhoujin
	 * @throws TimeoutException 
	 * @throws IOException 
	 * @date 2019-1-13
	 */
	public static Connection getConnection() throws IOException, TimeoutException{
		// 1.定义连接工厂
		ConnectionFactory factory = new ConnectionFactory();
		// 2.设置连接参数
		factory.setHost("127.0.0.1");           // 连接地址
		factory.setPort(5672);                  // 监听端口
		factory.setVirtualHost("/vhost_study");  // vhost
		factory.setUsername("study_user");      // 用户名
		factory.setPassword("123");             // 密码
		// 3.返回连接对象
		return factory.newConnection();
	}
	
	/**
	 * 关闭连接
	 * @param connection
	 * @throws IOException
	 * @return void
	 * @author zhoujin
	 * @data 2019-1-13
	 */
	public static void closeConnection(Connection connection) throws IOException{
		if (connection != null) {
			connection.close();
		}
	}
	
	/**
	 * 关闭通道以及连接(先后顺序不能颠倒)
	 * @param connection
	 * @throws IOException
	 * @return void
	 * @author zhoujin
	 * @throws TimeoutException 
	 * @data 2019-1-13
	 */
	public static void closeConnection(Channel channel, Connection connection) throws IOException, TimeoutException{
		if (channel != null) {
			channel.close();
		}
		if (connection != null) {
			connection.close();
		}
	}

}

    3、プロデューサを作成するメッセージを送信します。

package com.rabbitMQ.simple;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitMQ.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

/**
 * 消息生产者
 * @author zhoujin
 * @data 2019-1-13
 */
public class SimpleProducer {
	
	private static final String QUEUE_NAME = "simple_queue";
	
	public static void main(String[] args) {
		Connection conn = null;
		Channel channel = null;
		try {
			// 1.获取连接
			conn = ConnectionUtils.getConnection();
			// 2.从连接中获取通道
			channel = conn.createChannel();
			/*
			 * 3.声明队列
			 * param_1:队列名称
			 * param_2:是否持久化(重启是否消失)
			 * param_3:是否独占(仅创建者Connection私有,断开连接后自动删除)
			 * param_4:没有连接时是否自动删除
			 * param_5:此队列的其他属性设置
			 */
			channel.queueDeclare(QUEUE_NAME, false, false, false, null);
			/*
			 * 4.发送消息到队列中
			 * param_1:交换机名称(若没有定义交换机,则此处填"",使用默认交换机)
			 * param_2:Routing Key(路由键)
			 * param_3:此消息的其他属性设置
			 * param_4:需要发送的消息内容
			 * ★ 注:默认交换机(AMQP default),它是direct类型的。默认交换机隐式地绑定到每个队列,Routing Key(路由键)等于队列名称。
			 */
			String message = "This is simple MQ!";
			channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
			
			System.out.println("======================= Simple MQ send message end! 【Content:" + message + "】 =======================");
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
		} finally {
			try {
				ConnectionUtils.closeConnection(channel, conn);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (TimeoutException e) {
				e.printStackTrace();
			}
		}
		
	}

}

    図4は、消費者がメッセージを受信作ります。

package com.rabbitMQ.simple;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitMQ.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.QueueingConsumer.Delivery;
import com.rabbitmq.client.ShutdownSignalException;

/**
 * 消息消费者(接收者)
 * @author zhoujin
 * @data 2019-1-13
 */
public class SimpleConsumer {
	
	private static final String QUEUE_NAME = "simple_queue";
	
	public static void main(String[] args) {
		// 4.x以前的版本使用旧方法
		// oldMethod();
		
		// 4.x以后的版本使用新方法
		newMethod();
	}
	
	public static void newMethod(){
		try {
			// 1.获取连接
			Connection conn = ConnectionUtils.getConnection();
			// 2.从连接中获取通道
			Channel channel = conn.createChannel();
			/*
			 * 3.声明队列
			 * param_1:队列名称
			 * param_2:是否持久化(重启是否消失)
			 * param_3:是否独占(仅创建者Connection私有,断开连接后自动删除)
			 * param_4:没有连接时是否自动删除
			 * param_5:此队列的其他属性设置
			 */
			channel.queueDeclareNoWait(QUEUE_NAME, false, false, false, null);
			// 4.定义消费者获取消息(将客户端与队列绑定,若该队列中有消息,便会执行回调函数handleDelivery)
			DefaultConsumer consumer = new DefaultConsumer(channel){
				@Override    // envelope对象中是生产者相关信息(比如交换机名、路由键等),body是消息实体
				public void handleDelivery(String consumerTag,
						Envelope envelope, BasicProperties properties,
						byte[] body) throws IOException {
					
					String message = new String(body, "UTF-8");
					System.out.println("=======================NewMethod: Simple MQ received a message! 【Content:" + message + "】 =======================");
				}
			};
			/*
			 *  5.监听队列,回复消息接收反馈,通知将此消息在队列中移出(RabbitMQ中的消息确认机制)
			 *  param_1: 队列名称
			 *  param_2: autoAck:是否自动ack。如果不自动ack,需要使用channel.ack、channel.nack、channel.basicReject进行消息应答。
			 *  param_3: 消费者对象
			 */
			channel.basicConsume(QUEUE_NAME, true, consumer);
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 4.x版本之前
	 * @return void
	 * @author zhoujin
	 * @data 2019-1-13
	 */
	public static void oldMethod(){
		try {
			// 1.获取连接
			Connection conn = ConnectionUtils.getConnection();
			// 2.从连接中获取通道
			Channel channel = conn.createChannel();
			// 3.定义队列的消费者(4.x版本开始废弃)
			QueueingConsumer consumer = new QueueingConsumer(channel);
			// 4.监听队列
			channel.basicConsume(QUEUE_NAME, true, consumer);
			// 5.获取消息
			while(true){
				Delivery delivery = consumer.nextDelivery();
				String message = new String(delivery.getBody(), "UTF-8");
				System.out.println("======================= Simple MQ received a message! 【Content:" + message + "】 =======================");
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
		} catch (ShutdownSignalException e) {
			e.printStackTrace();
		} catch (ConsumerCancelledException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

第三に、コードとコンソール出力を実行します

    図1に示すように、操作コードの生産。

    1.1、コンソール出力

プロデューサーのコンソール出力

    Web管理ページでは1.2、ビューのメッセージ

ビューのニュースへのWebページ_1

    1.3、ビューの管理にWebページがメッセージを取得します 

メッセージを表示するためにWebページ_2

    2、消費者は、プログラムを実行します。

    2.1消費者コンソール出力(旧方式)

消費者のコンソール出力

    2.2、コンソール出力のための新しい方法

消費者のコンソール出力_NewMethod

第四に、シンプルなキュー(簡易キュー)不満

    あなたは、複数の消費者は、キューからメッセージを取得したい場合は、高、生産者の対応、消費者のカップリング、あなたが取得することはできません。キュー名の変更は、私たちは生産者と消費者の側面を変更する必要があります。

 


公開された47元の記事 ウォン称賛16 ビュー70000 +

おすすめ

転載: blog.csdn.net/zorro_jin/article/details/86648173