zoukankan      html  css  js  c++  java
  • rabbitmq

    rabbitmq是一种消息队列服务,可以实现rpc,一般情况下openstack的rpc用的就是用它做的,它有很多的用途。除了Qpid以外它是唯一实现了AMQP标准的代理服务器


    1.安装
    安装rabbitmq是一件十分容易的事情,在yum源正常的情况下直接即可
    yum install rabbitmq-server -y


    2.信道
    当你连接rmq后,你的应用程序与rmq服务器之间就会创建一条TCP连接,当你通过认证打开TCP连接后就会创建一条AMQP信道,这条信道是创建在真实TCP连接内的虚拟连接,当很多人对此rmq服务器进行连接使用时,这条TCP连接内就会有很多条信道。
    主要原因是因为对于操作系统来说创建销毁一条TCP连接是很昂贵的!并且使用TCP连接的话很快就会达到因为根据需求所设置的调度线程数,很快就会遇到瓶颈!(在一条TCP连接内创建多少信道是没有限制的)


    3.basic.consume与basic.get(知道即可)
    basic.consume会让消费者一直从队列中获取消息,比如消费者消费(拒绝)最近消费的消息后就可以自动从队列中拿下一条
    basic.get则是仅仅只获取单条消息,下一条不会再拿了,需要不断的再次执行basic.get,明显这种方式对性能有影响
    正常情况下消费者理应使用basic.consume来提升吞吐量


    4.交换器
    headers允许你匹配消息的头部而不是你设置的路由规则,剩下的与direct完全一致,但是性能上会差很多,这种不实用,现在几乎已经没有在用了
    direct很简单是一种完全根据路规则进行匹配投递的交换器
    fanout是一种完全发布的交换器,当有一条消息进来后它会直接将其发布到绑定到fanout交换器的所有队列内
    topic是一种模糊匹配的交换器,可以理解成对direct交换器匹配了正则后进行发布


    5.vhost
    rmq服务器都可以创建虚拟消息服务器,它是一个mini的rmq服务器,内部拥有着自己的队列交换机以及绑定,这样多租户之间就没有影响了
    rabbitmqctl list_vhosts # 列出所有vhosts
    rabbitmqctl add_vhost v1 # 创建一个v1的vhosts
    rabbitmqctl delete_vhost v1 # 删除v1


    6.基本操作
    systemctl start rabbitmq-server # 开启rmq服务
    systemctl stop rabbitmq-server # 关闭rmq服务
    rabbitmqctl start_app # 开启内部vhost
    rabbitmqctl stop_app # 关闭内部vhost,服务不会关闭
    rabbitmqctl add_user bfmq miao # 创建一个bfmq用户,密码是miao
    rabbitmqctl delete_user bfmq # 删除bfmq用户
    rabbitmqctl list_users # 列出所有用户
    rabbitmqctl change_password bmfq meng # 把bfmq用户的密码改成meng
    rabbitmqctl list_queues -p v1 # 列出v1内所有队列
    rabbitmqctl list_queues -p v1 name messages consumers memory # 列出v1内所有队列的名字,内部消息数目,消费者数目,内存使用
    rabbitmqctl list_exchanges -p v1 列出v1内所有交换器,出来你自己创建的交换器以外,会有amq.topic、amq.fanout、amq.match、amq.headers、amq.direct这几个默认自动生命的交换器以及在列出所有条目的底部有一个direct类型没有名字的交换器(匿名交换器,所有的队列默认都会把绑定到此交换器)
    rabbitmqctl list_queues -p v1 name type durable auto_delete # 列出v1内所有交换器的名字,类型,是否可持久化,是否自动删除


    7.权限关系
    用户对vhost的控制
    读:有关消费消息的任何操作(可清空队列)
    写:发布消息
    配置:队列及交换机的创建删除

    rabbitmqctl set_permissions -p v1 bfmq ".*" ".*" ".*" # 以前设置过再次执行即为修改成新设置的权限
    -p v1:这条权限设置是给与哪个vhost,如果不填写则是默认/,即对/ vhost进行了权限设置
    bfmq:被授予权限的用户
    ".*" ".*" ".*":授予的权限。顺序是配置,写,读

    ".*"代表所有权限
    “”代表无此权限
    “*a*”代表内部名字含有a的所有队列及交换机
    rabbitmqctl set_permissions -p v2 bfmq "" "*a*" ".*" 给与bfmq在v2内对所有队列及交换机读权限,名字内包含a的队列及交换机写权限,对内部所有队列及交换机都无配置权限

    rabbitmqctl list_permissions -p v1 # 查看对v1 vhost里所有权限,如果不填写则是对/ vhost进行查看
    rabbitmqctl clear_permissions -p v1 bfmq # 清空bfmq在v1上的权限设置
    rabbitmqctl list_user_permissions bfmq # 查看bfmq用户的所有权限


    8.集群
    通过更改port在同一台机器上搭建集群(当然正经来说肯定是不同的物理机了),默认端口5672,我们用5672,5673,5674来模拟
    RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbitmq_1 /sbin/rabbitmq-server -detached # -detached是让在后台运行
    RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=rabbitmq_2 /sbin/rabbitmq-server -detached
    RABBITMQ_NODE_PORT=5674 RABBITMQ_NODENAME=rabbitmq_3 /sbin/rabbitmq-server -detached
    rabbitmq_1作为第一个节点无需操作,但是rabbitmq_2与rabbitmq_3在加入集群前需要清空他们上面的元数据,首先需要停止erlang程序
    rabbitmqctl -n rabbitmq_2@bfmq stop_app # rabbitmq_2@bfmq,bfmq是我的主机名
    rabbitmqctl -n rabbitmq_3@bfmq stop_app
    rabbitmqctl -n rabbitmq_2@bfmq reset
    rabbitmqctl -n rabbitmq_3@bfmq reset

    组建集群
    rabbitmqctl -n rabbitmq_2@bfmq join_cluster rabbitmq_1@bfmq # 把rabbitmq_2@bfmq加入到rabbitmq_1@bfmq集群内
    rabbitmqctl cluster_status -n rabbitmq_1@bfmq # 查看rabbitmq_1@bfmq集群信息
    rabbitmqctl cluster_status -n rabbitmq_1@bfmq出现下列信息
    Cluster status of node rabbitmq_1@bfmq ...
    [{nodes,[{disc,[rabbitmq_1@bfmq,rabbitmq_2@bfmq]}]},
    {running_nodes,[rabbitmq_1@bfmq]},
    {cluster_name,<<"rabbitmq_1@bfmq">>},
    {partitions,[]},
    {alarms,[{rabbitmq_1@bfmq,[]}]}]
    我们看到running_nodes只有rabbitmq_1@bfmq一个,刚才加入的rabbitmq_2@bfmq没有运行,因为我们刚才stop_app了,现在启动它再查看信息

    rabbitmqctl -n rabbitmq_2@bfmq start_app && rabbitmqctl cluster_status -n rabbitmq_1@bfmq
    Cluster status of node rabbitmq_1@bfmq ...
    [{nodes,[{disc,[rabbitmq_1@bfmq,rabbitmq_2@bfmq]}]},
    {running_nodes,[rabbitmq_2@bfmq,rabbitmq_1@bfmq]},
    {cluster_name,<<"rabbitmq_1@bfmq">>},
    {partitions,[]},
    {alarms,[{rabbitmq_2@bfmq,[]},{rabbitmq_1@bfmq,[]}]}]
    好了现在rabbitmq_2@bfmq也在running_nodes里了,我们再将rabbitmq_3@bfmq也加进来并且启动然后查看信息

    rabbitmqctl -n rabbitmq_3@bfmq join_cluster rabbitmq_1@bfmq --ram && rabbitmqctl -n rabbitmq_3@bfmq start_app && rabbitmqctl cluster_status -n rabbitmq_1@bfmq # --ram是让此节点以内存节点加入,rmq集群内至少需要2个磁盘节点
    Cluster status of node rabbitmq_1@bfmq ...
    [{nodes,[{disc,[rabbitmq_1@bfmq,rabbitmq_2@bfmq]},{ram,[rabbitmq_3@bfmq]}]},
    {running_nodes,[rabbitmq_3@bfmq,rabbitmq_2@bfmq,rabbitmq_1@bfmq]},
    {cluster_name,<<"rabbitmq_1@bfmq">>},
    {partitions,[]},
    {alarms,[{rabbitmq_3@bfmq,[]},{rabbitmq_2@bfmq,[]},{rabbitmq_1@bfmq,[]}]}]
    我们看到rabbitmq_1@bfmq,rabbitmq_2@bfmq是disc而rabbitmq_3@bfmq是ram正是我们所设置的

    离开集群
    rabbitmqctl -n rabbitmq_3@bfmq stop_app
    rabbitmqctl -n rabbitmq_3@bfmq reset # reset会直接清空节点的状态,因此原本在集群内的状态也会被清掉
    rabbitmqctl -n rabbitmq_3@bfmq start_app # 此时rabbitmq_3@bfmq就已经是一个独立节点了
    rabbitmqctl cluster_status -n rabbitmq_1@bfmq
    Cluster status of node rabbitmq_1@bfmq ...
    [{nodes,[{disc,[rabbitmq_1@bfmq,rabbitmq_2@bfmq]}]},
    {running_nodes,[rabbitmq_2@bfmq,rabbitmq_1@bfmq]},
    {cluster_name,<<"rabbitmq_1@bfmq">>},
    {partitions,[]},
    {alarms,[{rabbitmq_2@bfmq,[]},{rabbitmq_1@bfmq,[]}]}]

    不同机器上搭建集群,那就不需要调整端口号了,我以1.1.1.1、10.10.10.10、100.100.100.100为例子直接写一遍流程
    3台机子上操作systemctl start rabbitmq-server
    将1.1.1.1内的/var/lib/rabbitmq/.erlang.cookie复制覆盖到10.10.10.10、100.100.100.100的/var/lib/rabbitmq/.erlang.cookie
    10.10.10.10、100.100.100.100操作
    systemctl restart rabbitmq-server
    rabbitmqctl stop_app
    rabbitmqctl reset
    rabbitmqctl join_cluster rabbit@1.1.1.1 && rabbitmqctl start_app
    如果写好了hosts文件就可以把ip用主机名替换掉,其实就是把@后主机名变更下以及把erlang.cookie统一


    9.升级
    独立节点升级很容易,只需要解压新版包后直接运行即可。
    集群则不可以!这样做会清除掉集群的相关配置及数据,你需要使用RabbitMQ Management插件备份当前配置,然后关闭所有生产者并且等待消费者消费完所有消息后关闭节点,解压新版本包到现有的安装目录,选用其中一个磁盘节点作为升级节点,当它运行时,该节点会把持久化的集群数据升级到新版本,然后启动其他磁盘节点,他们会获取数据自动升级,最后再打开内存节点,升级完毕。

  • 相关阅读:
    Android数据存储之SQLCipher数据库加密
    Android数据加密之Aes加密
    Android自定义控件之自定义组合控件
    Android自定义控件之自定义属性
    Android自定义控件之基本原理
    Java设计模式之代理模式(Proxy)
    Android注解使用之使用Support Annotations注解优化代码
    Java学习之注解Annotation实现原理
    Android数据存储之GreenDao 3.0 详解
    Android性能优化之App应用启动分析与优化
  • 原文地址:https://www.cnblogs.com/bfmq/p/6329563.html
Copyright © 2011-2022 走看看