RabbitMQ基本介绍
RabbitMQ基本介绍
RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件),RabbitMQ服务器是用Erlang语言编写的。
RabitMQ官方网站:
1.点对点(简单)的队列
2.工作(公平性)队列模式
3.发布订阅模式
4.路由模式Routing
5.通配符模式Topics
6.RPC
https://www.rabbitmq.com/getstarted.html
RabbitMQ常见名词
/Virtual Hosts---分类
/队列 存放我们消息
Exchange 分派我们消息在那个队列存放起来 类似于nginx
15672---rabbitmq控制台管理平台 http协议
25672rabbitmq 集群通信端口号
Amqp 5672 rabbitmq内部通信的一个端口号
快速入门RabbitMQ简单队列
首先需要再RabbitMQ平台创建Virtual Hosts 和队列。
/meiteVirtualHosts
----订单队列
----支付队列
- 在RabbitMQ平台创建一个队列;
- 在编写生产者代码
- 在编写消费者代码
Maven依赖
<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client --> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.9.0</version> </dependency>
创建连接
package com.dongl.rabbitmq.report.dl01; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import java.io.IOException; import java.util.concurrent.TimeoutException; /** * @author dongliang7 * @projectName rabbitmq-parent * @ClassName RabbitMQConnection.java * @description: 快速入门RabbitMQ简单队列 创建连接 * @createTime 2022年01月18日 14:43:00 */ public class RabbitMQConnection { public static Connection getConnection() throws IOException, TimeoutException { // 1.创建连接 ConnectionFactory connectionFactory = new ConnectionFactory(); // 2.设置连接地址 connectionFactory.setHost("127.0.0.1"); // 3.设置端口号: connectionFactory.setPort(5672); // 4.设置账号和密码 connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); // 5.设置VirtualHost connectionFactory.setVirtualHost("/dongliang07"); return connectionFactory.newConnection(); } }
生产者
package com.dongl.rabbitmq.report.dl01; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import java.io.IOException; import java.util.concurrent.TimeoutException; /** * @author dongliang7 * @projectName rabbitmq-parent * @ClassName Producer.java * @description: 生产者 * @createTime 2022年01月18日 14:45:00 */ public class Producer { private static final String QUEUE_NAME = "dltest"; public static void main(String[] args) throws IOException, TimeoutException { // 1.创建连接 Connection connection = RabbitMQConnection.getConnection(); // 2.设置通道 Channel channel = connection.createChannel(); // 3.设置消息 String msg = "董亮消息体"; System.out.println("msg:" + msg); channel.basicPublish("", QUEUE_NAME, null, msg.getBytes()); channel.close(); connection.close(); } }
消费者
package com.dongl.rabbitmq.report.dl01; import com.rabbitmq.client.*; import java.io.IOException; import java.util.concurrent.TimeoutException; /** * @author dongliang7 * @projectName rabbitmq-parent * @ClassName Consumer.java * @description: 消费者 * @createTime 2022年01月18日 15:05:00 */ public class Consumer { private static final String QUEUE_NAME = "dltest"; public static void main(String[] args) throws IOException, TimeoutException { // 1.创建连接 Connection connection = RabbitMQConnection.getConnection(); // 2.设置通道 Channel channel = connection.createChannel(); DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String msg = new String(body, "UTF-8"); System.out.println("消费者获取消息:" + msg); } }; // 3.监听队列 channel.basicConsume(QUEUE_NAME, true, defaultConsumer); } }
RabbitMQ五种消息模式
RabitMQ工作队列
默认的传统队列是为均摊消费,存在不公平性;如果每个消费者速度不一样的情况下,均摊消费是不公平的,应该是能者多劳。
采用工作队列
在通道中只需要设置basicQos为1即可,表示MQ服务器每次只会给消费者推送1条消息必须手动ack确认之后才会继续发送。
channel.basicQos(1);
RabbitMQ交换机类型
Direct exchange(直连交换机)
Fanout exchange(扇型交换机)
Topic exchange(主题交换机)
Headers exchange(头交换机)
/Virtual Hosts---区分不同的团队
----队列 存放消息
----交换机 路由消息存放在那个队列中 类似于nginx
---路由key 分发规则
RabbitMQ Fanout 发布订阅
生产者发送一条消息,经过交换机转发到多个不同的队列,多个不同的队列就多个不同的消费者。
原理:
- 需要创建两个队列 ,每个队列对应一个消费者;
- 队列需要绑定我们交换机
- 生产者投递消息到交换机中,交换机在将消息分配给两个队列中都存放起来;
- 消费者从队列中获取这个消息。
生产者代码:
package com.dongl.rabbitmq.report.dl02; import com.dongl.rabbitmq.report.RabbitMQConnection; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import java.io.IOException; import java.util.concurrent.TimeoutException; /** * @author dongliang7 * @projectName rabbitmq-parent * @ClassName ProducerFanout.java * @description: Fanout 发布订阅 生产者 * @createTime 2022年01月18日 18:24:00 */ public class ProducerFanout { /** * 定义交换机的名称 */ private static final String EXCHANGE_NAME = "dongl_fanout_exchange"; public static void main(String[] args) throws IOException, TimeoutException { // 创建Connection Connection connection = RabbitMQConnection.getConnection(); // 创建Channel Channel channel = connection.createChannel(); // 通道关联交换机 channel.exchangeDeclare(EXCHANGE_NAME, "fanout", true); String msg = "Fanout 消息~~~~~~~~~~~~~~"; channel.basicPublish(EXCHANGE_NAME, "", null, msg.getBytes()); channel.close(); connection.close(); } }
短信消费者:
package com.dongl.rabbitmq.report.dl02; import com.dongl.rabbitmq.report.RabbitMQConnection; import com.rabbitmq.client.*; import java.io.IOException; import java.util.concurrent.TimeoutException; /** * @author dongliang7 * @projectName rabbitmq-parent * @ClassName SmsConsumer.java * @description: 短信消费者 * @createTime 2022年01月18日 18:41:00 */ public class SmsConsumer { /** * 定义邮件队列 */ private static final String QUEUE_NAME = "fanout_sms_queue"; /** * 定义交换机的名称 */ private static final String EXCHANGE_NAME = "dongl_fanout_exchange"; public static void main(String[] args) throws IOException, TimeoutException { System.out.println("短信消费者..."); // 创建我们的连接 Connection connection = RabbitMQConnection.getConnection(); // 创建我们通道 final Channel channel = connection.createChannel(); // 关联队列消费者关联队列 channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ""); DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String msg = new String(body, "UTF-8"); System.out.println("短信消费者获取消息:" + msg); } }; // 开始监听消息 自动签收 channel.basicConsume(QUEUE_NAME, true, defaultConsumer); } }