關於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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM