rabbitmq安装和erlang环境的安装直接参考 官网;需要注意的是要查看一下两个的最低版本对应,避免出现版本问题,详细查看官网:
https://www.rabbitmq.com/which-erlang.html
我的版本:erlang:24.0,rabbitmq:3.8.17
springboot :2.2.4
rabbitmq 大致操作流程(simple)
- 创建连接工厂ConnectionFactory,输入host、port、username、password、虚拟访问节点VirtualHost(默认"/",发送到根目录/根节点下)
- 使用连接工厂创建连接Connection,连接可以取名和传参;
- 通过连接创建通道Channel
- 准备要发送的消息
- 准备交换机,创建一个交换机或者不指定交换机exchange;不指定交换机会使用默认的交换机;创建交换机:通过通道channel创建,即声明交换机,channel.exchangeDeclare(),声明交换机的话需要指定一下交换机的类型exchangeType,交换机类型四种:direct/topic/fanout/headers
- 准备队列queue,创建队列,即声明一个队列,和声明交换机基本一致,channel.queueDeclare()
- 队列指定routerKey,作用是为了指定消费者接受和消费消息;
- 绑定队列和交换机,channel.queueBind()
- 发布消息,channel.basicPublish()
- 关闭通道,关闭连接
四种模式
- direct 路由模式,由路由routerKey来指定哪些消费者来接收和消费消息
- topic 也是路由模式,只不过使用模糊的方式来指定路由routerKey,使用#和*,#表示有一级或者多级或者没有,表示必须有一级;例如#.com.,表示com前面可有一级或者多级或者没有,com后面必须有一级也可以是多级,这样的路由才符合接收消息的消费者条件
- fanout 发布订阅模式,只要订阅了,有消息,都可以进行接收消费;他没有路由key
- headers 参数匹配模式
使用springboot就可以简单的更多,看起来更加的简洁
springboot 集成rabbitmq
新建项目,导入rabbitmq依赖
配置配置信息,使用yml或者配置类,本地安装不需要配置,spring已经配置好了,如果在web页面(15672管理页面)修改过用户信息,需要把用户信息配置一下,默认guest;
需要建立两个项目,一个生产者和一个消费者
生产者
#rabbitmq配置 本机安装的话不需要配置,spring已经有过配置了
#不是本机安装需要配置一下
#spring:
# rabbitmq:
# username:
# password:
# host:
# virtual-host: /
# port: 5567
# listener:
# simple:
# # 手动应答
# acknowledge-mode: manual
这边配置了手动应答,不使用默认应答方式,如果程序抛异常,把消息进行其他的操作,防止消息丢失;生产者实际上是不需要的,消费者和生产者基本上一致,所以直接复制了;消费者配置更多的是使用了配置类,详细的会在消费者里面说。
配置成功之后,创建队列和转换机;创建的位置生产者和消费者哪一侧都可以,我放在了生产者中;生产者生产的消息到转换机中,由转换机投递到队列中,队列绑定转换机。
这次只用了fanout和direct两个模式
使用配置类创建交换机和队列(也可以说声明)
配置类
@Configuration
public class RabbitMQConfiguration {
//1.声明交换机 fanout交换机
//2.声明队列
//3.队列绑定交换机
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange("fanout_exchange",true,false);
}
@Bean
public Queue smsQueue(){
return new Queue("sms_queue",true,false,false);
}
/**
* 设置ttl队列,一定的时间消息过期,过期的消息可以转入死信队列
* @return
*/
@Bean
public Queue ttlQueue(){
//web界面可以看到队列的设置采用的是键值对的形式,所以用了map
Map<String,Object> map = new HashMap<>();
map.put("x-message-ttl",60000);//key是一定的,设置队列中消息的过期时间
map.put("x-dead-letter-exchange","dead_direct_exchange");//死信队列
map.put("x-dead-letter-routing-key","dead");//direct模式需要添加死信队列的routingKey,如果是fanout则不需要
return new Queue(