1:导入依赖
2:编写消息发送类NewTask.java
3:编写消息接收类Worker.java
4:测试
pom.xml
<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.7.0</version>
</dependency>
*******arguement 参数
NewTask .java
public class NewTask {
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.163.131");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
//确保消息不会丢失需要做两件事:我们需要将队列和消息都标记为持久。
//1需要声明队列是持久的
//2现在我们需要将消息标记为持久性 - 通过将MessageProperties(实现BasicProperties)设置为值PERSISTENT_TEXT_PLAIN。
channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
String message = String.join(" ", argv);
//此时我们确信即使RabbitMQ重新启动,task_queue队列也不会丢失。现在我们需要将消息标记为持久性 -
// 通过将MessageProperties(实现BasicProperties)设置为值PERSISTENT_TEXT_PLAIN。
// //第一个参数是交换的名称。空字符串表示默认或无名交换:消息通过routingKey指定的名称路由到队列(如果存在),routingkey指定名称跟队列名称相同找到是否存在,如果没有找到就可以传递消息到队列
channel.basicPublish("", TASK_QUEUE_NAME,
MessageProperties.PERSISTENT_TEXT_PLAIN,
message.getBytes("UTF-8"));
System.out.println(" [x] Sent '" + message + "'");
}
}
}
Worker .java
public class Worker {
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.163.131");
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");
//可以使用basicQos方法和 prefetchCount = 1设置。这告诉RabbitMQ一次不向一个worker发送一条消息。
// 或者,换句话说,在处理并确认前一个消息之前,不要向工作人员发送新消息。相反,它会将它发送给下一个仍然很忙的工人。
channel.basicQos(1);
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received '" + message + "'");
try {
doWork(message);
} finally {
System.out.println(" [x] Done");
//手动确认消息ack:默认情况下,手动消息确认已打开。在前面的示例中,我们通过autoAck = true 标志明确地将它们关闭。
// 一旦我们完成任务,就应该将此标志设置为false并从工作人员发送正确的确认。
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
//用于传递确认的API方法通常作为客户端库中的通道上的操作公开。
// Java客户端用户将分别使用Channel#basicAck和Channel#basicNack 来执行basic.ack和basic.nack。
// 这是一个Java客户端示例,它表明了一个积极的认可:
/**
* basic.ack用于肯定确认
* basic.nack用于否定确认(注意:这是AMQP 0-9-1的RabbitMQ扩展) 可以批量拒绝也可以单个
* basic.reject用于否定确认,但与basic.nack相比有一个限制
*/
}
};
channel.basicConsume(TASK_QUEUE_NAME, false, deliverCallback, consumerTag -> { });
}
//每个点模拟做一件事,需要1秒时间
private static void doWork(String task) {
for (char ch : task.toCharArray()) {
if (ch == '.') {
try {
Thread.sleep(1000);
} catch (InterruptedException _ignored) {
Thread.currentThread().interrupt();
}
}
}
}
}