[RabbitMQ]基础用法
1.安装和部署
在Linux下输入以下指令进行部署
-
首先拉取镜像
docker pull rabbitmq:[填入所需的版本号]
-
运行部署镜像
docker run \ -e RABBITMQ_DEFAULT_USER=[填入管理员账号] \ -e RABBITMQ_DEFAULT_PASS=[填入管理员密码] \ --name mq \ --hostname mq1 \ -p 15672:15672 \ -p 5672:5672 \ -d \ rabbitmq:3-management
注:
- 其中RABBITMQ_DEFAULT_USER和RABBITMQ_DEFAULT_PASS是设置初始管理员的账号和密码
- 15672为rabbitmq的网页管理页的端口,5672为rabbitmq的业务连接端口;此处都将其映射到虚拟机对应的15672和5672端口,且记住放行虚拟机防火墙端口
2.管理页面创建队列
-
进入登陆页输入刚刚设置的账号密码,进入首页
-
在上方导航栏选择Queues,进入队列管理页
-
点击Add a new queue,为队列起一个名字后,添加新的队列
-
待新建的队列是如下状态后,即为创建成功
3.Spring连接消息队列
-
在消费者和生产者的pom.xml文件中,添加如下依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
-
在Spring的application.yml配置文件中,填入以下的信息
spring: rabbitmq: host: [部署了rabbitmq的主机的IP地址] port: 5672 virtual-host: / [管理员的入口] username: [管理员的账号] password: [管理员的密码]
4.使用消息队列
1.simple queue
-
描述:一个生产者生产,一个消费者消费
-
代码实现:
-
在消费者中添加一个监听组件,然后启动消费者
@Slf4j @Component public class SpringRabbitMqListener { //@RabbitListener指定监听的队列名 @RabbitListener(queues = "hello.queue") public void listenerRabbit(String msg) { System.out.println(msg); } }
-
在生产者中注入RabbitTemplate的对象,再通过这个对象的方法进行发送消息
@RunWith(SpringRunner.class) @SpringBootTest public class PublisherTest { @Autowired private RabbitTemplate rabbitTemplate; @Test public void testSimpleQueue() throws InterruptedException { String queueName = "hello.queue"; String msg = "hello mq"; rabbitTemplate.convertAndSend(queueName, msg); } }
-
生产者发送消息后,消费者的控制台
-
2.Work queue
-
描述:一个生产者生产,多个消费者共同消费(竞争关系)
-
代码实现:
-
消费者代码,两个消费者绑定同一个队列,生产者代码基本不变,启动消费者
@Slf4j @Component public class SpringRabbitMqListener { @RabbitListener(queues = "hello.queue") public void listenerWork1Rabbit(String msg) throws InterruptedException { log.info("消息处理机1 " + msg + " " + LocalTime.now()); } @RabbitListener(queues = "hello.queue") public void listenerWork2Rabbit(String msg) throws InterruptedException { log.error("消息处理机2 " + msg + " " + LocalTime.now()); } }
-
使用生产者连续发送10个消息,消费者的情况
-
3.Publish/Subscribe
-
描述:多个队列与一个交换机绑定,消息发送到RabbitMQ时先经过交换机进行分发,给每一个绑定了该交换机的队列发送消息
-
代码实现:
-
创建两个订阅者,并用注解的形式指定要绑定的队列和交换机(若RabbitMQ中无,则会进行创建),启动订阅者
@Slf4j @Component public class SpringRabbitMqListener { @RabbitListener(bindings = @QueueBinding( value = @Queue("ps1.queue"), exchange = @Exchange("ps.fanout") )) public void listenerPublishSubscribe1Rabbit(String msg) { System.out.println("订阅者1" + " " + msg); } @RabbitListener(bindings = @QueueBinding( value = @Queue("ps2.queue"), exchange = @Exchange("ps.fanout") )) public void listenerPublishSubscribe2Rabbit(String msg) { System.out.println("订阅者2" + " " + msg); } }
-
发布者发布消息
@RunWith(SpringRunner.class) @SpringBootTest public class PublisherTest { @Autowired private RabbitTemplate rabbitTemplate; @Test public void PublishSubscribeQueue() { String exchangeName = "ps.fanout"; String msg = "hello everyone"; rabbitTemplate.convertAndSend(exchangeName, "", msg); } }
-
订阅者接收到消息
-
4.Routing queue
-
描述:多个队列绑定同一个交换机,通过路由关键字进行路由
-
代码实现:
-
接收者创建队列,创建交换机,并添加路由到交换机
@Slf4j @Component public class SpringRabbitMqListener { @RabbitListener(bindings = @QueueBinding( value = @Queue("route1.queue"), exchange = @Exchange("route.exchange"), key = {"orange", "blue"} )) public void listenerRouting1Rabbit(String msg) { System.out.println("路由orange or blue" + " " + "消息:" + msg); } @RabbitListener(bindings = @QueueBinding( value = @Queue("route2.queue"), exchange = @Exchange("route.exchange"), key = {"red", "blue"} )) public void listenerRouting2Rabbit(String msg) { System.out.println("路由red or blue" + " " + "消息:" + msg); } }
-
分别给orange,red,blue发消息
@RunWith(SpringRunner.class) @SpringBootTest public class PublisherTest { @Autowired private RabbitTemplate rabbitTemplate; @Test public void RoutingOrangeQueue() { String exchangeName = "route.exchange"; String msg = "hello orange"; rabbitTemplate.convertAndSend(exchangeName, "orange", msg); } @Test public void RoutingRedQueue() { String exchangeName = "route.exchange"; String msg = "hello red"; rabbitTemplate.convertAndSend(exchangeName, "red", msg); } @Test public void RoutingBlueQueue() { String exchangeName = "route.exchange"; String msg = "hello Blue"; rabbitTemplate.convertAndSend(exchangeName, "blue", msg); } }
-
5.Topic queue
-
描述:多个队列绑定一个交换机,与Routing Queue不同,其路由有特征匹配符,且要以点号(.)分割;特征匹配符的类型有两种,一种为(*)匹配一个任意字符,一种为(#)匹配零个或多个字符
-
代码实现:
-
创建两个接收者,一个交换机,并绑定交换机
@Slf4j @Component public class SpringRabbitMqListener { @RabbitListener(bindings = @QueueBinding( value = @Queue("topic1.queue"), exchange = @Exchange(name = "topic.exchange", type = ExchangeTypes.TOPIC), key = "#.weather" )) public void listenerTopic1Rabbit(String msg) { System.out.println("所有的weather话题" + " " + "消息:" + msg); } @RabbitListener(bindings = @QueueBinding( value = @Queue("topic2.queue"), exchange = @Exchange(name = "topic.exchange", type = ExchangeTypes.TOPIC), key = "china.#" )) public void listenerTopic2Rabbit(String msg) { System.out.println("中国所有的话题" + " " + "消息:" + msg); } @RabbitListener(bindings = @QueueBinding( value = @Queue("topic3.queue"), exchange = @Exchange(name = "topic.exchange", type = ExchangeTypes.TOPIC), key = "#.news" )) public void listenerTopic3Rabbit(String msg) { System.out.println("所有的news话题" + " " + "消息:" + msg); } }
-
发送消息
@RunWith(SpringRunner.class) @SpringBootTest public class PublisherTest { @Autowired private RabbitTemplate rabbitTemplate; @Test public void topicChinaNewsQueue() { String exchange = "topic.exchange"; String msg = "政协会议开幕 人大会议举行新闻发布会"; rabbitTemplate.convertAndSend(exchange, "china.news", msg); } @Test public void topicChinaWeatherQueue() { String exchange = "topic.exchange"; String msg = "北京天气良好,上海天气良好,深圳天气良好"; rabbitTemplate.convertAndSend(exchange, "china.weather", msg); } }
-
码字不易,如果觉得有用,点赞👍支持一下呗