RabbitMQ简单梳理

RabbitMQ

安装

这里使用docker安装,简单方便。

docker pull rabbitmq:3.8.10-management注意我们要下载management版本的,其他版本是没有web端管理界面的;

我们运行一个容器:docker run -d --name myrabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.8.10-management

其中15672是我们管理web端的端口。

介绍

浏览器输入ip:15672即可出现rabbitmq的web端管理界面。

默认的管理员用户密码都是guest,我们也可以新建用户,为其分配Virtual Host。

交换机exchange一般都是一个项目用一个。

我们看Rabbitmq官网列出了其中模型,其中消息队列主要涉及前5种。

HelloWorld

这是最简单的一种模型,生产者把消息放到队列里面,然后消费者从队列里面拿出来。
在这里插入图片描述

Work模型

这个其实就是有好多的消费者,消费者们从同一个里面队列里面拿消息。如果有多条消息,默认是采用轮询的,即消费者们一个一个拿消息。
在这里插入图片描述

fanout模型

生产者把消息放到交换机里,然后每一个消费者分配一个队列,交换机把消息发到每一个队列中。这是一种广播模型,我们需要制定交换机的类型为fanout在这里插入图片描述

Routing模型

在fanout的基础上,根据routeKey使得某一部分队列拿到消息,某一部分拿不到。在这里插入图片描述

Topic模型

在route的基础上,加入了通配符配置key,key表示为a.b.c这种按点分割单词的形式,*可匹配任意一个单词,#可匹配任意个单词。在这里插入图片描述

SpringBoot中使用RabbitMQ

准备

这里就简单测试一下五种模型。

首先我们新建一个用户ems,并给他添加一个虚拟主机/ems

新建一个springboot项目,添加Spring for RabbitMQ模块。

或者你在pom中添加坐标:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit-test</artifactId>
    <scope>test</scope>
</dependency>

配置

在yml中简单配一下:

spring:
  application:
    name: springboot-rabbitmq
  rabbitmq:
    host: 不给看
    port: 5672
    username: ems
    password: 123
    virtual-host: /ems

生产者

我们这里写一个测试类,看下5中模型的生产者是怎么写的:

package com.ljj;


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest(classes = SpringbootRabbitmqApplication.class)
@RunWith(SpringRunner.class)
public class TestRabbitmq {
	
	@Autowired
	private RabbitTemplate rabbitTemplate;
	
	/**
	 * hello world模型
	 */
	@Test
	public void testHelloWorld() {
		rabbitTemplate.convertAndSend("hello","Hello RabbitMQ");
	}
	
	/**
	 * work模型
	 */
	@Test
	public void testWork() {
		for (int i = 0; i < 10; i++) {
			rabbitTemplate.convertAndSend("work","work模型");
		}
	}
	
	/**
	 * fanout模型  广播
	 */
	@Test
	public void testFanout() {
		rabbitTemplate.convertAndSend("logs","","fanout模型");
	}
	
	/**
	 * route模型
	 */
	@Test
	public void testRoute() {
		rabbitTemplate.convertAndSend("directs","info","route模型");
	}
	
	/**
	 * topic模型
	 */
	@Test
	public void testTopic() {
		rabbitTemplate.convertAndSend("topics","a.b.c","topic模型");
	}

}

我们需要注入RabbitTemplate,然后使用它的convertAndSend方法。

可以看到无论是哪一种模型,都是采用这个方法发消息的。

前两种模型因为不涉及交换机,所以只用两个参数:第一个参数是routeKey,用于找到队列,第二个参数是消息内容。

而后三种模型需要交换机,所以第一个参数是交换机的名称(如果没有会新建),第二个参数是routeKey,fanout模型是广播,全部发送,所以routeKey填空串即可。

消费者

helloworld
package com.ljj.mq.consumers;

import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
//默认是持久化,非独占,非自动删除
@RabbitListener(queuesToDeclare = @Queue(value = "hello",durable = "true",autoDelete = "false"))
public class HelloCustomer {

	@RabbitHandler
	public void dealMessage(String message) {
		System.out.println("message:" + message);
	}
}

使用@RabbitListener注解和@RabbitHandler注解配合使用完成消费。

work
package com.ljj.mq.consumers;

import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class WorkCustomer {

	//消费者1
	@RabbitListener(queuesToDeclare = @Queue("work"))
	public void dealMessage1(String message) {
		System.out.println("message1:"+message);
	}
	
	//消费者2
	@RabbitListener(queuesToDeclare = @Queue("work"))
	public void dealMessage2(String message) {
		System.out.println("message2:"+message);
	}
}

没错@RabbitLister注解可以直接作用在方法上,queuesToDeclare表示如果没有这个队列就新建。

这里@Queue中指定的队列名即为routeKey。

fanout
package com.ljj.mq.consumers;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class FanoutCustomer {

	@RabbitListener(bindings = {
			@QueueBinding(
					value = @Queue, //不指定Queue的value表示创建临时队列
					exchange = @Exchange(value = "logs",type = "fanout")//指定交换机名称和类型
			)
	})
	public void dealMessage1(String message)  {
		System.out.println("message1:"+message);
	}
	
	@RabbitListener(bindings = {
			@QueueBinding(
					value = @Queue, 
					exchange = @Exchange(value = "logs",type = "fanout")
			)
	})
	public void dealMessage2(String message)  {
		System.out.println("message2:"+message);
	}
}

这个麻烦一点,其实也就是多配置了交换机的名称和类型。

routing
package com.ljj.mq.consumers;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class RouteCustomer {

	@RabbitListener(bindings = {
			@QueueBinding(
					value = @Queue,
					exchange = @Exchange("directs"), //type默认即为direct
					key = {"info","error"}
			)
	})
	public void dealMessage1(String message) {
		System.out.println("message1:"+message);
	}
	
	@RabbitListener(bindings = {
			@QueueBinding(
					value = @Queue,
					exchange = @Exchange("directs"), //type默认即为direct
					key = {"error"}
			)
	})
	public void dealMessage2(String message) {
		System.out.println("message2:"+message);
	}
}

同fanout,多配一个key,使得消息只发送到一部分queue中。

topic
package com.ljj.mq.consumers;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class TopicCustomer {
	@RabbitListener(bindings = {
			@QueueBinding(
					value = @Queue,
					exchange = @Exchange(value = "topics",type = "topic"), 
					key = {"a.*.c"}
			)
	})
	public void dealMessage1(String message) {
		System.out.println("message1:"+message);
	}
	
	@RabbitListener(bindings = {
			@QueueBinding(
					value = @Queue,
					exchange = @Exchange(value = "topics",type = "topic"),
					key = {"#.c"}
			)
	})
	public void dealMessage2(String message) {
		System.out.println("message2:"+message);
	}
}

配置key时可以加入通配符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值