Rabbit MQ client API development

Project started

The first step necessary to introduce the corresponding jar package

<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.6.0</version>
</dependency>

RabbitMQ connection

RabbitMQ connection in two ways: 1. connection 2. The connection URI based on specific parameters
based on specific parameters of the connection (user name, password, IP addresses, virtual broker, port number)

// 声明连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 使用连接工厂赋值 userName、password、host、vHost、port 等等
factory.setUsername("userName");
factory.setPassword("password");
factory.setHost("host");
factory.setVirtualHost("vhost");
factory.setPort(5672);
// 创建连接
Connection conn = factory.newConnection();

The connection URI may be the URI of the selected mode to achieve

ConnectionFactory factory = new ConnectionFactory();
factory.setUri("amqp://userName:password@host:port/vhost");
Connection connection = factory.newConnection();
System.out.println(connection);
connection.close();

Connection can be used to create multiple instances Channel, but Channel instance can not be shared between threads, each thread should open up a Channel. Threads share will lead to an error of communication frames interleaved on the network, but also affect the operation confirmation mechanism of the sender, so multiple threads shared between Channel instance is not thread safe.

And switches use the queue

How to declare a queue and switches

Channel channel = connection.createChannel();
channel.exchangeDeclare("exchangeName", "direct", true);
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, "exchangeName", "routuingKey");

We created above a persistent, non-automatic deletion, binding type to direct the switch, but also created a non-persistent, exclusive, automatic deletion of the queue (the name of this queue is automatically generated by the RabbitMQ).

Detailed methods exchangeDeclare

exchangeDeclare overloads are a plurality of default by the following parameters in this method thereof.

public DeclareOk exchangeDeclare(String exchange, String type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments) throws IOException;

此方法的返回值是 Exchange.DeclareOk 用来标识成功声明了一个交换器。
参数说明
  1.exchange: 交换器的名称。
  2.type: 交换器的类型。
  3.durable: 设置是否持久化。true 表示持久化 false 表示非持久化。持久化可以将交换器存盘,在服务器重启的时候不会丢失相关信息。
  4.autoDelete: 设置是否自动删除。true 表示自动删除。自动删除的前提是至少有一个队列或者交换器与这个交换器绑定,之后所有与这个交换器绑定的队列或者交换器都与此解绑。注意不能错误地把这个参数理解为: “当与此交换器连接的客户端都断开时,RabbitMQ 会自动删除本交换器”。
  5.internal: 设置是否是内置的。true 则表示内置交换器,客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式。
  6.arguments: 其他一些结构化参数。比如 alternate-exchange。

有声明创建交换器的方法,也对应肯定也有删除交换器的方法。其中 exchange 表示交换器的名称,而 ifUnuserd 用来设置在交换器没有被使用的情况下删除,如果设置为 true,则只有再此交换器没有被使用的情况下才会被删除,如果设置为 false,则无论如何这个交换器都要被删除。

public AMQP.Exchange.DeleteOk exchangeDelete(String exchange, boolean ifUnused) throws IOException;
public AMQP.Exchange.DeleteOk exchangeDelete(String exchange, boolean ifUnused) throws IOException;

不带任何参数的 queueDeclare 方法默认创建一个由 RabbitMQ 命名的名称,这种队列也称匿名队列,拥有排他、自动删除、非持久化的属性。

queueDeclare 方法详解

public AMQP.Queue.DeclareOk queueDeclare() throws IOException;
public AMQP.Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments) throws IOException;

QueueDeclare method without any parameters to create the default name of a named by RabbitMQ, which is also known as anonymous queue queue, it has exclusive, automatic deletion, non-persistent attributes.
Parameter Description :
  1.queue: name of the queue.
  2.durable: Set whether persistence. true that persistent false represents a non-persistent.
  3.exclusive: Set whether to discharge him. true means to discharge him if a queue is declared as exclusive queue, the queue is only visible for the first time declared its connection and automatically deleted when the connection is broken.
    3.1. Connection based exclusively queue (Connection) visible. Different channels (Channel) with a connection that can access the same connections created exclusively queue at the same time;
    3.2 "first" means that if a connection already declared an exclusive queue, exclusive queue of other connections are not allowed to build the same name, the different queues ordinary:
    3.3, even if the queue is persistent, once the connection is closed or the client exits, the exclusive queue will be deleted automatically, this applies to a client queue simultaneously transmitted and the message reading application scenarios.
  4.autoDelete: Set whether to automatically delete. true means to automatically delete.
    4.1 is automatically deleted premise: there is at least one consumer connection to the queue, when after all consumers connected to the queue are disconnected before they are automatically deleted. This parameter can not be understood as a mistake: "When all clients connected to this queue is disconnected, the queue is automatically deleted" because the producer client creates the queue, or no consumer clients to connect to this queue, will not automatically delete the queue.
  5.arguments: set some other parameters of the queue. The x-rnessage-ttl, x-expires, x -rnax-length, x-rnax-length-bytes, x-deadletter-exchange, x-deadletter-routing-key, x-rnax-priority and the like.

Corresponding to the exchanger, there is a corresponding queue on the method to remove. Which represents the queue queue name, and ifUnuserd to set deleted in the queue are not being used, if set to true, then only this queue will not be deleted in the case to be used, if set to false, anyway this queue must be removed. ifEmpty set to true, it can be eliminated in the case where the queue is empty (there is no message queue buildup) of.

public AMQP.Queue.DeleteOk queueDelete(String queue) throws IOException;
public AMQP.Queue.DeleteOk queueDelete(String queue, boolean ifUnused, boolean ifEmpty) throws IOException;

Another method used to empty the contents of the queue, the queue without deleting itself.

public AMQP.Queue.PurgeOk queuePurge(String queue) throws IOException;

Detailed methods exchangeBind

In addition to the switch queue can be bound and may also be exchanged with binding switch, bindings exactly the same method.

public AMQP.Exchange.BindOk exchangeBind(String destination, String source, String routingKey) throws IOException;
public AMQP.Exchange.BindOk exchangeBind(String destination, String source, String routingKey, Map<String, Object> arguments) throws IOException;

Parameters :
  1.destination: switch to be bound or queue
  2.source: switch need to be bound or queue.
  3.routingKey: routing keys.
  4. Other structural parameters.

Send a message

Channel.basicPublish is to send a message.

String message = "Hello Word!";
channel.basicPublish("exchangeName", "routingKey", null, message.getBytes());

Method Summary

public void basicPublish(String exchange, String routingKey, AMQP.BasicProperties props, byte[] body) throws IOException;
public void basicPublish(String exchange, String routingKey, boolean mandatory, AMQP.BasicProperties props, byte[] body) throws IOException;
public void basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, AMQP.BasicProperties props, byte[] body) throws IOException;

参数说明
  1.exchange: 交换器的名称,指明消息需要发送到哪个交换器中。如果设置为空串。则消息会被发送到 RabbitMQ 默认的交换器中。
  2.routhingKey: 路由键,交换器根据路由键将消息存储到相应的队列之中。
  3.props: 消息的基本属性集。其包含 14 个属性成员,分别有 contentType、content Encoding、headers(Map<String, Object>)、deliveryMode、priority、correlationld、replyTo、expiration、messageld、timestamp、type、userld、appld、clusterld。
  4.body: 消息体需要发送的消息。
  5.mandatory: true 表示如果交换器根据路由键无法找到符合条件的队列时会将消息返回给生产者 false 时将消息直接丢弃。
  6.immediate: true 表示交换器将消息路由到队列发现并不存在消费者时那么此消息不会被放入队列。

消费消息

RabbitMQ 消息模式分两种: 推 Push 模式和拉 Pull 模式。推模式采用 Basic.Consume 进行消费,而拉则是调用 Basic.Get 进行消费。我们只介绍推模式,对拉模式感兴趣可自行研究。

Connection conn = factory.newConnection();
Channel channel = conn.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.basicQos(1);
DeliverCallback deliverCallback = new DeliverCallback() {
	@Override public void handle(String s, Delivery delivery) throws IOException {
		String message = new String(delivery.getBody(), "UTF-8");
		System.out.println("RabbitMqWorkRec1Test Received: " + message);
		channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
	}
};
channel.basicConsume(QUEUE_NAME, false, deliverCallback, new CancelCallback() {
	@Override public void handle(String s) throws IOException {
		System.out.println("RabbitMqWorkRec1Test CancelCallback==========> " + s);
	}
});

以上代码中显式的 ack 操作对于消费者来说是非常必要的,可以防止必须要的消息丢失。

方法概览

public String basicConsume(String queue, boolean autoAck, DeliverCallback deliverCallback, CancelCallback cancelCallback) throws IOException;
public String basicConsume(String queue, boolean autoAck, String consumerTag, boolean noLocal, boolean exclusive, Map<String, Object> arguments, Consumer callback) throws IOException;

Parameter Description :
  1.queue: queue name.
  2.autoAck: Set whether to automatically confirm. true means no automatic confirmation, the proposed set to false.
  3.consumerTag: consumer labels used to distinguish between multiple consumers.
  4.noLocal: set to true, a message can not be sent by the producer connection to pass the consumer connection.
  5.exclusive: Set whether to discharge him.
  6.arguments: set other parameters consumers.
  7.callback: Set the consumer's callback function. RabbitMQ push over for processing a message.

Demo sample

Finally, it seems consumers complete production examples below.
Producers

public class RabbitMqPubTest {
	private static final String EXCHANGE_NAME = "test_exchange_fanout";

	public static void main(String[] args) {
		Connection conn = null;
		Channel channel = null;
		try {
			ConnectionFactory factory = new ConnectionFactory();
			factory.setUsername("userName");
			factory.setPassword("password");
			factory.setHost("host");
			factory.setVirtualHost("vhost");
			factory.setPort(5672);
			conn = factory.newConnection();
			channel = conn.createChannel();
			channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
			String message = "Hello Word!";
			channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
			System.out.println("RabbitMqPubTest send: " + message);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != channel) {
				try {
					channel.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (null != conn) {
				try {
					conn.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}

consumer

public class RabbitMqSub01Test {
	private static final String EXCHANGE_NAME = "test_exchange_fanout";

	public static void main(String[] args) throws Exception {
		ConnectionFactory factory = new ConnectionFactory();
		factory.setUsername("userName");
		factory.setPassword("password");
		factory.setHost("host");
		factory.setVirtualHost("vhost");
		factory.setPort(5672);
		Connection conn = factory.newConnection();
		Channel channel = conn.createChannel();
		channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
		String queueName = channel.queueDeclare().getQueue();
		System.out.println("RabbitMqSub01Test queueName: " + queueName);
		channel.queueBind(queueName, EXCHANGE_NAME, "");
		DeliverCallback deliverCallback = new DeliverCallback() {
			@Override public void handle(String s, Delivery delivery) throws IOException {
				String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
				System.out.println("RabbitMqSub01Test Received: " + message);
			}
		};
		channel.basicConsume(queueName, true, deliverCallback, new CancelCallback() {
			@Override public void handle(String s) throws IOException {

			}
		});
	}
}

public class RabbitMqSub02Test {
	private static final String EXCHANGE_NAME = "test_exchange_fanout";

	public static void main(String[] args) throws Exception {
		ConnectionFactory factory = new ConnectionFactory();
		factory.setUsername("userName");
		factory.setPassword("password");
		factory.setHost("host");
		factory.setVirtualHost("vhost");
		factory.setPort(5672);
		Connection conn = factory.newConnection();
		Channel channel = conn.createChannel();
		channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
		String queueName = channel.queueDeclare().getQueue();
		System.out.println("RabbitMqSub02Test queueName: " + queueName);
		channel.queueBind(queueName, EXCHANGE_NAME, "");
		DeliverCallback deliverCallback = new DeliverCallback() {
			@Override public void handle(String s, Delivery delivery) throws IOException {
				String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
				System.out.println("RabbitMqSub02Test Received: " + message);
			}
		};
		channel.basicConsume(queueName, true, deliverCallback, new CancelCallback() {
			@Override public void handle(String s) throws IOException {

			}
		});
	}
}

These are commonly used java rabbitMQ API operation, Thanks for watching! Inadequate please comment!

Guess you like

Origin blog.csdn.net/qq_16830879/article/details/90079934