RabbitMQ常见场景的研究

1.消息不丢失

(1)生产者弄丢数据

①使用事务(性能差)

可以选择用rabbitmq提供的事务功能,在生产者发送数据之前开启rabbitmq事务(channel.txSelect),然后发送消息,如果消息没有成功被rabbitmq接收到,那么生产者会收到异常报错,此时就可以回滚事务(channel.txRollback),然后重试发送消息;如果收到了消息,那么可以提交事务(channel.txCommit)。但是问题是,开始rabbitmq事务机制,基本上吞吐量会下来,因为太耗性能。

②发送回执确认(推荐)

可以开启confirm模式,在生产者那里设置开启confirm模式之后,你每次写的消息都会分配一个唯一的id,然后如果写入了rabbitmq中,rabbitmq会给你回传一个ack消息,告诉你说这个消息ok了。如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息id的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。
  事务机制和cnofirm机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是confirm机制是异步的,你发送个消息之后就可以发送下一个消息,然后那个消息rabbitmq接收了之后会异步回调你一个接口通知你这个消息接收到了。

所以一般在生产者这块避免数据丢失,都是用confirm机制的。

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {


    @Bean
    public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        //设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
        rabbitTemplate.setMandatory(true);

        //消息发送到交换器Exchange后触发回调
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("ConfirmCallback:     "+"相关数据:"+correlationData);
                System.out.println("ConfirmCallback:     "+"确认情况:"+ack);
                System.out.println("ConfirmCallback:     "+"原因:"+cause);
            }
        });

        //消息从交换器发送到对应队列失败时触发(比如根据发送消息时指定的routingKey找不到队列时会触发)
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                System.out.println("ReturnCallback:     "+"消息:"+message);
                System.out.println("ReturnCallback:     "+"回应码:"+replyCode);
                System.out.println("ReturnCallback:     "+"回应信息:"+replyText);
                System.out.println("ReturnCallback:     "+"交换机:"+exchange);
                System.out.println("ReturnCallback:     "+"路由键:"+routingKey);
            }
        });

        return rabbitTemplate;
    }
}

(2)rabbitMQ弄丢数据(在spring rabbit 2.2.5中查看源码,Exchange、queue和Message默认都是持久化的)

为了防止rabbitmq自己弄丢了数据,这个你必须开启rabbitmq的持久化,就是消息写入之后会持久化到磁盘,哪怕是rabbitmq自己挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢。除非极其罕见的是,rabbitmq还没持久化,自己就挂了,可能导致少量数据会丢失的,但是这个概率较小。

设置持久化有两个步骤,第一个是创建queue的时候将其设置为持久化的,这样就可以保证rabbitmq持久化queue的元数据,但是不会持久化queue里的数据;第二个是发送消息的时候将消息的deliveryMode设置为2,就是将消息设置为持久化的,此时rabbitmq就会将消息持久化到磁盘上去。必须要同时设置这两个持久化才行,rabbitmq哪怕是挂了,再次重启,也会从磁盘上重启恢复queue,恢复这个queue里的数据。

而且持久化可以跟生产者那边的confirm机制配合起来,只有消息被持久化到磁盘之后,才会通知生产者ack了,所以哪怕是在持久化到磁盘之前,rabbitmq挂了,数据丢了,生产者收不到ack,你也是可以自己重发的。

若生产者那边的confirm机制未开启的情况下,哪怕是你给rabbitmq开启了持久化机制,也有一种可能,就是这个消息写到了rabbitmq中,但是还没来得及持久化到磁盘上,结果不巧,此时rabbitmq挂了,就会导致内存里的一点点数据会丢失。

以上针对单节点,对于生产环境,是高可用集群模式,并不会将所有节点设置为disk模式,所以个人想法是保证2个disk节点,防止一个disk挂了,新消息将不会备份到磁盘

Exchange、queue和Message都备份在disk上,所以全部节点宕机,需先启动disk节点,若宕机一部分,剩下的节点没有disk节点,则后面进来的Exchange、queue和Message,在全部节点宕机后将不会再留备份(高可用集群模式下)

(3)消费端弄丢数据

主要是因为你消费的时候,刚消费到,还没处理,结果进程挂了比如重启了,那么就尴尬了,RabbitMQ认为你都消费了,这数据就丢了。或者消费者拿到数据之后挂了,这时候需要MQ重新指派另一个消费者去执行任务(一块肉,刚用筷子夹起来,发地震抖了一下,肉掉了)

这个时候得用RabbitMQ提供的ack机制,也是一种处理完成发送回执确认的机制。如果MQ等待一段时间后你没有发送过来处理完成 那么RabbitMQ就认为你还没处理完,这个时候RabbitMQ会把这个消费分配给别的consumer去处理,消息是不会丢的。

import com.xiaoll.rabbitmqconsumer.consumer.TraceReceiver;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class RabbitTraceConfig {
    @Autowired
    private CachingConnectionFactory connectionFactory;
    @Autowired
    private TraceReceiver traceReceiver;//trace消息接收处理类


    @Bean
    public Queue testTrace() {
        return new Queue("TestTrace");
    }

    @Bean
    TopicExchange traceExchange() {
        TopicExchange topicExchange = new TopicExchange("amq.rabbitmq.trace");
        topicExchange.setInternal(true);
        return topicExchange;
    }

    @Bean
    Binding bindingTrace() {
        return BindingBuilder.bind(testTrace()).to(traceExchange()).with("publish.#"); //监听所有收到的消息
    }

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setConcurrentConsumers(1);
        container.setMaxConcurrentConsumers(1);
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL); // RabbitMQ默认是自动确认,这里改为手动确认消息
        container.setQueues(testTrace());  //设置监听日志的队列
        container.setMessageListener(traceReceiver); //监听到日志收的处理方法
        return container;
    }
}
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.Map;
import java.util.Optional;

@Component
public class TraceReceiver implements ChannelAwareMessageListener {


    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            System.out.println("TestTrace消费者收到消息  : " +message.toString());
            System.out.println(message.getBody());

            //字符串
            String str2=new String(message.getBody());
            System.out.println("\n打印2:"+str2);

            //Object类型   ,这里是map类型
            String str4=this.bytesToObject(message.getBody()).toString();
            Optional<Map> map = this.bytesToObject(message.getBody());
            System.out.println("\n打印3:"+str4);
            System.out.println("\n打印4:"+map.get().get("messageData"));

            channel.basicAck(deliveryTag, true); //确认成功,队列会删除该消息
        } catch (Exception e) {
            channel.basicReject(deliveryTag, true); //确认失败,消息放回队列
            e.printStackTrace();
        }
    }

    /**
     * 数组转对象
     * @param bytes
     * @return
     */
    public static<T> Optional<T> bytesToObject(byte[] bytes) {
        T t = null;
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        ObjectInputStream sIn;
        try {
            sIn = new ObjectInputStream(new BufferedInputStream(in));
            t = (T)sIn.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Optional.ofNullable(t);

    }
}

2.消息日志存储

(1)启用官方日志监控(每个节点都要启动)

./rabbitmq-plugins enable rabbitmq_tracing

(2)开启日志监控(每个节点都要启动)

rabbitmqctl trace_on -p /

(3)自定义消息日志监控

自定义队列绑定到插件的队列上,代码处理消息即可

绑定路由键

所有消息:#

所有发送的消息:publish.#

所有消费的消息:deliver.#

指定发送到交换器的消息:publish.{交换器名字}

指定队列被消费的消息:deliver.{队列的名字}

(4)写一个自定义队列连上这个topicexchage-amq.rabbitmq.trace

import com.xiaoll.rabbitmqconsumer.consumer.TraceReceiver;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitTraceConfig {
    @Autowired
    private CachingConnectionFactory connectionFactory;
    @Autowired
    private TraceReceiver traceReceiver;//trace消息接收处理类


    @Bean
    public Queue testTrace() {
        return new Queue("TestTrace");
    }

    @Bean
    TopicExchange traceExchange() {
        TopicExchange topicExchange = new TopicExchange("amq.rabbitmq.trace");
        topicExchange.setInternal(true);
        return topicExchange;
    }

    @Bean
    Binding bindingTrace() {
        return BindingBuilder.bind(testTrace()).to(traceExchange()).with("publish.#"); //监听所有收到的消息
    }

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setConcurrentConsumers(1);
        container.setMaxConcurrentConsumers(1);
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL); // RabbitMQ默认是自动确认,这里改为手动确认消息
        container.setQueues(testTrace());  //设置监听日志的队列
        container.setMessageListener(traceReceiver); //监听到日志收的处理方法
        return container;
    }
}

(5)编写处理方法,将所有消息处理,可存库

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.Map;
import java.util.Optional;

@Component
public class TraceReceiver implements ChannelAwareMessageListener {


    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            System.out.println("TestTrace消费者收到消息  : " +message.toString());
            System.out.println(message.getBody());

            //字符串
            String str2=new String(message.getBody());
            System.out.println("\n打印2:"+str2);

            //Object类型   ,这里是map类型
            String str4=this.bytesToObject(message.getBody()).toString();
            Optional<Map> map = this.bytesToObject(message.getBody());
            System.out.println("\n打印3:"+str4);
            System.out.println("\n打印4:"+map.get().get("messageData"));

            channel.basicAck(deliveryTag, true);
        } catch (Exception e) {
            channel.basicReject(deliveryTag, true);
            e.printStackTrace();
        }
    }

    /**
     * 数组转对象
     * @param bytes
     * @return
     */
    public static<T> Optional<T> bytesToObject(byte[] bytes) {
        T t = null;
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        ObjectInputStream sIn;
        try {
            sIn = new ObjectInputStream(new BufferedInputStream(in));
            t = (T)sIn.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Optional.ofNullable(t);

    }
}

(6)日志文件保存:配置日志监听,管理界面-admin-Tracing-Add a new trace(每个node都要配置),日志目录:/var/tmp/rabbitmq-tracing

Name:自定义名字

Format:text/json,Text格式的日志方便人类阅读,JSON的方便程序解析

Max payload bytes:最大消息体大小

Pattern:可配置内,#(生产消费消息同时监控), publish.#(生产的消息), deliver.#(消费的消息)

保存完成可看到文件,打开即可查看

(7)可在exchage中看到amq.rabbitmq.trace,Connections、Channels、Queue中看到三个(各自监听各自节点的内容)用于监听日志的连接、通道及队列,检查是否启动文件保存

3.消息权限控制

(1)用户角色

①超级管理员(administrator)

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

② 监控者(monitoring)

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

③策略制定者(policymaker)

可登陆管理控制台(启用management plugin的情况下), 同时可以对policy进行管理。但无法查看节点的相关信息。

与administrator的对比,administrator能看到这些内容

④ 普通管理者(management)

仅可登陆管理控制台(启用management plugin的情况下),无法看到节点信息,也无法对策略进行管理。

⑤其他

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

(2)虚拟机:virtual-host

每个RabbitMQ 服务器都能创建若干个虚拟的消息服务器,我们称之为虚拟主机。

每一个虚拟主机都拥有自己的交换机、队列和绑定等(命名空间的概念),每个虚拟主机之间是相互隔离的,这就意味着我们可以在不同虚拟主机之间使用相同的交换机、队列。可以理解为一个沙箱,每个沙箱相互独立互不影响。

每个RabbitMQ 用户必须隶属于一个或多个虚拟主机,我们在连接RabbitMQ 的时候必须先指定一个虚拟主机。

(3)资源权限控制:permissions(针对虚拟机资源做正则表达式过滤)

1个用户对于1个虚拟机有且只有1个配置

权限配置包括:配置(队列和交换机的创建和删除)、写(发布消息)、读(有关消息的任何操作,包括清除这个队列)
conf:一个正则表达式match哪些配置资源能够被该用户访问。
write:一个正则表达式match哪些配置资源能够被该用户读。
read:一个正则表达式match哪些配置资源能够被该用户访问

(4)主题权限控制:Topic permissions

1个用户对于1个exchange有且仅有1个配置

从3.7版本开始,RabbitMQ开始支持为topic交换器设置权限,在设置权限时,要结合发布到主题交换器的消息的routing key信息(例如,在RabbitMQ默认授权后端,routing key与正则表达式是否匹配,决定了消息是否可以路由到下游)。

设置了topic授权后,向topic路由器发布消息,或者从topic路由器接收消息,都会依据消息的routing key进行权限检查,如果routing key与权限设置匹配,则成功,否则抛出异常。

(5)制定方案

①.以单虚拟机为基础权限控制方案

仅有1个虚拟机,本次采用fanout的形式推送消息,根据资源权限控制exchange、queue的读写

例如有系统A、系统B,A发消息,B收消息

A

exchange格式:A.message1 A.message2

queue格式:A.message1.A

权限:

Virtual:/
conifg:^A\..*$
write:^A\..*$
read:^.*\.A$

B

queue格式:A.message1.B(绑定A.message1)

权限:

Virtual:/
conifg:^B\..*$
write:^B\..*$
read:^.*\.A$

方案优点:只需要一个虚拟机,因此只需要开启一个日志监控,便可将所有消息监听做记录(存库或者文件)

方案缺点:通过资源的名称来控制权限,对名称要求稍严格

②.以多个虚拟机为基础权限控制方案

1个系统1个虚拟机,本次采用fanout的形式推送消息,根据资源权限控制exchange、queue的读写

例如有系统A、系统B,A发消息,B收消息

A

exchange格式:message1 message2

queue格式:message1.A

权限:

Virtual:A
conifg:.*
write:.*
read:.*

B

queue格式:message1.B(绑定A.message1)

权限:

Virtual:A
conifg:^$
write:^$
read:^.*\.B$

方案优点:整个虚拟机权限下放,任其定义exchange名称,各个系统可拥有相同的名称互不影响,queue名称因授权需要按规则定义

方案缺点:每新增一个系统,需增加一个虚拟机,并需要增加一个日志监控其虚拟机,并监听该topic进行存库或存文件操作

4.监控管理汉化

RabbitMQ Management插件提供了 HTTP API,可对集群进行很多操作,通过HTTP API接口操作集群(根据功能需要自定义开发)

postman测试,验证HTTP API

1.选择对应请求类型(get、put、delete、post)

2.Authorzation->Basic Auth->填写用户密码

3.带数据请填写,Body->raw->填写json数据

具体功能API列表如下,且验证如下(注意,“/”为URI特殊字符,默认虚拟机为“/”,需使用它时请将它编码为“%2F”)

序号 get put delete post 接口 描述
1 /api/overview 获取描述整个系统的各种概述信息
2 /api/cluster-name RabbitMQ集群的名称,需修改请带入json内容类似:{“name”:“rabbit@rabbitDM”}
3 /api/nodes RabbitMQ集群中的节点列表
4 /api/nodes/(name) RabbitMQ集群中的单个节点信息
5 /api/extensions 管理插件的扩展列表
6 /api/definitions 服务器定义-交换,队列,绑定,用户,虚拟主机,权限,主题权限和参数,除消息外的所有内容
7 /api/definitions/(vhost) 给定虚拟主机的服务器定义-交换,队列,绑定和策略
8 /api/connections 所有打开的连接的列表
9 /api/vhosts/(vhost)/connections 特定虚拟主机中所有打开的连接的列表
10 /api/connections/(name) 单个连接。删除它将关闭连接。可以选择在删除时设置“ X-Reason”标头以提供原因。
11 /api/connections/(name)/channels 给定连接的所有通道的列表
12 /api/channels 所有开放通道的列表。
13 /api/vhosts/(vhost)/channels 特定虚拟主机中所有打开的通道的列表。
14 /api/channels/(channel) 有关单个频道的详细信息。
15 /api/consumers 所有消费者的名单
16 /api/consumers/(vhost) 给定虚拟主机中所有消费者的列表
17 /api/exchanges 所有交换器的清单
18 /api/exchanges/(vhost) 给定虚拟主机中所有交换器的列表
19 /api/exchanges/(vhost)/(name) 单个交换器操作。增加交换,格式如下:{“ type”:“ direct”,“ auto_delete”:false,“ durable”:true,“internal”:false,“arguments”:{}}
该type关键是强制性的; 其他键是可选的。
删除交换时,可以添加查询字符串参数if-unused=true。如果交换绑定到队列或作为另一个交换的源,这将阻止删除成功。
20 /api/exchanges/(vhost)/(name)/bindings/source 以给定交换为源的所有绑定的列表。
21 /api/exchanges/(vhost)/(name)/bindings/destination 以给定交换为目的地的所有绑定的列表。
22 /api/exchanges/(vhost)/(name)/publish 将消息发布到给定的交易(不建议使用,效率低,使用tcp的长连接发即可)
23 /api/queues 所有队列的列表。
24 /api/queues/(vhost) 给定虚拟主机中所有队列的列表。
25 /api/queues/(vhost)/(name) 单个队列。增加队列,格式如下:
{“ auto_delete”:false,“ durable”:true,“ arguments”:{},“ node”:“ rabbit @ smacmullen”}
所有键都是可选的。
删除队列时,可以添加查询字符串参数if-empty=true和/或if-unused=true。如果队列分别包含消息或具有使用者,则这会阻止删除成功。
27 /api/queues/(vhost)/(name)/bindings 给定队列上所有绑定的列表。
28 /api/queues/(vhost)/(name)/contents 队列的内容。删除以清除。请注意,您无法获得此。
29 /api/queues/(vhost)/(name)/actions 可以在队列上执行的操作。张贴以下内容:
{“ action”:“ sync”}
当前支持的操作是sync和cancel_sync。
30 /api/queues/(vhost)/(name)/get 从队列中获取消息。(这不是HTTP GET,因为它会更改队列的状态。)您应该发布一个类似于以下内容的正文:
{“ count”:5,“ ackmode”:“ ack_requeue_true”,“ encoding”:“ auto”,“ truncate”:50000}
count控制要获取的最大消息数。如果队列无法立即提供消息,则收到的消息可能少于此。
ackmode确定是否从队列中删除消息。如果ackmode为ack_requeue_true或reject_requeue_true,则将重新排队-如果ackmode为ack_requeue_false或reject_requeue_false,则将其删除。
encoding 必须是“自动”(在这种情况下,有效载荷将是有效的UTF-8,否则有效载荷将以字符串形式返回,否则将以base64编码)或“ base64”(在这种情况下,有效载荷将始终以base64编码)。
如果truncate存在,则它将大于给定的大小(以字节为单位)截断消息有效负载。
truncate是可选的;所有其他键都是必需的。

请注意,HTTP API中的get路径用于诊断等-它不能实现可靠的传递,因此应将其视为sysadmin的工具,而不是用于消息传递的常规API。
31 /api/bindings 所有绑定的列表。
32 /api/bindings/(vhost) 给定虚拟主机中所有绑定的列表。
33 /api/bindings/(vhost)/e/(exchange)/q/(queue) 交换和队列之间的所有绑定的列表。请记住,交换和队列可以绑定在一起很多次!

要创建新的绑定,请发布到该URI。请求正文应该是一个JSON对象,可以选择包含两个字段routing_key(一个字符串)和arguments(一个可选参数的映射):

{“ routing_key”:“ my_routing_key”,“ arguments”:{“ x-arg”:“ value”}}
所有键都是可选的。响应将包含一个Location标头,告诉您新绑定的URI。
34 /api/bindings/(vhost)/e/(exchange)/q/(queue)/(props) 交换和队列之间的个体绑定。URI 的props部分是绑定的“名称”,该名称由其路由键和其参数的哈希组成。props是绑定列表响应中名为“ properties_key”的字段。
35 /api/bindings/(vhost)/e/(source)/e/(destination) 两个交换器之间的所有绑定的列表,类似于上面的交换机和队列之间的所有绑定的列表。

要创建新的绑定,请发布到该URI。请求正文应该是一个JSON对象,可以选择包含两个字段routing_key(一个字符串)和arguments(一个可选参数的映射):

{“ routing_key”:“ my_routing_key”,“ arguments”:{“ x-arg”:“ value”}}
所有键都是可选的。响应将包含一个Location标头,告诉您新绑定的URI。
36 /api/bindings/(vhost)/e/(source)/e/(destination)/(props) 两个交换器之间的个体绑定。类似于上面的交换和队列之间的单独绑定。
37 /api/vhosts 所有虚拟主机的列表。
38 /api/vhosts/(name) 单个虚拟主机。由于虚拟主机通常只有一个名称,因此在放置其中之一时不需要HTTP正文。要启用/禁用跟踪,请提供如下所示的主体:
{“ tracing”:true}
39 /api/vhosts/(name)/permissions 给定虚拟主机的所有权限的列表。
40 /api/vhosts/(name)/topic-permissions 给定虚拟主机的所有主题权限的列表。
41 /api/vhosts/(name)/start/(node) 在节点node上启动虚拟主机名。
42 /api/users 所有用户的列表。
43 /api/users/without-permissions 无权访问任何虚拟主机的用户列表。
44 /api/users/bulk-delete 批量删除用户列表。请求正文必须包含列表:
{“users” : [“user1”, “user2”, “user3”]}
45 /api/users/(name) 个人用户。要放置用户,您将需要一个如下所示的主体:
{“password”:“secret”,“tags”:“administrator”}
要么:
{“ password_hash”:“ 2lmoth8l4H0DViLaK9Fxi6l9ds8 =”,“ tags”:“administrator”}
该tags密钥是强制性的。无论是 password或password_hash 可以设置。如果两者均未设置,则用户将无法使用密码登录,但是可以使用其他机制,例如客户端证书。设置password_hash为,""将确保用户不能使用密码登录。tags是用户的逗号分隔标签列表。目前公认的标签administrator,monitoring和management。 password_hash必须使用此处描述的算法生成 。您还可以通过将hashing_algorithm 键添加到主体来指定要使用的哈希函数。目前公认的算法rabbit_password_hashing_sha256, rabbit_password_hashing_sha512和rabbit_password_hashing_md5。
46 /api/users/(user)/permissions 给定用户的所有权限的列表。
47 /api/users/(user)/topic-permissions 给定用户的所有主题权限的列表。
48 /api/whoami 当前已认证用户的详细信息。
49 /api/permissions 所有用户的所有权限列表。
50 /api/permissions/(vhost)/(user) 用户和虚拟主机的个人许可。要获得许可,您将需要一个如下所示的主体:
{“ configure”:“。”,“ write”:“。”,“ read”:“。*”}
所有键都是强制性的。
51 /api/topic-permissions 所有用户的所有主题权限的列表。
52 /api/topic-permissions/(vhost)/(user) 用户和虚拟主机的主题权限。要放置主题权限,您将需要一个如下所示的主体:{“ exchange”:“ amq.topic”,“ write”:“ ^ a”,“ read”:“。*”}所有键都是强制性的。
53 /api/parameters 所有虚拟主机作用域参数的列表。
54 /api/parameters/(component) 给定组件的所有虚拟主机作用域参数的列表。
55 /api/parameters/(component)/(vhost) 给定组件和虚拟主机的所有虚拟主机作用域参数的列表。
56 /api/parameters/(component)/(vhost)/(name) 单个虚拟主机作用域参数。要放置参数,您将需要一个如下所示的主体:
{“ vhost”:“ /”,“ component”:“ federation”,“ name”:“ local_username”,“ value”:“ guest”}
57 /api/global-parameters 所有全局参数的列表。
58 /api/global-parameters/(name) 单个全局参数。要放置参数,您将需要一个如下所示的主体:
{“ name”:“ user_vhost_mapping”,“ value”:{“ guest”:“ /”,“ rabbit”:“ warren”}}
59 /api/policies 所有策略的列表。
60 /api/policies/(vhost) 给定虚拟主机中所有策略的列表。
61 /api/policies/(vhost)/(name) 个人政策。要提出政策,您需要一个看起来像这样的主体:
{“ pattern”:“ ^ amq。”,“ definition”:{“ federation-upstream-set”:“ all”},“ priority”:0,“ apply-to”:“ all”}
pattern并且definition是必需的,priority并且apply-to是可选的。
62 /api/operator-policies 所有操作员策略替代的列表。
63 /api/operator-policies/(vhost) 给定虚拟主机中所有操作员策略替代的列表。
64 /api/operator-policies/(vhost)/(name) 个体运营商政策。要提出政策,您需要一个看起来像这样的主体:
{“ pattern”:“ ^ amq。”,“ definition”:{“ expires”:100},“ priority”:0,“ apply-to”:“ queues”}
pattern并且definition是必需的,priority并且apply-to是可选的。
65 /api/aliveness-test/(vhost) 声明一个测试队列,然后发布并使用一条消息。供监视工具使用。如果一切正常,将返回带有正文的HTTP状态200:
{“status”:“ok”}
注意:测试队列不会被删除(如果队列被反复ping,以防止队列搅动)。
66 /api/healthchecks/node 在当前节点中运行基本运行状况检查。检查Rabbit应用程序是否正在运行,是否可以成功列出通道和队列,并且没有警报有效。如果一切正常,将返回带有正文的HTTP状态200:
{“status”:“ok”}
如果失败,将返回HTTP状态200,其内容为
{“status”:“failed”,“reason”:“string”}
67 /api/healthchecks/node/(node) 在给定的节点中运行基本的运行状况检查。检查Rabbit应用程序是否正在运行,是否返回list_channels和list_queues,并且没有引发警报。如果一切正常,将返回带有正文的HTTP状态200:
{“status”:“ok”}
如果失败,将返回HTTP状态200,其内容为
{“status”:“failed”,“reason”:“string”}
68 /api/vhost-limits 列出所有虚拟主机的每个虚拟主机限制。
69 /api/vhost-limits/(vhost) 列出特定虚拟主机的每个虚拟主机限制。
70 /api/vhost-limits/(vhost)/(name) 设置或删除的每个虚拟机限制vhost。该nameURL路径元素是指限制(的名称max-connections,max-queues)。限制是使用正文中的JSON文档设置的:
{“值”:100}
。请求示例:
curl -4u’guest:guest’-H’content-type:application / json’-X PUT localhost:15672 / api / vhost-limits / my-vhost / max-connections -d’{“ value”:50}’
©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值