RabbitMQ系列之三 RabbitMQ几种典型模式

本文详细介绍了RabbitMQ的六种模式:简单模式、工作模式、发布订阅模式、路由模式、通配符模式和远程调用模式。每个模式都包含生产者和消费者的实现代码,旨在帮助读者理解RabbitMQ在不同场景下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文详细介绍简单模式Simple、工作模式Work、发布订阅模式Publish/Subscribe、路由模式Routing、通配符模式Topics、远程调用模式RPC(暂不对该队列模式进行详解)

模式1:简单模式(Simple / HelloWorld 单生产单消费)
简单的发送与接收,没有特别的处理。

RabbitMQ连接(公共的连接方法,其他模式共用此方法)

package com.sc.queuemode.connection;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConnectionUtil {
public static Connection getConnection() throws IOException, TimeoutException {
//定义连接池
ConnectionFactory connectionFactory = new ConnectionFactory();
//连接地址
connectionFactory.setHost(“localhost”);
//连接端口
connectionFactory.setPort(5672);
//用户名
connectionFactory.setUsername(“guest”);
//密码
connectionFactory.setPassword(“guest”);
//通过连接工厂获取连接
Connection connection = connectionFactory.newConnection();
//返回连接
return connection;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Producer:

package com.sc.queuemode.simple;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {
private final static String QUEUE_NAME = “hello”;
public static void main(String[] args) throws IOException, TimeoutException {
//获取连接
Connection connection = ConnectionUtil.getConnection();
//从连接中声明通道
Channel channel = connection.createChannel();
//队列申明
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//消息内容
String message = “simple queue hello world !”;
//推送发布消息
//basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
//信道关闭
channel.close();
//连接关闭
connection.close();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Consumer:

package com.sc.queuemode.simple;

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

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Consumer1 {

private final static String QUEUE_NAME = "hello_queue";

public static void main(String[] args) throws IOException, TimeoutException{
	//获取连接
	Connection connection = ConnectionUtil.getConnection();
	//声明信道
	Channel channel = connection.createChannel();
	//声明队列
	channel.queueDeclare(QUEUE_NAME, false, false, false, null);
	//声明消费者
	Consumer consumer = new DefaultConsumer(channel) {
		@Override
		public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body) 
				throws IOException {
			String message = new String(body,"UTF-8");
			System.out.println("customer 消费消息:"+message);
		}
	};
	channel.basicConsume(QUEUE_NAME, true,consumer);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
模式2:工作模式(Work单发送多接收)
一个生产者端,多个消费者端。示例中为了保证消息发送的可靠性,不丢失消息,使消息持久化了。同时为了防止接收端在处理消息时down掉,只有在消息处理完成后才发送消息确认。

Producer:

package com.sc.queuemode.work;

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

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {

private final static String QUEUE_NAME = "work_queue";

public static void main(String[] args) throws IOException, TimeoutException {
	//获取连接
	Connection connection = ConnectionUtil.getConnection();
	//声明信道
	Channel channel = connection.createChannel();
	//队列申明,durable:true消息持久化
	channel.queueDeclare(QUEUE_NAME, true, false, false, null);
	//消息内容
	String message = getMessage(args);
	for(int i = 0; i < 20; i++) {
		//发布消息
		//basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
		channel.basicPublish("", QUEUE_NAME, null, (i + " " +message).getBytes());
	}
	//关闭通道
	channel.close();
	//连接关闭
	connection.close();
}

private static String getMessage(String[] strings) {
	if(strings.length < 1) {
		return "Hello World!";
	}
	return joinStrings(strings, "");
}

private static String joinStrings(String[] strings, String delimiter) {
	int length = strings.length;
	if(length == 0) return "";
	StringBuilder words = new StringBuilder(strings[0]);
	for(int i = 0; i < length; i++) {
		words.append(delimiter).append(strings[i]);
	}
	return words.toString();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Consumer:
消费者1

package com.sc.queuemode.work;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;
/*

  • 消费者1
    */
    public class Consumer1 {

    private final static String QUEUE_NAME = “work_queue”;
    public static void main(String[] args) throws IOException, TimeoutException{
    Connection connection = ConnectionUtil.getConnection();
    Channel channel = connection.createChannel();
    channel.queueDeclare(QUEUE_NAME, true, false, false, null);

      //同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
      //保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
      //在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
      channel.basicQos(1);
      
      //声明队列的消费者O
      Consumer consumer1 = new DefaultConsumer(channel){
      	@Override
      	public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
      			throws IOException {
      		//channel.basicConsume(QUEUE_NAME, false, consumer1);
      		String message = new String(body, "UTF-8");
      		System.out.println("customer1 消费消息:"+message);
      		//手动返回结果
      		channel.basicAck(envelope.getDeliveryTag(), false);
      		try {
      			Thread.sleep(50);
      		} catch (InterruptedException e) {
      			e.printStackTrace();
      		}
      	}
      };
      //定义的消费者监听队列 autoAck:true自动返回结果,false手动返回
      channel.basicConsume(QUEUE_NAME, false,consumer1);
    

    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    消费者2

package com.sc.queuemode.work;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;
/*
* 消费者2
*/
public class Consumer2 {
private final static String QUEUE_NAME = “work_queue”;

public static void main(String[] args) throws IOException, TimeoutException{
	Connection connection = ConnectionUtil.getConnection();
	Channel channel = connection.createChannel();
	channel.queueDeclare(QUEUE_NAME, true, false, false, null);
	
	//同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
	channel.basicQos(1);
	
	//声明队列的消费者
	Consumer consumer2 = new DefaultConsumer(channel){
		@Override
		public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
				throws IOException {
			//channel.basicConsume(QUEUE_NAME, false, consumer1);
			String message = new String(body, "UTF-8");
			System.out.println("customer2 消费消息:"+message);
			channel.basicAck(envelope.getDeliveryTag(), false);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	};
	//定义的消费者监听队列(第二个参数:true自动返回结果,false手动返回)
	channel.basicConsume(QUEUE_NAME, false,consumer2);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
模式3:发布、订阅模式(Publish/Subscribe)
使用场景:发布、订阅模式,生产者端发送消息,多个消费者同时接收所有的消息。

Producer:

package com.sc.queuemode.publish_subscrible;

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

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {

private final static String EXCHANGE_NAME = "publishSubscrible_exchange";

public static void main(String[] args) throws IOException, TimeoutException {
	Connection connection = ConnectionUtil.getConnection();
	Channel channel = connection.createChannel();
	//声明交换机Exchange类型为fanout
	channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
	
	String message = "publish/subscrible hello world";
	channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
	System.out.println("发布订阅 生产者 发布消息:"+message);
	channel.close();
	connection.close();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
生产者端发布消息到交换机,使用“fanout”方式发送,即广播消息,不需要使用queue,发送端不需要关心谁接收。
消费者1:

package com.sc.queuemode.publish_subscrible;

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

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.ShutdownSignalException;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer1 {

//队列1
private final static String QUEUE_NAME = "publishSubscrible_queue";
private final static String EXCHANGE_NAME = "publishSubscrible_exchange";

public static void main(String[] args) throws IOException, TimeoutException{
	Connection connection = ConnectionUtil.getConnection();
	Channel channel = connection.createChannel();
	//声明交换机
	channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
	//声明队列
	channel.queueDeclare(QUEUE_NAME, true, false, false, null);
	//绑定队列到交换机
	channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
	
	//同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
	//保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
	//在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
	channel.basicQos(1);
	
	//申明消费者
	Consumer consumer1 = new DefaultConsumer(channel) {
		@Override
		public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
				throws IOException {
			String message = new String(body, "UTF-8");
			System.out.println("发布订阅 消费者1 消费消息:"+message);
			//手动返回结果
			channel.basicAck(envelope.getDeliveryTag(), false);
		}
	};
	channel.basicConsume(QUEUE_NAME, false, consumer1);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
消费者2:

package com.sc.queuemode.publish_subscrible;

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

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer2 {

//队列2
private final static String QUEUE_NAME = "publishSubscrible_queue2";
private final static String EXCHANGE_NAME = "publishSubscrible_exchange";

public static void main(String[] args) throws IOException, TimeoutException{
	Connection connection = ConnectionUtil.getConnection();
	Channel channel = connection.createChannel();
	//声明交换机
	channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
	//声明队列
	channel.queueDeclare(QUEUE_NAME, true, false, false, null);
	//绑定队列到交换机
	channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
	
	//同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
	//保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
	//在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
	channel.basicQos(1);
	
	//申明消费者
	Consumer consumer2 = new DefaultConsumer(channel) {
		@Override
		public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
				throws IOException {
			String message = new String(body, "UTF-8");
			System.out.println("发布订阅 消费者2 消费消息:"+message);
			//手动返回结果
			channel.basicAck(envelope.getDeliveryTag(), false);
		}
	};
	channel.basicConsume(QUEUE_NAME, false, consumer2);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
消费者端:
1、声明和生产者端一样的交换机。
2、注意binding queue的时候,channel.queueBind()的第三个参数Routing key为空,即所有的消息都接收。如果这个值不为空,在exchange type为“fanout”方式下该值被忽略!
3、消息队列和交换机绑定如下图所示

模式4:路由模式(Routing)
生产者按routing key发送消息,不同的消费者端按不同的routing key接收消息。

Producer:

package com.sc.queuemode.routing;

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

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {

private final static String EXCHANGE_NAME = "routing_exchange";

public static void main(String[] args) throws IOException, TimeoutException {
	Connection connection = ConnectionUtil.getConnection();
	Channel channel = connection.createChannel();
	//声明交换机Exchange类型为direct
	channel.exchangeDeclare(EXCHANGE_NAME, "direct");
	
	//发布消息3种routingKey的消息
	String message = "hello info";
	channel.basicPublish(EXCHANGE_NAME, "info", null, message.getBytes());
	System.out.println("路由模式发布info消息:"+message);
	
	message = "hello warning";
	channel.basicPublish(EXCHANGE_NAME, "warning", null, message.getBytes());
	System.out.println("路由模式发布warning消息:"+message);
	
	message = "hello error";
	channel.basicPublish(EXCHANGE_NAME, "error", null, message.getBytes());
	System.out.println("路由模式发布error消息:"+message);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
消费者端和模式3(发布订阅模式)的区别:
1、exchange的type为direct
2、发送消息的时候加入了routing key
Consumer:
消费者1

package com.sc.queuemode.routing;

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

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer1 {

private final static String QUEUE_NAME = "routing_queue1";
private final static String EXCHANGE_NAME = "routing_exchange";

public static void main(String[] args) throws IOException, TimeoutException{
	Connection connection = ConnectionUtil.getConnection();
	Channel channel = connection.createChannel();
	//声明交换机
	channel.exchangeDeclare(EXCHANGE_NAME, "direct");
	//申明队列
	channel.queueDeclare(QUEUE_NAME, true, false, false, null);
	
	//队列绑定交换机,指定路由routingKey
	//结束路由routingKey为info和warning的消息
	channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "info");
	channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "warning");
	
	//同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
	//保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
	//在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
	channel.basicQos(1);
	
	//声明消费者
	Consumer consumer = new DefaultConsumer(channel) {
		@Override
		public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
				throws IOException {
			String message = new String(body, "UTF-8");
			System.out.println("路由模式 消费者1 消费消息:"+message);
			channel.basicAck(envelope.getDeliveryTag(), false);
		}
	};
	channel.basicConsume(QUEUE_NAME, false, consumer);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
消费者2

package com.sc.queuemode.routing;

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

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer2 {

private final static String QUEUE_NAME = "routing_queue2";
private final static String EXCHANGE_NAME = "routing_exchange";

public static void main(String[] args) throws IOException, TimeoutException{
	Connection connection = ConnectionUtil.getConnection();
	Channel channel = connection.createChannel();
	//声明交换机
	channel.exchangeDeclare(EXCHANGE_NAME, "direct");
	//申明队列
	channel.queueDeclare(QUEUE_NAME, true, false, false, null);
	
	//队列绑定交换机,指定路由routingKey
	//结束路由routingKey为error的消息
	channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "error");
	
	//同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
	//保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
	//在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
	channel.basicQos(1);
	
	//声明消费者
	Consumer consumer2 = new DefaultConsumer(channel) {
		@Override
		public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
				throws IOException {
			String message = new String(body, "UTF-8");
			System.out.println("路由模式 消费者2 消费消息:"+message);
			channel.basicAck(envelope.getDeliveryTag(), false);
		}
	};
	channel.basicConsume(QUEUE_NAME, false, consumer2);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
消费者端和模式3(发布订阅模式)的区别:
在绑定queue和exchange的时候使用了路由routing key,即从该exchange上只接收routing key指定的消息。
队列绑定如下图所示

模式5:通配符(或主题)模式(Topics ,按topic发送接收)
生产者端不只按固定的routing key发送消息,而是按字符串“匹配”发送,消费者端同样如此。
与之前的路由模式相比,它将信息的传输类型的key更加细化,以“key1.key2.keyN…”的模式来指定信息传输的key的大类型和大类型下面的小类型,让消费者端可以更加精细的确认自己想要获取的信息类型。而在消费者端,不用精确的指定具体到哪一个大类型下的小类型的key,而是可以使用类似正则表达式(但与正则表达式规则完全不同)的通配符在指定一定范围或符合某一个字符串匹配规则的key,来获取想要的信息。“通配符交换机”(Topic Exchange)将路由键和某模式进行匹配。此时队列需要绑定在一个模式上。符号“#”匹配一个或多个词,符号“*”仅匹配一个词。

Producer:

package com.sc.queuemode.topics;

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

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {

private static final String EXCHANGE_NAME = "topic_exchange";

public static void main(String[] args) throws IOException, TimeoutException {
	Connection connection = ConnectionUtil.getConnection();
	Channel channel =connection.createChannel();
	//声明交换机类型为topic
	channel.exchangeDeclare(EXCHANGE_NAME, "topic");
	
	String message = "发布了一条中国新闻消息";
	channel.basicPublish(EXCHANGE_NAME, "china.news", null, message.getBytes());
	
	message = "发布了一条中国天气消息";
	channel.basicPublish(EXCHANGE_NAME, "china.weather", null, message.getBytes());
	
	message = "发布了一条美国新闻消息";
	channel.basicPublish(EXCHANGE_NAME, "usa.news", null, message.getBytes());
	
	message = "发布了一条美国天气消息";
	channel.basicPublish(EXCHANGE_NAME, "usa.weather", null, message.getBytes());
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
生产者和模式4(路由模式)的区别:
1、交换机exchange的type为topic
2、发送消息的routing key不是固定的单词,而是匹配字符串,如"china.#",匹配一个单词,#匹配0个或多个单词。因此如“china.#”能够匹配到“china.news.info”,但是“china. ”只会匹配到“china.news”

Consumer:
消费者1

package com.sc.queuemode.topics;

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

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer1 {

private static final String QUEUE_NAME = "topics_queue1";
private static final String EXCHANGE_NAME = "topic_exchange";

public static void main(String[] args) throws IOException, TimeoutException{
	Connection connection = ConnectionUtil.getConnection();
	Channel channel = connection.createChannel();
	//交换机申明
	channel.exchangeDeclare(EXCHANGE_NAME, "topic");
	//队列声明
	channel.queueDeclare(QUEUE_NAME, true, false, false, null);
	//队列绑定交换机并制定路由routingKey
	channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "china.#");
	//同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
	//保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
	//在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
	channel.basicQos(1);
	//申明消费者
	Consumer consumer1 = new DefaultConsumer(channel) {
		@Override
		public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
				throws IOException {
			String message = new String(body, "UTF-8");
			System.out.println("通配符模式 消费者1消费:"+message);
			channel.basicAck(envelope.getDeliveryTag(), false);
		}
	};
	channel.basicConsume(QUEUE_NAME, false, consumer1);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
消费者2

package com.sc.queuemode.topics;

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

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer2 {

private static final String QUEUE_NAME = "topics_queue2";
private static final String EXCHANGE_NAME = "topic_exchange";

public static void main(String[] args) throws IOException, TimeoutException{
	Connection connection = ConnectionUtil.getConnection();
	Channel channel = connection.createChannel();
	//交换机申明
	channel.exchangeDeclare(EXCHANGE_NAME, "topic");
	//队列声明
	channel.queueDeclare(QUEUE_NAME, true, false, false, null);
	//队列绑定交换机并制定路由routingKey
	channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "usa.#");
	//同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
	//保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
	//在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
	channel.basicQos(1);
	//申明消费者
	Consumer consumer2 = new DefaultConsumer(channel) {
		@Override
		public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
				throws IOException {
			String message = new String(body, "UTF-8");
			System.out.println("通配符模式 消费者2消费:"+message);
			channel.basicAck(envelope.getDeliveryTag(), false);
		}
	};
	channel.basicConsume(QUEUE_NAME, false, consumer2);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
交换机和队列绑定如下图所示

————————————————
版权声明:本文为优快云博主「通往架构师的路上」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/caiqing116/article/details/84032099

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值