Three, RabbitMQ the simple queue (Simple Queue)

A simple queuing model

Simple Queue model

  • P (producer): Manufacturer - Send message
  • Q (Queue): a message queue (FIG red squares) - stored message
  • C (consumer): Consumers - receive messages

Two, Java programming

    1, jar introduced AMQP protocol packet (RabbitMQ AMQP based communication protocol);

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

    spring-amqp-1.3.5.RELEASE Download

    2, create RabbitMQ connection tools;

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, create a producer sends a message;

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, create a consumer receives a message.

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();
		}
	}

}

Third, run the code and console output

    1, operation codes producers;

    1.1, the console output

Producer console output

    1.2, view messages in the web management page

web page to view news _1

    1.3, the web page to view management gets the message 

web page to view the message _2

    2, consumers run the program.

    2.1 Consumers console output (the old method)

Consumers console output

    2.2, a new method for console output

Consumers console output _NewMethod

Fourth, Simple Queue (Simple Queue) inadequate

    Coupling high, producers correspondence consumers, if you want to have multiple consumers get messages from the queue, you can not get. Queue name change, we need to change the producer and consumer sides.

 


Published 47 original articles · won praise 16 · views 70000 +

Guess you like

Origin blog.csdn.net/zorro_jin/article/details/86648173