【RabbitMQ】 Java简单的实现RabbitMQ
准备工作
1、安装RabbitMQ,参考【RabbitMQ】 RabbitMQ安装
2、新建Java项目,引入RabbitMQ的Maven依赖
1 <dependency> 2 <groupId>com.rabbitmq</groupId> 3 <artifactId>amqp-client</artifactId> 4 <version>5.5.0</version> 5 </dependency>
单生产者消费者
流程图:

1、创建生产者Producer1
1 public class Producer1 {
2
3 private final static String QUEUE_NAME = "rabbitMQ.test.queue";
4
5 public static void main(String[] args) throws IOException, TimeoutException {
6
7 // 创建连接工厂
8 ConnectionFactory factory = new ConnectionFactory();
9 // 设置RabbitMQ相关信息
10 factory.setHost("localhost");
11 factory.setUsername("guest");
12 factory.setPassword("guest");
13 factory.setPort(5672);
14 // 创建一个新的连接
15 Connection connection = factory.newConnection();
16 // 创建一个通道
17 Channel channel = connection.createChannel();
18
19 // 声明一个队列
20 // queueDeclare(队列名称,是否持久化(true表示是,队列将在服务器重启时生存),是否是独占队列(创建者可以使用的私有队列,断开后自动删除),
21 // 当所有消费者客户端连接断开时是否自动删除队列,队列的其他参数)
22 channel.queueDeclare(QUEUE_NAME, false, false, false, null);
23 String message = "Hello RabbitMQ ~";
24
25 // 发送消息到队列中
26 // basicPublish(交换机名称,队列映射的路由key,消息的其他属性,发送信息的主体)
27 channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
28 System.out.println("Producer Send +'" + message + "'");
29 // 关闭通道和连接
30 channel.close();
31 connection.close();
32
33 }
34
35 }
2、创建消费者Customer1
1 public class Customer1 {
2
3 private final static String QUEUE_NAME = "rabbitMQ.test.queue";
4
5 public static void main(String[] args) throws IOException, TimeoutException {
6 // 创建连接工厂
7 ConnectionFactory factory = new ConnectionFactory();
8 // 设置RabbitMQ地址
9 factory.setHost("localhost");
10 factory.setUsername("guest");
11 factory.setPassword("guest");
12 factory.setPort(5672);
13 // 创建一个新的连接
14 Connection connection = factory.newConnection();
15 // 创建一个通道
16 final Channel channel = connection.createChannel();
17 // 声明要关注的队列
18 channel.queueDeclare(QUEUE_NAME, false, false, false, null);
19 channel.basicQos(1);//保证一次只分发一个
20 System.out.println("Customer Waiting Received messages");
21
22 // DefaultConsumer类实现了Consumer接口,通过传入一个频道,
23 // 告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery
24 Consumer consumer = new DefaultConsumer(channel) {
25 @Override
26 public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
27 byte[] body) throws IOException {
28 String message = new String(body, "UTF-8");
29 System.out.println("Customer Received '" + message + "'");
30 }
31 };
32
33 // 自动回复队列应答 -- RabbitMQ中的消息确认机制
34 channel.basicConsume(QUEUE_NAME, true, consumer);
35 }
36
37 }
3、运行结果
a、生产者

b、消费者

推送确认和消费应答
流程图

1、创建推送确认生产者Producer2
1 public class Producer2 {
2
3 private final static String QUEUE_NAME = "rabbitMQ.test.queue";
4
5 public static void main(String[] args) throws IOException, TimeoutException {
6
7 // 创建连接工厂
8 ConnectionFactory factory = new ConnectionFactory();
9 // 设置RabbitMQ相关信息
10 factory.setHost("localhost");
11 factory.setUsername("guest");
12 factory.setPassword("guest");
13 factory.setPort(5672);
14 // 创建一个新的连接
15 Connection connection = factory.newConnection();
16 // 创建一个通道
17 Channel channel = connection.createChannel();
18
19 // 声明一个队列
20 // queueDeclare(队列名称,是否持久化(true表示是,队列将在服务器重启时生存),是否是独占队列(创建者可以使用的私有队列,断开后自动删除),
21 // 当所有消费者客户端连接断开时是否自动删除队列,队列的其他参数)
22 channel.queueDeclare(QUEUE_NAME, false, false, false, null);
23
24 // 开启发送方确认模式
25 channel.confirmSelect();
26
27 // 存储未确认的消息标识tag
28 final SortedSet<Long> confirmSet = Collections.synchronizedNavigableSet(new TreeSet<Long>());
29
30 // 异步监听确认和未确认的消息
31 channel.addConfirmListener(new ConfirmListener() {
32
33 /**
34 * 处理返回确认成功
35 *
36 * @param deliveryTag 如果是多条,这个就是最后一条消息的tag
37 * @param multiple 是否多条
38 * @throws IOException
39 */
40 public void handleAck(long deliveryTag, boolean multiple) throws IOException {
41 System.out.println("消息发送成功, deliveryTag:" + deliveryTag + " multiple:" + multiple + "");
42 if (multiple) {
43 // 移除发送成功的多条消息标识tag
44 confirmSet.headSet(deliveryTag + 1).clear();
45 } else {
46 // 移除发送成功的一条消息标识tag
47 confirmSet.remove(deliveryTag);
48 }
49 }
50
51 /**
52 * 处理返回确认失败
53 *
54 * @param deliveryTag 如果是多条,这个就是最后一条消息的tag
55 * @param multiple 是否多条
56 * @throws IOException
57 */
58 public void handleNack(long deliveryTag, boolean multiple) throws IOException {
59 System.out.println("失败,deliveryTag:" + deliveryTag + "multiple:" + multiple + "");
60 if (multiple) {
61 confirmSet.headSet(deliveryTag + 1).clear();
62 } else {
63 confirmSet.remove(deliveryTag);
64 }
65 }
66
67 });
68
69 String message = "Hello RabbitMQ ~ ";
70
71 // 发送消息到队列中
72 // basicPublish(交换机名称,队列映射的路由key,消息的其他属性,发送信息的主体)
73 for (int i = 1; i <= 10; i++) {
74 String msg = message + i;
75 long tag = channel.getNextPublishSeqNo();
76 confirmSet.add(tag);
77 System.out.println("tag:" + tag);
78
79 channel.basicPublish("", QUEUE_NAME, null, msg.getBytes("UTF-8"));
80 System.out.println("Producer Send +'" + msg + "'");
81
82 }
83
84 System.out.println("============================");
85 // 关闭通道和连接
86 // channel.close();
87 // connection.close();
88
89 }
90 }
2、创建消费应答消费者Customer2
1 public class Customer2 {
2
3 private final static String QUEUE_NAME = "rabbitMQ.test.queue";
4
5 public static void main(String[] args) throws IOException, TimeoutException {
6 // 创建连接工厂
7 ConnectionFactory factory = new ConnectionFactory();
8 // 设置RabbitMQ地址
9 factory.setHost("localhost");
10 factory.setUsername("guest");
11 factory.setPassword("guest");
12 factory.setPort(5672);
13 // 创建一个新的连接
14 Connection connection = factory.newConnection();
15 // 创建一个通道
16 final Channel channel = connection.createChannel();
17 // 声明要关注的队列
18 channel.queueDeclare(QUEUE_NAME, false, false, false, null);
19 channel.basicQos(1);// 保证一次只分发一个
20 System.out.println("Customer Waiting Received messages");
21
22 // DefaultConsumer类实现了Consumer接口,通过传入一个频道,
23 // 告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery
24 Consumer consumer = new DefaultConsumer(channel) {
25 @Override
26 public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
27 byte[] body) throws IOException {
28 String message = new String(body, "UTF-8");
29 System.out.println("Customer Received '" + message + "'");
30
31 // 返回消费确认状态
32 channel.basicAck(envelope.getDeliveryTag(), false);
33 }
34 };
35
36 // 消费手动确认 -- RabbitMQ中的消息确认机制
37 channel.basicConsume(QUEUE_NAME, false, consumer);
38 }
39
40 }
3、运行结果
生产者:

消费者:

多消费者
流程图

1、创建推送确认生产者Producer3(与示例Producer2一样)
2、创建消费应答消费者Customer3
1 public class Customer3 {
2
3 private final static String QUEUE_NAME = "rabbitMQ.test.queue";
4
5 public static void main(String[] args) throws IOException, TimeoutException {
6 Customer3 customer3 = new Customer3();
7 customer3.createCustomer("customer1");
8 customer3.createCustomer("customer2");
9 }
10
11 public void createCustomer(final String customerName) throws IOException, TimeoutException{
12
13 // 创建连接工厂
14 ConnectionFactory factory = new ConnectionFactory();
15 // 设置RabbitMQ地址
16 factory.setHost("localhost");
17 factory.setUsername("guest");
18 factory.setPassword("guest");
19 factory.setPort(5672);
20 // 创建一个新的连接
21 Connection connection = factory.newConnection();
22 // 创建一个通道
23 final Channel channel = connection.createChannel();
24 // 声明要关注的队列
25 channel.queueDeclare(QUEUE_NAME, false, false, false, null);
26 channel.basicQos(1);// 保证一次只分发一个
27 System.out.println(customerName + " Waiting Received messages");
28
29 // DefaultConsumer类实现了Consumer接口,通过传入一个频道,
30 // 告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery
31 Consumer consumer = new DefaultConsumer(channel) {
32 @Override
33 public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
34 byte[] body) throws IOException {
35 String message = new String(body, "UTF-8");
36 System.out.println(customerName + " Received '" + message + "'");
37
38 // doWork处理任务
39 doWork(customerName);
40
41 // 返回消费确认状态
42 channel.basicAck(envelope.getDeliveryTag(), false);
43 }
44 };
45
46 // 消费手动确认 -- RabbitMQ中的消息确认机制
47 channel.basicConsume(QUEUE_NAME, false, consumer);
48 }
49
50
51 private void doWork(String customer) {
52 try {
53 Thread.sleep(2000); // 暂停2秒钟
54 System.out.println(customer + ": completion of the job!");
55 } catch (InterruptedException _ignored) {
56 Thread.currentThread().interrupt();
57 }
58 }
59 }
3、运行结果
生产者与前面相同
消费者


浙公网安备 33010602011771号