异步通信处理,一个项目调用另外一个项目,可将一些无需及时返回且耗时长的操作提取出来,使用异步消息通信,减少请求响应时间,提系统的吞吐量,解耦合;(erlang语言开发)
/**
* 简单模式发送消息
*/
public class Producer {
static final String QUEUE_NAME = "simple_queue";
public static void main(String[] args) throws IOException, TimeoutException {
//1- 创建连接工厂(设置RabbitMQ的连接参数);
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("localhost");
connectionFactory.setPort(8888);
connectionFactory.setVirtualHost("/zhupeiliang");
connectionFactory.setUsername("zhupeiliang");
connectionFactory.setPassword("zhupeiliang");
//2- 创建连接;
Connection connection = connectionFactory.newConnection();
//3- 创建频道;
Channel channel = connection.createChannel();
//4- 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
//5- 发送消息;
String message = "你好,rabbitMQ!!!";
/*
* 参数1:交换机名称,如果没有则指定空字符串(表示使用默认的交换机)
* 参数2:路由key,简单模式中可以使用队列名称
* 参数3:消息其它属性,没有指定null
* 参数4:消息内容
*/
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
//6- 关闭资源;
channel.close();
connection.close();
}
}
/**
* 简单模式,:消费者消费消息
*/
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException {
//1 - 创建连接工厂;
//2 - 创建连接;
Connection connection = ConnectionUtil.getConnection();
//3 - 创建频道;
Channel channel = connection.createChannel();
//4 - 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(Producer.QUEUE_NAME, true, false, false, null);
//5 - 创建消费者(接收消息并处理消息);
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//输出信息:__>/路由key/交换机/消息id/接收到的消息
System.out.println(envelope.getRoutingKey());
System.out.println(envelope.getExchange());
System.out.println(envelope.getDeliveryTag());
System.out.println(new String(body, "urf-8"));
}
};
//6 -监听队列
/*
参数1:队列名称
参数2:是否自动确认,设置为true,表示消息接收到自动向MQ回复接收到了,MQ则会将消息从队列中自动删除,反之需要手动删除
参数3:消费者
*/
channel.basicConsume(Producer.QUEUE_NAME, true, defaultConsumer);
}
}
/**
*work模式发送消息
*/
public class Producer {
static final String QUEUE_NAME = "work_queue";
public static void main(String[] args) throws IOException, TimeoutException {
//1- 创建连接工厂(设置RabbitMQ的连接参数);
//2- 创建连接;
Connection connection = ConnectionUtil.getConnection();
//3- 创建频道;
Channel channel = connection.createChannel();
//4- 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
/
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
for (int i = 1; i <= 30; i++) {
//5- 发送消息;
//定义消息体
String message = "你好,rabbitMQ!!!---work摩丝" + i;
/
* 参数1:交换机名称,如果没有则指定空字符串(表示使用默认的交换机)
* 参数2:路由key,简单模式中可以使用队列名称
* 参数3:消息其它属性,没有指定null
* 参数4:消息内容
*/
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(message);
}
//6- 关闭资源;
channel.close();
connection.close();
}
}
/**
* work模式,:消费者消费消息
*/
public class Consumer1 {
public static void main(String[] args) throws IOException, TimeoutException {
//1 - 创建连接工厂;
//2 - 创建连接;
Connection connection = ConnectionUtil.getConnection();
//3 - 创建频道;
Channel channel = connection.createChannel();
//4 - 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(Producer.QUEUE_NAME, true, false, false, null);
//设置每次可以预取多少个消息
channel.basicQos(1);
//5 - 创建消费者(接收消息并处理消息);
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//输出信息:__>/路由key/交换机/消息id/接收到的消息
try {
System.out.println("路由key:" + envelope.getRoutingKey());
System.out.println("交换机:" + envelope.getExchange());
System.out.println("消息id:" + envelope.getDeliveryTag());
System.out.println("消费者1接收到消息内容:" + new String(body, "UTF-8"));
Thread.sleep(1000);
//确认消息是否被消费,参数1:消息id,参数2:false表示只有当前这条消息被处理了
channel.basicAck(envelope.getDeliveryTag(), false);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//6 -监听队列
/*
参数1:队列名称
参数2:是否自动确认,设置为true,表示消息接收到自动向MQ回复接收到了,MQ则会将消息从队列中自动删除,反之需要手动删除
参数3:消费者
*/
channel.basicConsume(Producer.QUEUE_NAME, true, defaultConsumer);
}
}
/**
* 发布与订阅模式发送消息
*/
public class Producer {
//交换机名称_广播类型
static final String FANOUT_EXCHANGE = "fanout_exchange";
//队列名称
static final String FANOUT_QUEUE_1 = "fanout_queue_1";
static final String FANOUT_QUEUE_2 = "fanout_queue_2";
public static void main(String[] args) throws IOException, TimeoutException {
//1- 创建连接工厂(设置RabbitMQ的连接参数);
Connection connection = ConnectionUtil.getConnection();
//2- 创建频道;
Channel channel = connection.createChannel();
//3-声明交换机,参数1:交换机名称,参数2:交换机类型-广播类型(&&-->fanout,direct,topic)
channel.exchangeDeclare(FANOUT_EXCHANGE, BuiltinExchangeType.FANOUT);
//4- 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(FANOUT_QUEUE_1, true, false, false, null);
channel.queueDeclare(FANOUT_QUEUE_2, true, false, false, null);
//4.1- 队列绑定到交换机,参数1:队列名称;参数2:交换机名称;参数3:路由key,没有设置空
channel.queueBind(FANOUT_QUEUE_1, FANOUT_EXCHANGE, "");
channel.queueBind(FANOUT_QUEUE_2, FANOUT_EXCHANGE, "");
for (int i = 1; i <= 10; i++) {
//5- 发送消息;
String message = "你好,rabbitMQ!!!--发布与订阅摩丝------" + i;
/*
* 参数1:交换机名称,如果没有则指定空字符串(表示使用默认的交换机)
* 参数2:路由key,简单模式中可以使用队列名称
* 参数3:消息其它属性,没有指定null
* 参数4:消息内容
*/
channel.basicPublish(FANOUT_EXCHANGE, "", null, message.getBytes());
channel.basicPublish(FANOUT_EXCHANGE, "", null, message.getBytes());
System.out.println(message);
}
//6- 关闭资源;
channel.close();
connection.close();
}
}
/**
* 发布与订阅模式,:消费者消费消息
*/
public class Consumer1 {
public static void main(String[] args) throws IOException, TimeoutException {
//1 - 创建连接工厂;
//2 - 创建连接;
Connection connection = ConnectionUtil.getConnection();
//3 - 创建频道;
Channel channel = connection.createChannel();
//3.1 - 声明交换机
channel.exchangeDeclare(Producer.FANOUT_EXCHANGE, BuiltinExchangeType.FANOUT);
//4 - 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(Producer.FANOUT_QUEUE_1, true, false, false, null);
// channel.queueDeclare(Producer.FANOUT_QUEUE_2, true, false, false, null);
//4.1 - 队列绑定到交换机上;参数1:队列名称;参数2:交换机名称;参数3:路由key
channel.queueBind(Producer.FANOUT_QUEUE_1, Producer.FANOUT_EXCHANGE, "");
//5 - 创建消费者(接收消息并处理消息);
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//输出信息:__>/路由key/交换机/消息id/接收到的消息
System.out.println("路由key:" + envelope.getRoutingKey());
System.out.println("交换机:" + envelope.getExchange());
System.out.println("消息id:" + envelope.getDeliveryTag());
// System.out.println(new String(body));
System.out.println("消费者1---消费消息::" + new String(body, "UTF-8"));
// System.out.println("?");
}
};
//6 -监听队列
/*
参数1:队列名称
参数2:是否自动确认,设置为true,表示消息接收到自动向MQ回复接收到了,MQ则会将消息从队列中自动删除,反之需要手动删除
参数3:消费者
*/
channel.basicConsume(Producer.FANOUT_QUEUE_1, true, defaultConsumer);
}
}
/**
* RoutingKey路由模式发送消息
*/
public class Producer {
//交换机名称_路由类型
static final String DIRECT_EXCHANGE = "direct_exchange";
//队列名称
static final String DIRECT_QUEUE_INSERT = "direct_queue_insert";
static final String DIRECT_QUEUE_UPDATE = "direct_queue_update";
public static void main(String[] args) throws IOException, TimeoutException {
//1- 创建连接工厂(设置RabbitMQ的连接参数);
Connection connection = ConnectionUtil.getConnection();
//2- 创建频道;
Channel channel = connection.createChannel();
//3-声明交换机,参数1:交换机名称,参数2:交换机类型-路由类型(&&-->fanout,direct,topic)
channel.exchangeDeclare(DIRECT_EXCHANGE, BuiltinExchangeType.DIRECT);
//4- 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(DIRECT_QUEUE_INSERT, true, false, false, null);
channel.queueDeclare(DIRECT_QUEUE_UPDATE, true, false, false, null);
//4.1- 队列绑定到交换机,参数1:队列名称;参数2:交换机名称;参数3:路由key,没有设置空
channel.queueBind(DIRECT_QUEUE_INSERT, DIRECT_EXCHANGE, "insert");
channel.queueBind(DIRECT_QUEUE_UPDATE, DIRECT_EXCHANGE, "update");
//5- 发送消息;
String message = "你好,rabbitMQ!!!--路由摩丝----RoutingKey为-->insert";
/*
* 参数1:交换机名称,如果没有则指定空字符串(表示使用默认的交换机)
* 参数2:路由key,简单模式中可以使用队列名称
* 参数3:消息其它属性,没有指定null
* 参数4:消息内容
*/
channel.basicPublish(DIRECT_EXCHANGE, "insert", null, message.getBytes());
System.out.println(message);
//5- 发送消息;
message = "你好,rabbitMQ!!!--路由摩丝----RoutingKey为-->update";
/*
* 参数1:交换机名称,如果没有则指定空字符串(表示使用默认的交换机)
* 参数2:路由key,简单模式中可以使用队列名称
* 参数3:消息其它属性,没有指定null
* 参数4:消息内容
*/
channel.basicPublish(DIRECT_EXCHANGE, "update", null, message.getBytes());
System.out.println(message);
//6- 关闭资源;
channel.close();
connection.close();
}
}
/**
* RoutingKey路由模式,:消费者消费消息
*/
public class Consumer1 {
public static void main(String[] args) throws IOException, TimeoutException {
//1 - 创建连接工厂;
//2 - 创建连接;
Connection connection = ConnectionUtil.getConnection();
//3 - 创建频道;
Channel channel = connection.createChannel();
//3.1 - 声明交换机,模式为路由模式
channel.exchangeDeclare(Producer.DIRECT_EXCHANGE, BuiltinExchangeType.DIRECT);
//4 - 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(Producer.DIRECT_QUEUE_INSERT, true, false, false, null);
//4.1 - 队列绑定到交换机上;参数1:队列名称;参数2:交换机名称;参数3:路由key
channel.queueBind(Producer.DIRECT_QUEUE_INSERT, Producer.DIRECT_EXCHANGE, "insert");
//5 - 创建消费者(接收消息并处理消息);
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//输出信息:__>/路由key/交换机/消息id/接收到的消息
System.out.println("路由key:" + envelope.getRoutingKey());
System.out.println("交换机:" + envelope.getExchange());
System.out.println("消息id:" + envelope.getDeliveryTag());
System.out.println("消费者1---消费消息::" + new String(body, "UTF-8"));
}
};
//6 -监听队列
/*
参数1:队列名称
参数2:是否自动确认,设置为true,表示消息接收到自动向MQ回复接收到了,MQ则会将消息从队列中自动删除,反之需要手动删除
参数3:消费者
*/
channel.basicConsume(Producer.DIRECT_QUEUE_INSERT, true, defaultConsumer);
}
}
/**
* topic通配符模式,:消费者消费消息
*/
public class Consumer1 {
public static void main(String[] args) throws IOException, TimeoutException {
//1 - 创建连接工厂;
//2 - 创建连接;
Connection connection = ConnectionUtil.getConnection();
//3 - 创建频道;
Channel channel = connection.createChannel();
//3.1 - 声明交换机,模式为路由模式
channel.exchangeDeclare(Producer.TOPIC_EXCHANGE, BuiltinExchangeType.TOPIC);
//4 - 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(Producer.TOPIC_EXCHANGE, true, false, false, null);
//4.1 - 队列绑定到交换机上;参数1:队列名称;参数2:交换机名称;参数3:路由key
channel.queueBind(Producer.TOPIC_QUEUE_1,Producer.TOPIC_EXCHANGE, "zpl.update");
channel.queueBind(Producer.TOPIC_QUEUE_1,Producer.TOPIC_EXCHANGE, "zpl.delete");
//5 - 创建消费者(接收消息并处理消息);
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//输出信息:__>/路由key/交换机/消息id/接收到的消息
System.out.println("路由key:" + envelope.getRoutingKey());
System.out.println("交换机:" + envelope.getExchange());
System.out.println("消息id:" + envelope.getDeliveryTag());
System.out.println("消费者1---消费消息::" + new String(body, "UTF-8"));
}
};
//6 -监听队列
/*
参数1:队列名称
参数2:是否自动确认,设置为true,表示消息接收到自动向MQ回复接收到了,MQ则会将消息从队列中自动删除,反之需要手动删除
参数3:消费者
*/
channel.basicConsume(Producer.TOPIC_QUEUE_1, true, defaultConsumer);
}
}
/**
* topic通配符模式,:消费者消费消息
*/
public class Consumer1 {
public static void main(String[] args) throws IOException, TimeoutException {
//1 - 创建连接工厂;
//2 - 创建连接;
Connection connection = ConnectionUtil.getConnection();
//3 - 创建频道;
Channel channel = connection.createChannel();
//3.1 - 声明交换机,模式为路由模式
channel.exchangeDeclare(Producer.TOPIC_EXCHANGE, BuiltinExchangeType.TOPIC);
//4 - 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(Producer.TOPIC_EXCHANGE, true, false, false, null);
//4.1 - 队列绑定到交换机上;参数1:队列名称;参数2:交换机名称;参数3:路由key
channel.queueBind(Producer.TOPIC_QUEUE_1,Producer.TOPIC_EXCHANGE, "zpl.update");
channel.queueBind(Producer.TOPIC_QUEUE_1,Producer.TOPIC_EXCHANGE, "zpl.delete");
//5 - 创建消费者(接收消息并处理消息);
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//输出信息:__>/路由key/交换机/消息id/接收到的消息
System.out.println("路由key:" + envelope.getRoutingKey());
System.out.println("交换机:" + envelope.getExchange());
System.out.println("消息id:" + envelope.getDeliveryTag());
System.out.println("消费者1---消费消息::" + new String(body, "UTF-8"));
}
};
//6 -监听队列
/*
参数1:队列名称
参数2:是否自动确认,设置为true,表示消息接收到自动向MQ回复接收到了,MQ则会将消息从队列中自动删除,反之需要手动删除
参数3:消费者
*/
channel.basicConsume(Producer.TOPIC_QUEUE_1, true, defaultConsumer);
}
}
/**
* topic通配符模式,:消费者消费消息
*/
public class Consumer2 {
public static void main(String[] args) throws IOException, TimeoutException {
//1 - 创建连接工厂;
//2 - 创建连接;
Connection connection = ConnectionUtil.getConnection();
//3 - 创建频道;
Channel channel = connection.createChannel();
//3.1 - 声明交换机,模式为路由模式
channel.exchangeDeclare(Producer.TOPIC_EXCHANGE, BuiltinExchangeType.TOPIC);
//4 - 声明队列;
/*
*参数1:队列名称
*参数2:定义持久化到服务器上,
*参数3:是否独占本连接,
*参数4:是否在不使用的时候将队列自动删除,
*参数5:其他参数
*/
channel.queueDeclare(Producer.TOPIC_EXCHANGE, true, false, false, null);
//4.1 - 队列绑定到交换机上;参数1:队列名称;参数2:交换机名称;参数3:路由key
channel.queueBind(Producer.TOPIC_QUEUE_2, Producer.TOPIC_EXCHANGE, "zpl.*");
//5 - 创建消费者(接收消息并处理消息);
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//输出信息:__>/路由key/交换机/消息id/接收到的消息
System.out.println("路由key:" + envelope.getRoutingKey());
System.out.println("交换机:" + envelope.getExchange());
System.out.println("消息id:" + envelope.getDeliveryTag());
System.out.println("消费者1---消费消息::" + new String(body, "UTF-8"));
}
};
//6 -监听队列
/*
参数1:队列名称
参数2:是否自动确认,设置为true,表示消息接收到自动向MQ回复接收到了,MQ则会将消息从队列中自动删除,反之需要手动删除
参数3:消费者
*/
channel.basicConsume(Producer.TOPIC_QUEUE_2, true, defaultConsumer);
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-amqpartifactId>
<version>2.3.2.RELEASEversion>
dependency>
2.生产者配置spring.yml配置文件.rabbitMQ的连接参数
spring:
rabbitmq:
host: localhost
port: 5672
virtual-host: /zhupeiliang
username: zhupeiliang
password: zhupeiliang
3.创建消息生产者,topic通配符模式
@Configuration
public class RabbitMQConfig {
//交换机名称
public static final String ZPL_TOPIC_EXCHANGE = "zpl_topic_exchange";
//队列名称
public static final String ZPL_QUEUE = "zpl_queue";
//声明交换机
@Bean("zplTopicExchange")
public Exchange topicExchange() {
return ExchangeBuilder.topicExchange(ZPL_TOPIC_EXCHANGE).durable(true).build();
}
//声明队列
@Bean("zplQueue")
public Queue zplQueue() {
return QueueBuilder.durable(ZPL_QUEUE).build();
}
//将队列绑定到交换机
@Bean
public Binding bindingQueueExchange(@Qualifier("zplTopicExchange") Exchange exchange,
@Qualifier("zplQueue") Queue queue) {
return BindingBuilder.bind(queue).to(exchange).with("zpl.#").noargs();
}
}
4.创建消费者:topic通配符模式
4.1.配置spring.yml配置文件.RabbitMQ的连接参数通消息生产者一样
消费者开始撸码:↓>消费者监听的队列名称必须跟消息生产者发送消息的队列名称要匹配;
@Component
public class RabbitMQConsumer {
/**
* 接收队列消息
* @param message 消息内容
* @RabbitListener(queues = "zplQueue")参数可以监听多个队列 例如:
* @RabbitListener(queues = {"q1","q2"})
*/
@RabbitListener(queues = "zplQueue")
public void rabbitMQListener(String message) {
System.out.println("消费者接收到的消息为:" + message);
}
}
5.消息生产者工程中编写测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRabbitmqProducerApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void mqContextLoads() {
rabbitTemplate.convertAndSend(RabbitMQConfig.ZPL_TOPIC_EXCHANGES, "inserts", "路由key为:zpl.inserts");
rabbitTemplate.convertAndSend(RabbitMQConfig.ZPL_TOPIC_EXCHANGES, "deletes", "路由key为:zpl.deletes");
rabbitTemplate.convertAndSend(RabbitMQConfig.ZPL_TOPIC_EXCHANGES, "updates", "路由key为:zpl.updates");
rabbitTemplate.convertAndSend(RabbitMQConfig.ZPL_TOPIC_EXCHANGES, "selects", "路由key为:zpl.selects");
}
}
如有不对的地方,请各路大神指正 ~