RabbitMQ 使用AMQP模型
生产者与交换机关联
消费者与队列关联,队列通过路由键与交换机绑定
<dependency>
<groupId>com.rabbitmqgroupId>
<artifactId>amqp-clientartifactId>
<version>5.9.0version>
dependency>
在此Demo 中的生产者主要完成以下动作,其中声明队列的动作放在消费者中执行;
package com.example.rabbitmq.native_.direct.producer;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @Author: lancx
* @Date: 2020/4/22
*/
public class DirectProducer {
public final static String EXCHANGE_NAME = "direct_logs";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("152.136.45.55");
connectionFactory.setPort(5672);
connectionFactory.setUsername("root");
connectionFactory.setPassword("123456");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
// 设置信道中的交换器, 交换器名称和类型
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
// 申明队列(此处放在消费者中实现)
// 申明路由鍵
String[] routeKeys = {"ClassA", "ClassB", "ClassC"};
for (int i = 0; i < routeKeys.length; i++) {
String routeKey = routeKeys[i % 3];
String msg = "hello RabbitMq" + i;
// 發送消息
channel.basicPublish(EXCHANGE_NAME, routeKey, null, msg.getBytes());
System.out.println("sent : " + routeKey + ":" + msg);
}
channel.close();
connection.close();
}
}
package com.example.rabbitmq.native_.direct.producer;
import com.example.rabbitmq.native_.fanout.FanoutProducer;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @Author: lancx
* @Date: 2020/4/23 0023
* 普通消费者 订阅模式
*/
public class Consumer2 {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("152.136.45.55");
connectionFactory.setPort(5672);
connectionFactory.setUsername("root");
connectionFactory.setPassword("123456");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
// 设置信道中的交换器, 交换器名称和类型
channel.exchangeDeclare(DirectProducer.EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
// 申明队列
String queueName = "queue-ClassA";
channel.queueDeclare(queueName, false, false, false ,null);
// 绑定, 将队列(queue-ClassA)与交换器通过路由键绑定
String routeKey = "ClassA";
channel.queueBind(queueName, DirectProducer.EXCHANGE_NAME, routeKey);
System.out.println("waiting for message .... ");
//申明一个消费者
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
// super.handleDelivery(consumerTag, envelope, properties, body);
String msg = new String(body, "UTF-8");
// 消费者业务
System.out.println("Recevied["+envelope.getRoutingKey()+ "]");
}
};
// 消费者在指定队列消费(queue-ClassA)
channel.basicConsume(queueName, true, consumer);
}
}
每个路由键对应的消息都能收到
package com.example.rabbitmq.native_.direct.producer;
import com.example.rabbitmq.native_.fanout.FanoutProducer;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @Author: lancx
* @Date: 2020/4/23 0023
* 普通消费者 订阅模式
*/
public class Consumer1 {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("152.136.45.55");
connectionFactory.setPort(5672);
connectionFactory.setUsername("root");
connectionFactory.setPassword("123456");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
// 设置信道中的交换器, 交换器名称和类型
channel.exchangeDeclare(DirectProducer.EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
// 申明队列
String queueName = "queue-all";
channel.queueDeclare(queueName, false, false, false ,null);
// 绑定, 将队列与交换器通过路由键绑定
String[] routeKeys = {"key", "ClassA", "ClassB"};
for (String routeKey : routeKeys) {
channel.queueBind(queueName, DirectProducer.EXCHANGE_NAME, routeKey);
}
System.out.println(queueName + "waiting for message .... ");
//申明一个消费者
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
// super.handleDelivery(consumerTag, envelope, properties, body);
String msg = new String(body, "UTF-8");
// 消费者业务
System.out.println("Recevied["+envelope.getRoutingKey()+ "]");
}
};
//消费者在指定队列消费
channel.basicConsume(queueName, true, consumer);
}
}
每个信道都会收到消息
package com.example.rabbitmq.native_.direct.consumer;
import com.example.rabbitmq.native_.direct.producer.DirectProducer;
import com.rabbitmq.client.*;
import lombok.SneakyThrows;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @Author: lancx
* @Date: 2020/4/23
* 一个连接多个信道 订阅模式,每个信道都会收到消息
*/
public class MultiChannelConsumer {
private static class ConsumerWorker implements Runnable{
final Connection connection;
private ConsumerWorker(Connection connection) {
this.connection = connection;
}
@SneakyThrows
@Override
public void run() {
Channel channel = connection.createChannel();
// 设置信道中的交换器, 交换器名称和类型
channel.exchangeDeclare(DirectProducer.EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
// 申明队列 随机队列
String queueName = channel.queueDeclare().getQueue();
// 队列绑定到交换器上市,允许绑定多个路由键,也就是多重绑定
String[] routeKeys = {"key", "ClassA", "ClassB"};
for (String routeKey : routeKeys) {
channel.queueBind(queueName, DirectProducer.EXCHANGE_NAME, routeKey);
}
//创建队列消费者
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
// super.handleDelivery(consumerTag, envelope, properties, body);
String msg = new String(body, "UTF-8");
// 消费者业务
System.out.println("Recevied["+envelope.getRoutingKey()+ "]");
}
};
//消费者在指定队列消费(queue-king)
channel.basicConsume(queueName, true, consumer);
}
}
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("152.136.45.55");
connectionFactory.setPort(5672);
connectionFactory.setUsername("root");
connectionFactory.setPassword("123456");
// 单个连接
Connection connection = connectionFactory.newConnection();
// 两个信道
for (int i = 0; i < 2; i++) {
Thread work = new Thread(new ConsumerWorker(connection));
work.start();
}
}
}