zoukankan      html  css  js  c++  java
  • 关于RabbitMQ关键性问题的总结

    摘要:本篇是本人对RabbitMQ使用的关键性问题进行的总结,如性能上限、数据存储、集群等,

                具体的RabbitMQ概念、安装、使用方法、SpringAMQP配置,假设读者已有了基础。

    1.      RabbitMQ

    1.1  RabbitMQ数据速率问题

    在边读边写的情况下:速率只与网络带宽正相关,网络使用率最高能达到接近100%,并且数据使用率很高(90%以上)。

            在千兆网下,以500KB一条数据为例,读写速率均能达到200/s,约为100MB/s

    在只写不读的情况下:写入速率瓶颈在于硬盘写入速度。

     

    1.2  RabbitMQ数据存储路径变更到D盘方法

    Windows环境下,在安装前设置环境变量:RABBITMQ_BASE=D:RabbitMQ_Data

     

    1.3  RabbitMQ磁盘写满重启后数据丢失问题

    表现:磁盘写满后发送、读取程序均不能连接服务。

    解决方法:将QueueExchange设置为Durable即不会发生数据丢失问题。

    通过a.关闭服务;b.删除占位文件、erl_crash.dump;c.重启服务 三步操作后,磁盘会清理出10M左右空间,此时读取数据程序便可正常工作。

    正确设计的架构,应确保RabbitMQ不会发生磁盘写满崩溃的情况。

     

    1.4  RabbitMQ集群

    在网络带宽占满的情况下,通过集群的方式解决吞吐量不足的问题需要多台效果才明显。


    假设外设吞吐率为d条/s,外设向RabbitMQ1发送的概率为r1,向RabbitMQ2发送的概率为r2,RabbitMQ1需要向RabbitMQ2转发的概率为r3,RabbitMQ2需要向RabbitMQ1转发的概率为r3。那么RabbitMQ1进入的吞吐率为:(r1*d + r4*r2*d) 条/s ≈ 3d/4条/s,RabbitMQ2进入的吞吐率为:(r2*d + r3*r1*d) 条/s ≈ 3d/4条/s;这样的确比只使用一台RabbitMQ的吞吐率d/s要求低些。

    NRabbitMQ的集群,每台的平均吞吐率为:(2N-1)d/(N*N) 条/sN=3时,平均吞吐率为5d/9/sN=4时,平均吞吐率为7d/16/s

    解决方法:多台RabbitMQ服务器提供服务,在客户端以轮循方式访问服务,若1down掉则不使用此台的队列服务,服务器之间没有联系,这样NRabbitMQ的平均吞吐率为:1d/N /s。具体实现可以,专写一个用户收发RabbitMQ消息的jar/dll,在配置文件里填写RabbitMQ机器地址,使用轮循询问、收发的方式,提供给应用程序以黑盒方式调用。下面提供了java版本的收发实现。

    发送端sender.xml配置:

    <!-- 处理器相关 -->
        <bean id="sender" class="demo.Sender">
            <property name="templates">
                <list>
                    <ref bean="template1" />
                <!--     <ref bean="template2" /> -->
                </list>
            </property>
        </bean>
     
        <bean id="timeFlicker" class="demo.TimeFlicker">
            <property name="handlers">
                <list>
                    <ref bean="sender" />
                </list>
            </property>
        </bean>
        <!-- 处理器相关 -->
     
        <!-- amqp配置 相关 -->
        <rabbit:connection-factory id="connectionFactory1"
            host="192.1.11.108" username="guest" password="guest" virtual-host="/" />
        <rabbit:connection-factory id="connectionFactory2"
            host="192.1.11.172" username="guest" password="guest" virtual-host="/" />
        <!-- amqp配置 相关 -->
     
        <!-- 发送相关 -->
        <rabbit:template id="template1" connection-factory="connectionFactory1"
            exchange="exchange" />
     
        <rabbit:template id="template2" connection-factory="connectionFactory2"
            exchange="exchange" />

        <!-- 发送相关 -->

                      说明:这里配置了两个RabbitMQ服务器,timeFlicker的目的是过一段时间把不能服务的RabbitMQ服务器重新添加到列表中,重试发送。

                      接收端receiver.xml配置:

    <!-- amqp配置 相关 -->
        <rabbit:connection-factory id="connectionFactory1"
            host="192.1.11.108" username="guest" password="guest" virtual-host="/" />
        <rabbit:connection-factory id="connectionFactory2"
            host="192.1.11.172" username="guest" password="guest" virtual-host="/" />
        <!-- amqp配置 相关 -->
     
        <!-- 监听相关 -->
        <bean id="Recv1" class="demo.Recv1" />
        <rabbit:listener-container id="Listener1"
            connection-factory="connectionFactory1" prefetch="1" acknowledge="auto">
            <rabbit:listener ref="Recv1" method="listen"
                queue-names="queue1" />
        </rabbit:listener-container>
        <bean id="Recv2" class="demo.Recv2" />
        <rabbit:listener-container id="Listener"
            connection-factory="connectionFactory1" prefetch="1" acknowledge="auto">
            <rabbit:listener ref="Recv2" method="listen"
                queue-names="queue2" />
        </rabbit:listener-container>

        <!-- 监听相关 -->

                     说明:这里监听了两个RabbitMQ服务器,此处不需要timeFlicker。

                     如需具体代码可以联系本人 http://www.cnblogs.com/wgp13x/

    我认为MQ丢数据的问题,主要是同步还是异步刷盘、断电是否导致的。只要send反馈正确,确保发送被接收,receive时有反馈后才会删除数据;同步刷盘,或异步刷盘不断电的,就不会丢失消息,

    程序对于发送反馈异常的,要记录;MQ对于receive无反馈的,有重发机制,可能会有一条数据发送多次的情况,要在程序中剔除。

     

    http://weibo.com/aitanjupt

  • 相关阅读:
    链表操作二——中间结点的删除等
    stack vector queue 等的实现方式<<0922
    任何和日期相关的函数都在这里<<0922
    类函数返回该类的问题<<0922
    Android学习笔记之PullToRefreshListView和BaseAdapter的使用
    记录Android学习过程中遇到的问题
    ruby appium 准备环境
    os x升级到10.10后appium不能测试通过的解决办法
    appium 在ios模拟器上面成功运行
    appium IOS真机测试
  • 原文地址:https://www.cnblogs.com/jpfss/p/10313029.html
Copyright © 2011-2022 走看看