本文根据视频https://www.bilibili.com/video/BV1pa4y1x7Kc?p=12 创作。未经视频作者授权,如果作者感到侵权,请联系本人删除此文
header模式取消了routingkey的设置,但要设置key-value匹配队列。
header模式生产者代码:
public class HeaderProducer {
private static final String QUEUE_EMAIL = "queue_email";
private static final String QUEUE_SMS = "queue_sms";
private static final String EXCHANGE_ROUTING = "exchange_topic";
private static final String EMAIL_ROUTING_KEY = "email_key";
private static final String SMS_ROUTING_KEY = "sms_key";
public static void main(String[] args) {
//通过连接工厂创建新的连接和MQ建立连接
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
//设置虚拟机,一个MQ可以设置多个虚拟机,每个虚拟机相当于一个独立的MQ
connectionFactory.setVirtualHost("/");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = null;
Channel channel = null;
try {
//建立新的连接
connection = connectionFactory.newConnection();
//创建会话通道,生产者和MQ服务所有通信都在channel通道中完成
channel = connection.createChannel();
//声明队列,如果队列在MQ中不存在则创建
channel.queueDeclare(QUEUE_SMS, true, false, false,null);
channel.queueDeclare(QUEUE_EMAIL, true, false, false,null);
//声明交换机
//参数: String exchange, String type
/**
* 参数明细
* 1. exchange 交换机名称
* 2. 交换机类型
* fanout: 对应发布订阅模式
* direct: 对应路由模式
* topic: 对应通配符模式
* headers: 对应header转发模式
*/
channel.exchangeDeclare(EXCHANGE_ROUTING, BuiltinExchangeType.HEADERS);
//绑定交换机和队列
//参数: String queue, String exchange, String routingKey
/**
* 参数明细:
* 1. queue 队列名称
* 2. exchange 交换机名称
* 3. routingKey 路由key,作用是交换机会根据路由key的值转发到指定的队列,在发布订阅模式为空串
*/
Map<String, Object> mailHeader = new HashMap<>();
mailHeader.put(EMAIL_ROUTING_KEY, "email");
channel.queueBind(QUEUE_EMAIL, EXCHANGE_ROUTING, "", mailHeader);
Map<String, Object> smsHeader = new HashMap<>();
smsHeader.put(SMS_ROUTING_KEY, "sms");
channel.queueBind(QUEUE_SMS, EXCHANGE_ROUTING, "", smsHeader);
//发送消息制定rounting key
String message = "Hello World email";
String message1 = "Hello World sms";
AMQP.BasicProperties.Builder emailProperties = new AMQP.BasicProperties.Builder();
emailProperties.headers(mailHeader);
AMQP.BasicProperties.Builder smsProperties = new AMQP.BasicProperties.Builder();
smsProperties.headers(smsHeader);
channel.basicPublish(EXCHANGE_ROUTING, "", emailProperties.build(), message.getBytes());
channel.basicPublish(EXCHANGE_ROUTING, "", smsProperties.build(), message1.getBytes());
System.out.println("send to mq " + message);
System.out.println("send to mq " + message1);
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭连接
//先关闭通道,在关闭连接
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
header模式email消费者代码:
public class HeaderConsumerEmail {
private static final String QUEUE_EMAIL = "queue_email";
private static final String EXCHANGE_ROUTING = "exchange_topic";
private static final String EMAIL_ROUTING_KEY = "email_key";
public static void main(String[] args) throws IOException, TimeoutException {
//通过连接工厂创建新的连接和MQ建立连接
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
//设置虚拟机,一个MQ可以设置多个虚拟机,每个虚拟机相当于一个独立的MQ
connectionFactory.setVirtualHost("/");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = null;
Channel channel = null;
//建立新的连接
connection = connectionFactory.newConnection();
//创建会话通道,生产者和MQ服务所有通信都在channel通道中完成
channel = connection.createChannel();
//声明队列,如果队列在MQ中不存在则创建
channel.queueDeclare(QUEUE_EMAIL, true, false, false, null);
//声明交换机
channel.exchangeDeclare(EXCHANGE_ROUTING, BuiltinExchangeType.HEADERS);
//绑定交换机和队列
Map<String, Object> mailHeader = new HashMap<>();
mailHeader.put(EMAIL_ROUTING_KEY, "email");
channel.queueBind(QUEUE_EMAIL, EXCHANGE_ROUTING, "", mailHeader);
//实现消费方法
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println("receive message: " + message);
}
};
//监听队列
channel.basicConsume(QUEUE_EMAIL, true, defaultConsumer);
}
}
header模式sms消费者代码:
public class HeaderConsumerSms {
private static final String QUEUE_SMS = "queue_sms";
private static final String EXCHANGE_ROUTING = "exchange_topic";
private static final String SMS_ROUTING_KEY = "sms_key";
public static void main(String[] args) throws IOException, TimeoutException {
//通过连接工厂创建新的连接和MQ建立连接
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
//设置虚拟机,一个MQ可以设置多个虚拟机,每个虚拟机相当于一个独立的MQ
connectionFactory.setVirtualHost("/");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = null;
Channel channel = null;
//建立新的连接
connection = connectionFactory.newConnection();
//创建会话通道,生产者和MQ服务所有通信都在channel通道中完成
channel = connection.createChannel();
//声明队列,如果队列在MQ中不存在则创建
channel.queueDeclare(QUEUE_SMS, true, false, false, null);
//声明交换机
channel.exchangeDeclare(EXCHANGE_ROUTING, BuiltinExchangeType.HEADERS);
//绑定交换机和队列
Map<String, Object> smsHeader = new HashMap<>();
smsHeader.put(SMS_ROUTING_KEY, "sms");
channel.queueBind(QUEUE_SMS, EXCHANGE_ROUTING, "", smsHeader);
channel.queueBind(QUEUE_SMS, EXCHANGE_ROUTING, SMS_ROUTING_KEY);
//实现消费方法
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println("receive message: " + message);
}
};
//监听队列
channel.basicConsume(QUEUE_SMS, true, defaultConsumer);
}
}