RabbitMQ总结

RabbitMQ总结

什么是RabbitMQ:

RabbitMQ是一个使用 erlang 编写的 AMQP(高级消息队列协议)的服务实现,简单来说,就是一个功能强大的消息队列服务。RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue Protocol)的开源实现。

工作原理:

Publisher

消息的生产者,也是一个向交换器发布消息的客户端应用程序。

Consumer

消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。

Message

消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

Exchange

交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。

Exchange有4种类型:direct(默认),fanout, topic, 和headers,不同类型的Exchange转发消息的策略有所区别

Queue

消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。

Binding

绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。

Exchange 和Queue的绑定可以是多对多的关系。

Connection

网络连接,比如一个TCP连接。

Channel

信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。

Virtual Host

虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 / 。

Broker

表示消息队列服务器实体

怎么用RabbitMQ

1.安装Erlang

1)rpm -ivh esl-erlang-17.3-1.x86_64.rpm --force --nodeps

2)rpm -ivh esl-erlang_17.3-1centos6_amd64.rpm --force --nodeps

3)rpm -ivh esl-erlang-compat-R14B-1.el6.noarch.rpm --force --nodeps

2.安装 RabbitMQ

上传安装包

1.安装RabbitMQ

rpm -ivh rabbitmq-server-3.4.1-1.noarch.rpm

2.启动、停止

service rabbitmq-server start

service rabbitmq-server stop

service rabbitmq-server restart

service rabbitmq-server status

3.设置开机启动

chkconfig rabbitmq-server on

4.防火墙开放15672端口

/sbin/iptables -I INPUT -p tcp --dport 15672 -j ACCEPT

/etc/rc.d/init.d/iptables save

5.开启web界面管理工具

rabbitmq-plugins enable rabbitmq_management

service rabbitmq-server restart

6.创建账户

这里我们以创建个admin帐号,密码1111为例,创建一个账号并支持远程ip访问。

1.创建账号

rabbitmqctl  add_user admin 1111

2.设置用户角色

rabbitmqctl  set_user_tags admin  administrator

3.设置用户权限

rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"

4.设置完成后可以查看当前用户和角色(需要开启服务)

rabbitmqctl list_users	

账号guest具有所有的操作权限,并且又是默认账号,出于安全因素的考虑,guest用户只能通过localhost登陆

5.测试

​ 浏览器输入:serverip:15672。其中serverip是RabbitMQ-Server所在主机的ip,15672是RabbitMQ-Server的端口号

Spring AMQP

Spring有很多不同的项目,其中就有对AMQP的支持:

Spring-amqp是对AMQP协议的抽象实现,而spring-rabbit 是对协议的具体实现,也是目前的唯一实现。底层使用的就是RabbitMQ。

依赖和配置

添加AMQP的启动器:

org.springframework.boot spring-boot-starter-amqp

application.properties中添加RabbitMQ地址:

主机

spring.rabbitmq.host=192.168.233.132

端口

spring.rabbitmq.port=5672

用户名

spring.rabbitmq.username=admin

密码

spring.rabbitmq.password=1111

虚拟分组

spring.rabbitmq.virtual-host=/

监听者

在SpringAmqp中,对消息的消费者进行了封装和抽象,一个普通的JavaBean中的普通方法,只要通过简单的注解,就可以成为一个消费者。

@Component
public class Listener {

/**
 * 监听者接收消息三要素:
 *  1、queue
 *  2、exchange
 *  3、routing key
 */
@RabbitListener(bindings = @QueueBinding(
    value = @Queue(value="springboot_queue",durable = "true"),
    exchange = @Exchange(value="springboot_exchage",type= ExchangeTypes.TOPIC),
    key= {"*.*"}
))
public void listen(String msg){
    System.out.println("接收到消息:" + msg);
}

}

  • @Componet:类上的注解,注册到Spring容器
  • @RabbitListener:方法上的注解,声明这个方法是一个消费者方法,需要指定下面的属性:
    • bindings:指定绑定关系,可以有多个。值是@QueueBinding的数组。@QueueBinding包含下面属性:
      • value:这个消费者关联的队列。值是@Queue,代表一个队列
      • exchange:队列所绑定的交换机,值是@Exchange类型
      • key:队列和交换机绑定的RoutingKey

类似listen这样的方法在一个类中可以写多个,就代表多个消费者。

发送者

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class MqDemo {

@Autowired
private AmqpTemplate amqpTemplate;

@Test
public void testSend() throws InterruptedException {
    String msg = "hello, Spring boot amqp";
    this.amqpTemplate.convertAndSend("spring.test.exchange","a.b", msg);
    // 等待10秒后再结束
    Thread.sleep(10000);
}

}

手动ack

添加配置

1.application.properties

设置三种订阅模式手动ack

spring.rabbitmq.listener.direct.acknowledge-mode=manual

设置work消息类型手动ack

spring.rabbitmq.listener.simple.acknowledge-mode=manual

2.监听者

注意:监听方法添加Channel channel, Message message两个参数

package com.usian.springboot;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
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;

import java.io.IOException;

@Component
public class Recv {
/**
* 监听者接收消息三要素:
* 1、queue
* 2、exchange
* 3、routing key
/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value="springboot_queue",durable = "true"),
exchange = @Exchange(value="springboot_exchage",type= ExchangeTypes.TOPIC),
key= {"
.*"}
))
public void listen(String msg, Channel channel, Message message) throws IOException {
System.out.println("接收到消息:" + msg);
//int a = 6/0;
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
}
}

posted @ 2020-11-23 08:30  脑浆炸裂  阅读(115)  评论(0)    收藏  举报