rabbitMq使用手册

293 阅读7分钟

添加一个账号****

在RabbitMQ添加一个新的用户

RabbitMQ服务器上

创建账号

rabbitmqctl add_user admin “密码”

设置用户角色

rabbitmqctl set_user_tags admin administrator

 

1、超级管理员(administrator)

可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。

2、监控者(monitoring)

可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)

3、策略制定者(policymaker)

可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。

4、普通管理者(management)

仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。

5、其他

无法登陆管理控制台,通常就是普通的生产者和消费者。

 

设置用户权限

rabbitmqctl ?set_permissions ?-p ?'/' ?user_name '.' '.' '.'

查询当前用户信息

rabbitmqctl list_users

 

设置成功后可用用户登录rabbitMQ页面

 

Spring-boot对RabbitMQ的引用****

RabbitMq依赖为

 

    org.springframework.boot

    spring-boot-starter-amqp

 

 

在配置文件中添加RabbitMq相关配置信息

#  rabbitmq:**

#    host: ${rabbitmq.ip}**

#    port: ${port}**

#    username: ${rabbitmqUser}**

#    password: ${rabbitmqPassword}**

#    listener:**

#      # 默认配置是 simple**

#      type: simple**

#      simple:**

#        # ack Acknowledge mode of container. auto none**

#        #acknowledge-mode: manual**

#        # Maximum number of unacknowledged messages that can be outstanding at each consumer.**

#        #prefetch: 3

配置详解****

spring.rabbitmq.host: 服务Host

spring.rabbitmq.port: 服务端口

spring.rabbitmq.username: 登陆用户名

spring.rabbitmq.password: 登陆密码

spring.rabbitmq.virtual-host: 连接到rabbitMQ的vhost

spring.rabbitmq.addresses: 指定client连接到的server的地址,多个以逗号分隔(优先取addresses,然后再取host)

spring.rabbitmq.requested-heartbeat: 指定心跳超时,单位秒,0为不指定;默认60s

spring.rabbitmq.publisher-confirms: 是否启用【发布确认】

spring.rabbitmq.publisher-returns: 是否启用【发布返回】

spring.rabbitmq.connection-timeout: 连接超时,单位毫秒,0表示无穷大,不超时

spring.rabbitmq.parsed-addresses:

 

ssl

spring.rabbitmq.ssl.enabled: 是否支持ssl

spring.rabbitmq.ssl.key-store: 指定持有SSL certificate的key store的路径

spring.rabbitmq.ssl.key-store-password: 指定访问key store的密码

spring.rabbitmq.ssl.trust-store: 指定持有SSL certificates的Trust store

spring.rabbitmq.ssl.trust-store-password: 指定访问trust store的密码

spring.rabbitmq.ssl.algorithm: ssl使用的算法,例如,TLSv1.1

 

cache

spring.rabbitmq.cache.channel.size: 缓存中保持的channel数量

spring.rabbitmq.cache.channel.checkout-timeout: 当缓存数量被设置时,从缓存中获取一个channel的超时时间,单位毫秒;如果为0,则总是创建一个新channel

spring.rabbitmq.cache.connection.size: 缓存的连接数,只有是CONNECTION模式时生效

spring.rabbitmq.cache.connection.mode: 连接工厂缓存模式:CHANNEL 和 CONNECTION

 

listener

spring.rabbitmq.listener.simple.auto-startup: 是否启动时自动启动容器

spring.rabbitmq.listener.simple.acknowledge-mode: 表示消息确认方式,其有三种配置方式,分别是none、manual和auto;默认auto

spring.rabbitmq.listener.simple.concurrency: 最小的消费者数量

spring.rabbitmq.listener.simple.max-concurrency: 最大的消费者数量

spring.rabbitmq.listener.simple.prefetch: 指定一个请求能处理多少个消息,如果有事务的话,必须大于等于transaction数量.

spring.rabbitmq.listener.simple.transaction-size: 指定一个事务处理的消息数量,最好是小于等于prefetch的数量.

spring.rabbitmq.listener.simple.default-requeue-rejected: 决定被拒绝的消息是否重新入队;默认是true(与参数acknowledge-mode有关系)

spring.rabbitmq.listener.simple.idle-event-interval: 多少长时间发布空闲容器时间,单位毫秒

 

spring.rabbitmq.listener.simple.retry.enabled: 监听重试是否可用

spring.rabbitmq.listener.simple.retry.max-attempts: 最大重试次数

spring.rabbitmq.listener.simple.retry.initial-interval: 第一次和第二次尝试发布或传递消息之间的间隔

spring.rabbitmq.listener.simple.retry.multiplier: 应用于上一重试间隔的乘数

spring.rabbitmq.listener.simple.retry.max-interval: 最大重试时间间隔

spring.rabbitmq.listener.simple.retry.stateless: 重试是有状态or无状态

 

template

spring.rabbitmq.template.mandatory: 启用强制信息;默认false

spring.rabbitmq.template.receive-timeout: receive() 操作的超时时间

spring.rabbitmq.template.reply-timeout: sendAndReceive() 操作的超时时间

spring.rabbitmq.template.retry.enabled: 发送重试是否可用

spring.rabbitmq.template.retry.max-attempts: 最大重试次数

spring.rabbitmq.template.retry.initial-interval: 第一次和第二次尝试发布或传递消息之间的间隔

spring.rabbitmq.template.retry.multiplier: 应用于上一重试间隔的乘数

spring.rabbitmq.template.retry.max-interval: 最大重试时间间隔

 

 

 

 

 

 

消息队列的使用****

 

1.简单队列****

P:生产者

P和C之间:队列

C:消费者

 

管理工具中创建队列:

 

 

message TTL:消息生存时间,超过设置时间自动删除

 

auto expire:队列生存时间,超过设置时间自动删除

 

overflow behaviour:队列溢出行为,可设置drop-head, reject-publish 或reject-publish-dlx,

 

drop-head会丢弃最老的消息,reject-publish或reject-publish-dlx会丢弃最新的消息

 

dead letter exchange:死信交换机,如果消息被拒绝或过期,将发布到改交换机绑定的队列

 

dead letter routing key:死信交换机路由,由该交换机根据路由键发给队列

 

max length:最大消息容量,超过会从头部丢弃

 

max length bytes:最大消息容量字节数,超过会从头部丢弃

 

maximum priority:最大优先级,消息的优先级参数越靠近最大优先级,越早被消费

 

lazy mode:惰性模式,在磁盘上保留尽可能多的消息,以减少RAM的使用,否则是一个内存缓存,尽可能快的传递消息

 

创建一个队列如图中所示:

 

 

后创建生产者

 

此处为传输一个序列化UserLogForm对象

 

创建一个消费者

 

 

触发该生产者方法数据会传输到RabbitMQ中发给消费者消费

 

 

 

 

 

 

 

2 . 工作队列****

代码跟上一个队列基本一样,不过工作队列有两个消费者:

 

工作队列是以公平方式,轮询发送消息到消费者。

 

5.3 发布/订阅队列(publish/subscribe)****

发布、订阅队列是以fanout 广播方式发送消息给消费者的

 

 

 

 queue、exchange配置

 

package com.example.demo.config;

 

import org.springframework.amqp.core.*;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

 

@Configuration

public class QueueAndExchangeConfig {

 

    //第一个队列:my-first-queue

    @Bean("myFirstQueue")

    public Queue getFirstQueue(){

        return new Queue("my-first-queue");

    }

 

    //第二个队列:my-second-queue

    @Bean("mySecondQueue")

    public Queue getSecondQueue(){

        return new Queue("my-second-queue");

    }

 

    //第一个交换机:my-first-exchange

    @Bean("myFirstExchange")

    FanoutExchange getMyFirstExchange(){

        return new FanoutExchange("my-first-exchange");

    }

 

    //将my-first-queue队列绑定到my-first-exchange交换机上

    @Bean

    Binding bindingFirstQueueToFanoutExchange(){

        return BindingBuilder.bind(getFirstQueue()).to(getMyFirstExchange());

    }

 

    //将my-second-queue队列绑定到my-first-exchange交换机上

    @Bean

    Binding bindingSecondQueueToFanoutExchange(){

        return BindingBuilder.bind(getSecondQueue()).to(getMyFirstExchange());

    }

 

}

生产者:

 

package com.example.demo.controller;

 

import org.springframework.amqp.core.Message;

import org.springframework.amqp.core.MessageDeliveryMode;

import org.springframework.amqp.core.MessageProperties;

import org.springframework.amqp.rabbit.core.RabbitTemplate;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

 

 

@RestController

@RequestMapping("producer")

public class ProducerController{

 

    @Autowired

    private RabbitTemplate rabbitTemplate;

 

    @GetMapping("/producerSendFirstExchange")

    public String sendMsg(@RequestParam(value = "msg") String msg){

        rabbitTemplate.convertAndSend("my-first-exchange","",msg);

        return msg;

    }

}

消费者:

 

package com.example.demo.config;

 

import org.springframework.amqp.rabbit.annotation.RabbitListener;

import org.springframework.stereotype.Component;

 

@Component

public class ConsumerHandler {

 

    @RabbitListener(queues = "my-first-queue")

    public void getFirstQueue(String msg){

        System.out.println("消费者1:"+msg);

    }

 

    @RabbitListener(queues = "my-second-queue")

    public void getSecondQueue(String msg){

        System.out.println("消费者2:"+msg);

    }

 

}

 

 

 

跟工作队列(work queue)做个比较,有什么不同和相同点:

 

不同:发布/订阅队列需要创建一个交换机并将队列绑定到交换机,而工作队列不需要

 

相同:多个消费者监听同一个队列,消息不会被重复消费

 

4 路由队列(routing)****

路由队列是以direct  routing = key方式发送消息给消费者的

 

queue 可以通过一个或多个routing key绑定到Exchange上,不同queue相同routing ke绑定到Exchange也是完全可以的

 

 

 

 

 

 queue、exchange配置:

 

package com.example.demo.config;

 

import org.springframework.amqp.core.*;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

 

@Configuration

public class QueueAndExchangeConfig {

 

    //第一个队列:my-first-queue

    @Bean("myFirstQueue")

    public Queue getFirstQueue(){

        return new Queue("my-first-queue");

    }

 

    //第二个队列:my-second-queue

    @Bean("mySecondQueue")

    public Queue getSecondQueue(){

        return new Queue("my-second-queue");

    }

 

    //第一个交换机:my-first-exchange

    @Bean("myFirstExchange")

    DirectExchange getMyFirstExchange(){

        return new DirectExchange("my-first-exchange");

    }

 

    //将以my-first-queue队列绑定到my-first-exchange交换机上

    @Bean

    Binding bindingFirstQueueToFanoutExchange(){

        return   BindingBuilder.bind(getFirstQueue()).to(getMyFirstExchange()).with("orange");

    }

 

    //将以my-second-queue队列绑定到my-first-exchange交换机上

    @Bean

    Binding bindingSecondQueueToFanoutExchange(){

        return BindingBuilder.bind(getSecondQueue()).to(getMyFirstExchange()).with("green");

    }

 

}

生产者:

 

package com.example.demo.controller;

 

import org.springframework.amqp.core.Message;

import org.springframework.amqp.core.MessageDeliveryMode;

import org.springframework.amqp.core.MessageProperties;

import org.springframework.amqp.rabbit.core.RabbitTemplate;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

 

 

@RestController

@RequestMapping("producer")

public class ProducerController{

 

    @Autowired

    private RabbitTemplate rabbitTemplate;

 

    @GetMapping("/producerSendFirstQueue")

    public String sendMsg(@RequestParam(value = "msg") String msg){

        rabbitTemplate.convertAndSend("my-first-exchange","green",msg);

        return msg;

    }

 

}

消费者:

 

package com.example.demo.config;

 

import org.springframework.amqp.rabbit.annotation.RabbitListener;

import org.springframework.stereotype.Component;

 

@Component

public class ConsumerHandler {

 

    @RabbitListener(queues = "my-first-queue")

    public void getFirstQueue(String msg){

        System.out.println("消费者1:"+msg);

    }

 

    @RabbitListener(queues = "my-second-queue")

    public void getSecondQueue(String msg){

        System.out.println("消费者2:"+msg);

    }

}

 

 

 

如果将my-first-queue与my-second-queue的routing-key(路由键)都设置成一样的值,那消费者1和消费者2都会收到消息,一个queue如果有多个routing-key,任意一个routing-key都可以路由到queue中,然后被消费

 

 

 

5 通配符队列(Topics)****

通配符队列这种模式是基于routing 模式上优化的一种队列,需要了解两种通配符规则:

 

*:匹配任意一个单词

 

#:匹配任意一个或多个单词

 

例子:

 

rabbit.*:匹配rabbit.first

 

rabbit.#:匹配rabbit.first 或者 rabbit.first.two

 

如果没有匹配的路由到队列,那么该消息会丢失

 

queue、exchange配置:

 

package com.example.demo.config;

 

import org.springframework.amqp.core.*;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

 

@Configuration

public class QueueAndExchangeConfig {

 

    //第一个队列:my-first-queue

    @Bean("myFirstQueue")

    public Queue getFirstQueue(){

        return new Queue("my-first-queue");

    }

 

    //第二个队列:my-second-queue

    @Bean("mySecondQueue")

    public Queue getSecondQueue(){

        return new Queue("my-second-queue");

    }

 

    //第一个交换机:my-first-exchange

    @Bean("myFirstExchange")

    TopicExchange getMyFirstExchange(){

        return new TopicExchange("my-first-exchange");

    }

 

    //将以my-first-queue队列绑定到my-first-exchange交换机上

    @Bean

    Binding bindingFirstQueueToFanoutExchange(){

        return BindingBuilder.bind(getFirstQueue()).to(getMyFirstExchange()).with("green.*");

    }

 

    //将以my-second-queue队列绑定到my-first-exchange交换机上

    @Bean

    Binding bindingSecondQueueToFanoutExchange(){

        return BindingBuilder.bind(getSecondQueue()).to(getMyFirstExchange()).with("green.#");

    }

 

}

生产者:

 

    @GetMapping("/producerSendFirstQueue")

    public String sendMsg(@RequestParam(value = "msg") String msg){

        rabbitTemplate.convertAndSend("my-first-exchange","green.red",msg);

        return msg;

    }

消费者还是监听my-first-queue和my-second-queue两个队列

 

 

 两个消费都匹配,并且路由到queue上被消费了

 

 

    @GetMapping("/producerSendFirstQueue")

    public String sendMsg(@RequestParam(value = "msg") String msg){

        rabbitTemplate.convertAndSend("my-first-exchange","green.red.blue",msg);

        return msg;

    }

 

 

结果是my-second-queue收到消息然后消费了