一:RabbitMq 安装;
docker 环境安装rabbitMq
docker pull rabbitmq
docker images
docker run -itd -p 15672:15672 -p 5672:5672 rabbitmq
-- 或者修改一些配置
docker run -id \
--hostname my-rabbitmq \
--name my-rabbitmq \
--restart always \
-v /home/rabbitmq/data:/var/lib/rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
-e RABBITMQ_DEFAULT_VHOST=my_vhost \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
rabbitmq:latest
-- 查看 docker 进程
docker ps
-- 进入docker容器
docker exec -it [docker进程ID] /bin/bash
-- 修改docker 配置
rabbitmq-plugins enable rabbitmq_management
启动完成后,访问 15672端口,出现登录页面,安装成功
二:RabbitMq的基础命令和启动
rabbitmq-service install 安装服务
rabbitmq-service start 开始服务
Rabbitmq-service stop 停止服务
Rabbitmq-service enable 使服务有效
Rabbitmq-service disable 使服务无效
rabbitmq-service help 帮助
Rabbitmq管理插件启动
rabbitmq-plugins enable rabbitmq_management 启动
rabbitmq-plugins disable rabbitmq_management 关闭
rabbitMq 停止
rabbitmqctl stop
三、RabbitMq
1、 overview(概述)
记录一些本地rabbit的磁盘信息和内存占用,而后是一个监听端口,意思是协议的端口.
这里我们需要记下amqp协议的端口5672.因为rabbitmq就是遵从amqp协议的erlang语言实现的消息列队框架技术.也就是我们需要在rabbitmq开发和实现时,必须要用此端口来进行连接.
2.、Connections (连接)
连接界面此时是空的,看似什么也没有,但是通过词意大概可以猜想到,这个界面记录应该是展示客户端或者某个服务连接到此rabbitmq的信息展示,那么通过什么连接呢?
IP?用户名?密码?还有端口,前3个都有了,那么后面的端口呢,是不是overview(概述)里面的监听协议端口.显然是的.
3、Channels
信道抽象理解一下,就是在创建连接的时候,我们还需要给一个信道,来承载信息的传输.好比一根电线,当它通电后,其实是其内的铜线来传输电力一样.
4. Exchanges (交换器)
交换器的理解就是在第三步创建信道后,信道上需要设置一个交换器.那么用交换器去做什么呢,往下看.
界面一个列表,Name列就是名称,Type是交换器类型,既然类型那么交换器肯定通过类型会做不同的逻辑处理.还有一个Features特性列,证明在我们实现代码的时候也需要如此定位类型.
D表示(durable(持久化的)),I表示(internal(内在的))
词面理解交换器可以是持久化的也可以定义为内部内在的,外部无法访问,只能通过交换器之间来访问
接下来点开某个交换器看下
5. Queues(列队)
下图是借用别人的图
列队用于存储消息.等待消息被接收.
在理论层面上来看,以上都是生产者需要做的工作.
问题:channel通道和queue队列的区别是什么?
答:
大家有没有做过这样一个实验。假设一个程序(或者一个线程),它有一个通道变量叫做channel,也有一个队列变量叫做queue。当这个线程调用queue.put(“我靠”)之后,再继续调用queue.take(),就可以把”我靠”又取了出来。但是如果这个线程调用channel.write(“我靠”),再调用一万遍channel.read(),你也不可能读到”我靠”了。
这么一说,大家有没有发现本质区别了?
队列对象就是一个存储,你扔东西进去,你自己也可以把它再拿出来。但是初始化通道变量的时候,你必须指定这个通道的另一端。你丢东西进去,就像丢到一个下水管道里面一样,你自己是拿不出来的。只有通道的另一端才可以拿到这个数据。
四、SpringBoot项目 使用rabbitMq
1:在RabbitMq 控制台,创建一个远程登录账号,并设置好权限;
2: pom里面添加相关依赖
org.springframework.boot
spring-boot-starter-amqp
3:修改配置文件
spring:
rabbitmq:
host: 192.168.0.5
port: 5672
username: guest
password: guest
virtual-host: /
4:rabbitMq 配置Bean
@Configuration
public class RabbitMqConfig {
//队列 起名:TestDirectQueue
@Bean
public Queue TestDirectQueue() {
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存 在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
// return new Queue("TestDirectQueue",true,true,false);
//一般设置一下队列的持久化就好,其余两个就是默认false
return new Queue("TestDirectQueue", true);
}
//Direct交换机 起名:TestDirectExchange
@Bean
DirectExchange TestDirectExchange() {
// return new DirectExchange("TestDirectExchange",true,true);
return new DirectExchange("TestDirectExchange", true, false);
}
//绑定 将队列和交换机绑定, 并设置用于匹配键:TestDirectRouting
@Bean
Binding bindingDirect() {
return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting");
}
@Bean
DirectExchange lonelyDirectExchange() {
return new DirectExchange("lonelyDirectExchange");
}
}
5:监听队列
@Component
public class DirectListener {
@RabbitListener(queues = {"TestDirectQueue"})
public void process(Map map) {
System.out.println("TestDirectQueue 消费者收到消息 : " + map.toString());
}
@RabbitListener(queues = {"TestDirectQueue"})
public void process2(Map map) {
System.out.println("TestDirectQueue2 消费者收到消息2 : " + map.toString());
}
}
6:插入测试消息
@RestController
@RequestMapping("/mq")
public class SendMsgController {
@Autowired
RabbitTemplate rabbitTemplate;
@GetMapping("/rabbitMq/sendMsg")
public String sendDirectMessage() {
String messageId = UUID.randomUUID().toString();
String messageData = "test message, hello!";
Map map=new HashMap<>();
map.put("messageId",messageId);
map.put("messageData",messageData);
map.put("createTime",new Date());
//将消息携带绑定键值:TestDirectRouting 发送到交换机TestDirectExchange
rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map);
return "ok";
}
}
运行一下看看效果:
简单操作完工