<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 41  文章 - 7  trackbacks - 0
    <2016年7月>
    262728293012
    3456789
    10111213141516
    17181920212223
    24252627282930
    31123456

    常用鏈接

    留言簿

    隨筆分類

    隨筆檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    在這一章中,我們將涵蓋:
    1. 多線程和隊列
    2. 系統(tǒng)調(diào)整
    3. 改善帶寬
    4. 使用不同分發(fā)工具
    介紹
    這里沒有標準的RabbitMQ調(diào)優(yōu)指南,因為不同應(yīng)用程序會采用不同方式優(yōu)化.
    通常情況下,應(yīng)用程序需要在客戶端進行優(yōu)化:
    1. 處理器密集型應(yīng)用程序可以通過為每個處理器內(nèi)核運行一個線程來進行優(yōu)化
    2. I/O密集型應(yīng)用程序可以通過在單核上運行多個線程來隱藏隱式延遲
    在兩種情況下,消息傳遞是完美的結(jié)合.為了優(yōu)化網(wǎng)絡(luò)傳輸速率,AMQP標準規(guī)定消息按束(bunches)進行傳輸,然后再由客戶端一個一個地消費(參考第1章,使用AMQP).
    RabbitMQ 允許多線程應(yīng)用程序高效地消費消息;這部分內(nèi)容將在多線程和隊列食譜中涉及.

    另一個常見的用例是當RabbitMQ在分布式應(yīng)用程序服務(wù)大量客戶的情況.在這種情況下,更為現(xiàn)實的瓶頸是broker而不是客戶端應(yīng)用程序。在這種情況下,重要的是,我們的經(jīng)紀人有一個特點,即:可擴展性。
    當客戶數(shù)量超過當前的最大容量閥值時,可在集群在增加一個或多個節(jié)點來分散負載,并提高總吞吐量。
    那為什么要到那時才來優(yōu)化呢?其主要原因是減少硬件、電力、冷卻或云計算資源的成本。

    在章節(jié)中,我們將討論RabbitMQ的性能,同時也會展
    示一些技巧來提高客戶端的性能,并最終修改broker參數(shù).
    多線程和隊列
    使用多線程也改善應(yīng)用程序的性能.在本食譜中,我們將展示如何使用連接、通道、多線程.在這個例子中,我們使用的是Java,但一般來說,在目前多數(shù)技術(shù)中,使用多線程來提高性能是一種很好的實踐。
    你可在這里找到源碼:Chapter08/Recipe01.
    準備
    你需要Java 1.7+和Apache maven.
    如何做
    在這個例子中,我們繼承了ReliableClient Java 類 (參考第7章,開發(fā)高可用應(yīng)用程序) 創(chuàng)建了一個producer,一個consumer. 讓我們看下面的詳細步驟:
    1. 創(chuàng)建一個maven project,并增加RabbitMQ client 依賴.
    2. 創(chuàng)建一個繼承ReliableClient的producer.
    3. 創(chuàng)建一個繼承ReliableClient的consumer.
    4. 使用下面的方法,為consumer和producer類創(chuàng)建一個ExecutorService Java類:
    ExecutorService exService =Executors.newFixedThreadPool(threadNumber);

    5. 以線程數(shù)目創(chuàng)建Runnable任務(wù).producer如下:
    for (int i = 0; i<threadNumber; i++) {
    exService.execute(new Runnable() {
    @Override
    public void run() {
    try {
    publishMessages();
    6.以線程數(shù)目創(chuàng)建Runnable任務(wù).consumer如下 :
    for (int i = 0; i<threadNumber; i++) {
    exService.execute(new Runnable() {
    @Override
    public void run() {
    final Channel internalChannel;
    try {
    internalChannel = connection.createChannel();
    @Override
    public void handleDelivery(String consumerTag,Envelope envelope, BasicProperties properties,byte[] body) throws IOException {..}

    如何工作
    ReliableClient 類創(chuàng)建了一個名為perf_queue_08/01的隊列, 它將綁定到一個producer和一個consumer. producer 和 consumer 都會打開一個連接,并會基于每個線程創(chuàng)建一個通道。
    通道可以在多個線程之間共享,但為了避免同步次數(shù)和一些鎖的問題,盡量對每個線程單獨創(chuàng)建一個通道。

    TIP
    通道并不總是線程安全的.這依賴于實現(xiàn),例如,在使用 .NET client API時,在使用其方法前,你應(yīng)該該對IModel加鎖.閱讀https://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v3.1.5/rabbitmqdotnet-client-3.1.5-user-guide.pdf中的IModel should not be shared between threads章節(jié).

    要開始多線程(步驟3),我們使用了Java ExecutorService 類的Executors.newFixedThreadPool(..).通過這種方式,你可以控制你的線程數(shù)目.
    TIP
    你可在 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html找到更多關(guān)于ExecutorService類和Java線程池的信息.


    在這個例子中,你可以選擇消息大小,運行時間,以及消費的消息數(shù)目.你可以使用下面的命令來創(chuàng)建rmqThreadTest.jar 文件:
    mvn clean compile assembly:single
    現(xiàn)在,你可以使用下面的命令來測試producer:
    java -cp rmqThreadTest.jar rmqexample.ProducerMain 4 10000 128
    第1個參數(shù)是線程數(shù)目;第二個參數(shù)是以毫秒為單位的運行時間;最后一個是以byte為單位的緩沖區(qū)大小.
    你可以使用下面的命令來測試consumer:
    java -cp rmqThreadTest.jar rmqexample.ConsumerMain 4
    參數(shù)是線程的數(shù)目.你可以結(jié)合producer和consumer參數(shù)來測試應(yīng)用程序,并在你的環(huán)境中來找到更好的性能.打開web管理控制臺來檢查實際速率,如下面截圖所示:

    更多
    當隊列為空時,隊列比較快,在設(shè)計應(yīng)用程序時,應(yīng)該盡可能地讓隊列保持空的狀態(tài)在你的應(yīng)用程序需要處理負載尖峰時,隊列容量會很方便。
    通過使用隊列,消息最終會被緩存并在不丟失任何信息的情況下地被處理.
    如果消費者的速度慢于生產(chǎn)者,那么你必須更加快速地消費消息,如:你可以嘗試添加更多的線程或消費者來加速消息的消費.

    TIP
    從3.2.0版本開始, RabbitMQ支持隊列聯(lián)合(http://www.rabbitmq.com/blog/2013/10/23/federated-queuesin-3-2-0/), 它可以在沒有集群的情況下, 均衡多個broker上的消息負載無論如何,如果你有一個以前版本的RabbitMQ,你必須將你的隊列手動地分配更多的broker。

    生產(chǎn)者和消費者線程的數(shù)量嚴格依賴于您的應(yīng)用程序和部署環(huán)境。注意不要打開太多的線程,因為這可能會有相反的效果。
    系統(tǒng)調(diào)優(yōu)
    在這個食譜中,我們會展示從RabbitMQ獲得最大性能的一些有用步驟。我們將涵蓋以下主題:
    1. vm_memory_high_watermark 配置 (http://www.rabbitmq.com/memory.html)
    2. Erlang High Performance Erlang (HiPE) (http://erlang.org/doc/apps/hipe/)
    vm_memory_high_watermark配置用于設(shè)置消息被消耗或緩存到磁盤前,所占用的最大系統(tǒng)內(nèi)存百分比.在達到極限前,默認情況下,在vm_memory_high_watermark設(shè)置的百分之五十時,(或適當設(shè)置vm_memory_high_watermark_paging_ratio參數(shù),默認情況下設(shè)置為0.5),RabbitMQ會開始將消息從內(nèi)存移動到磁盤分頁空間上。
    如果沒有這個分頁機制,或者消費者趕不上生產(chǎn)者的步伐,這將導(dǎo)致達到極限,然后RabbitMQ將阻塞生產(chǎn)者。
    在某些情況下,加大這些參數(shù)是可能的,這樣可以避免消息過早地轉(zhuǎn)移到到磁盤上。在這個食譜中,我們將看到如何結(jié)合HIPE做。這里包含有兩個不同的方面,但完成他們所需要的步驟是非常相似的。
    你可以使用Chapter08/Recipe02目錄下的代碼.
    準備
    要嘗試本食譜,你必須從RabbitMQ開始,并安裝管理插件.接著,你還需要java 1.7+和Apache maven.
    如何做
    為了從RabbitMQ中獲取最大性能,你可以執(zhí)行下面的步驟:
    1. 配置watermark:
    rabbitmqctl set_vm_memory_high_watermark 0.6
    或者直接在rabbitmq.config文件配置:
    [{rabbit, [{vm_memory_high_watermark, 0.6}]}].
    2. 修改Linux ulimit 參數(shù),修改/etc/default/rabbitmqserver文件.然后,你可以使用HiPE來改善RabbitMQ自身.
    3. 從http://www.erlang.org/download.html來安裝最新版本的Erlang.
    4. 在你的系統(tǒng)中安裝HiPE.
    5. 檢查HiPE是否已正確激活;如果沒有,你需要從源碼來安裝Erlang,并將其激活.
    6. 在RabbitMQ 配置文件中激活Erlang HiPE. 創(chuàng)建rabbitmq.config文件并用下面的選項激活,或者現(xiàn)有的配置文件中添加下面的配置:
    [
    {rabbit, [{hipe_compile, true}]}
    ].
    7. 重啟RabbitMQ.
    8. 檢查RabbitMQ日志文件,確保沒有HiPE沒有激活的警告:
    =WARNING REPORT==== 6-Oct-2013::00:38:23 ===
    Not HiPE compiling: HiPE not found in this Erlang installation.

    如何工作
    watermark是RabbitMQ可使用的最大內(nèi)存,默認情況下,其值為0.4,即它可使用安裝物理內(nèi)存的40%.當內(nèi)存達到watermark時,broker會停止接受新的連接和消息.watermark 值可以是近似的.
    在某些情況下,它可以不是默認的百分之40。無論如何,當服務(wù)器有大量的內(nèi)存,你可以增加值,例如,只是為了容忍尖峰,可將增加到百分之60。
    與rabbitmqctl變化是暫時的相比,當你修改rabbitmq.config文件,該選項將設(shè)置為永久生效。
    默認情況下ulimit參數(shù)為1024。增加此值,可增加文件的數(shù)量和可用的RabbitMQ socket.
    TIP
    太高的值可能會對系統(tǒng)造成負面影響。在https://wiki.debian.org/limits可了解關(guān)于ulimit參數(shù)的說明。
    目前來說,Erlang HiPE是實驗性質(zhì)的.如果它能工作,我們可以使用它,但如果系統(tǒng)不穩(wěn)定,你需要禁用它.
    然而,對于RabbitMQ服務(wù)器來說,如果CPU是瓶頸的話,使用它,你可以獲得百分之40的CPU使用上的改進。 例如,在下面的截圖中,
    你可以看到在一個生產(chǎn)者和消費者的標準配置在本地broker的行為:

    在這個例子中,我們在本地同時運行producer和consumer, 300秒發(fā)送了32字節(jié)消息, 并讓消費者實時消費所有消息.
    當 HiPE激活后,如下面的截圖所示, 同樣的測試將表現(xiàn)得更好:

    在RabbitMQ配置文件中激活HiPE前,你可以通過調(diào)用下面的erl命令進行檢查:
    # erl
    Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [smp:2:2] [asyncthreads:0] [hipe] [kernel-poll:false]
    EshellV5.9.3.1 (abort with ^G)
    1>
    這里HiPE是存在的,在啟動時,你可以看到[hipe]選項.

    TIP
    在 Debian wheeze 系統(tǒng)中,當從Erlang網(wǎng)站下載了最新Erlang版本時,你可以通過下面的命令來安裝HiPE模塊:
    apt-get install erlang-base-hipe 
    其它的發(fā)行包也有相似的可用包.

    否則,你需要使用外部包或從 http://www.erlang.org/download.html下載Erlang源碼包來安裝,同時在配置時,需要記得指定 --enable-hipe 選項.
    一旦RabbitMQ已經(jīng)配置好了(步驟6),你將注意到服務(wù)器的重啟會花費較長時間,一般需要數(shù)分鐘.
    TIP
    在大部分Linux的發(fā)行版中,默認的RabbitMQ配置位于/etc/rabbitmq/rabbitmq.config.

    此時,RabbitMQ broker是HiPE激活的. 
    最苛刻的部分不被解釋了,但在啟動時編譯成本地機器代碼.
    你可以檢查日志文件,確保你不會看到下面的消息:
    =WARNING REPORT==== 6-Oct-2013::00:38:23 ===
    Not HiPE compiling: HiPE not found in this Erlang installation.


    TIP
    默認情況下,在Linux RabbitMQ上, 日志文件存放在/var/log/rabbitmq. 在12章節(jié),管理RabbitMQ 錯誤條件中可找到更多信息.
    更多
    因為HIPE是實驗性的,我們不鼓勵從一開始就使用考慮到通常需要的優(yōu)化,來解決應(yīng)用程序的優(yōu)化和可擴展性.
    然而,通過啟用它,您可以減少服務(wù)器的使用率和功耗,因此這是一個可以在優(yōu)化您的架構(gòu)時考慮的選項。

    改善帶寬
    使用noAck標志以及管理prefetch參數(shù)是另一種用來提高性能和帶寬的客戶端方式,它兩者都由消費者來使用的.
    在這個例子中,我們將使用這些參數(shù)來創(chuàng)建一個producer 和一個consumer. 你可在Chapter08/Recipe03找到源碼.
    準備
    你需要Java 1.7+和Apache maven.
    如何做
    我們將跳過produce代碼,因為它與多線程和隊列食譜中是一樣的. 我們?nèi)匀皇褂?span style="background-color: inherit;">ReliableClient類來作基礎(chǔ)類. 我們可通過執(zhí)行下面的步驟來查看consumer:
    1. 創(chuàng)建一個maven project,并添加RabbitMQ client依賴.
    2. 創(chuàng)建一個 consumer 主類,它可讀取args[]來管理consumer,其四個參數(shù)如下:
    threadNumber = Integer.valueOf(args[0]);
    prefetchcount = Integer.valueOf(args[1]);
    autoAck = (Integer.valueOf(args[2]) != 0);
    print_thread_consumer= (Integer.valueOf(args[3]) != 0);
    3. 創(chuàng)建一個繼承ReliableClient類的consumer,然后設(shè)置prefetch、noAck參數(shù):
    internalChannel.basicQos(prefetch_count);
    internalChannel.basicConsume(Constants.queue, autoAck..

    如何工作
    如果設(shè)置了noAck選項時, 預(yù)提取大小(prefetch-size)將被忽略, 因此我們將本食譜分成兩部分講解:
    1. Prefetch
    2. noAck
    其目標是理解如何管理客戶端參數(shù)來改善性能和帶寬.
    Prefetch
    要設(shè)置prefetch,使用basicQos(prefetch_count) (步驟3).
    在第1章節(jié)使用AMQP,分發(fā)消息給多個消費者中,我們已經(jīng)了解了channel QoS參數(shù), 在那里,為了正解地負載均衡消息,消息是一個接一個地應(yīng)答的.
    預(yù)取數(shù)是未確認消息的最大數(shù)目:較大的值會讓客戶提前預(yù)取的許多消息,而不用等待正在被處理消息的應(yīng)答.
    正如本章開頭所說的,優(yōu)化時,沒有一個通用的規(guī)則。
    事實上,提高預(yù)取數(shù)可能會適得其反,當每個消息的處理時間很重要時,我們需要分配和平衡處理。
    首先,Maven將使用下面的命令編譯:
    mvn clean compile assembly:single
    然后, maven會創(chuàng)建rmqAckTest.jar包.
    現(xiàn)在你可以嘗試這個例子,通過修改參數(shù)來查看消息速率的改變.我們在MacBook pro Dual Core, 4 GB RAM機器上使用下面的參數(shù)來測試:
    1.對于producer, 我們可以運行下面的命令:
    java -cp rmqAckTest.jar rmqexample.ProducerMain 1 100000 64000
    2.對于consumer,我們可以運行下面的兩個測試:
    java -cp rmqAckTest.jar rmqexample.ConsumerMain 2 50 0 0
    java -cp rmqAckTest.jar rmqexample.ConsumerMain 2 1 0 0
    producer使用 uses thread for 100 seconds and 64000 bytes as the message size.
    consumer 使用了 2個線程,在Test1中的預(yù)提取大小是50,Test2中是1autoAck設(shè)為了false, 并且不在控制臺中打印線程數(shù)目.
    兩種測試的結(jié)果如下:

    正如你所看到的,預(yù)提取大小不同,效果也不同,特別是有多個消費者綁定到同一個隊列上的時候.
    NoAck
    要設(shè)置noAck,使用basicConsume(Constants.queue, true). 當消息是數(shù)據(jù)流或者根本不關(guān)心手動應(yīng)答時,此參數(shù)是很有用處的.
    TIP
    在Java API中, Channel.basicConsume 的act參數(shù)名稱作為Boolean類型的autoack,存在嚴重的誤導(dǎo),實際上autoack=true表示我們會設(shè)置noAck選項.

    當設(shè)置了noAck時,你不能調(diào)用下面的方法:
    internalChannel.basicAck(envelope.getDeliveryTag(), false);
    嘗試將第三個參數(shù)(忽略了第二個)設(shè)置為1來測試  :
    java -cp rmqAckTest.jar rmqexample.ConsumerMain 1 1 1 0


    更多
    在優(yōu)化消息傳遞操作時,可以通過應(yīng)用方面的優(yōu)化來獲得性能提升。這是可行的,無論是“小”和“大”的消息:
    1. 如果消息太小, 在發(fā)送前,你可以手動對它們進行打包,然后在接收端再進行解包
    2. 如果消息太大,在發(fā)送前,你可以嘗試壓縮消息,并在消費端進行解壓
    也可參考
    閱讀http://www.rabbitmq.com/blog/2012/04/17/rabbitmqperformance-measurements-part-1/ 和 http://www.rabbitmq.com/blog/2012/04/25/rabbitmq-performance-measurements-part-2/來理解如何單個參數(shù)的重要性.

    使用不同的分發(fā)工具
    當應(yīng)用程序需要提高性能的時候,你需要選擇正確的分發(fā)工具. 在這個例子中,我們將展示發(fā)布消息時,鏡像隊列和非鏡像隊列之間的不同點.
    準備
    你需要Java 1.7+和Apache Maven.
    如何做
    你可以使用改善帶寬食譜中的源碼,并創(chuàng)建一個包含兩個節(jié)點的RabbitMQ集群.

    如何工作
    使用HA鏡像隊列的集群相比單個broker較慢。鏡像服務(wù)器的數(shù)目越高,應(yīng)用程序就越慢,因為只有當消息全部存在鏡像節(jié)點之后,生產(chǎn)者才能發(fā)送更多的消息。

    TIP
    這并不像它看起來的那樣糟糕。一方面,對集群節(jié)點是并行執(zhí)行的,所以開銷不會隨著節(jié)點的數(shù)量線性增長。另一方面,通常情況下,復(fù)制最多限制為兩到三份,這部分內(nèi)容已在第7章,開發(fā)高可用應(yīng)用程序中看到過了.

    我們使用下面的環(huán)境來執(zhí)行測試:
    https://www.digitalocean.com/為云
    兩臺Debian機器為RabbitMQ集群,如下所示:

    一個Debian機具有相同特征的java客戶端測試如下:
    Test 1: 使用下面的配置創(chuàng)建一個鏡像(正如在第7章,開發(fā)高可用應(yīng)用程序看到的),截圖如下:

    因此,集群會使用perf_ prefix來反射所有隊列.
    producer將使用下面的命令運行:
    java -cp rmqAckTest.jar rmqexample.ProducerMain 1 100000 640
    consumer使用下面的命令來運行:
    java -cp rmqAckTest.jar rmqexample.ConsumerMain 1 0 0 0
    clients通過perf_queue_08/03隊列來交換消息, 其性能如下所示:

    Test 2: 刪除HA策略并再次嘗試. 在這種情況下,其結(jié)果類似于下面的截圖:

    結(jié)論:通過使用小規(guī)模的消息,我們已經(jīng)放大了差異。對于更大的信息,由差異不太明顯. 在 Test 2中, 我們已經(jīng)觀察到比Test1每秒多了2000個消息,但同時也要看到,消息速率下降了,因為生產(chǎn)者快于消費者
    TIP
    作為通用規(guī)則,高可用性對性能有負面影響。所以,如果不具有強制性,最好把它關(guān)閉。

    在這個例子中,我們已經(jīng)嘗試了最高性能,也看到鏡像隊列的影響.如果我們需要一定程度的復(fù)制,但對鏡像要求不嚴格,那么可以使用shovel插件,或者簡單地通過并行的方式將消息發(fā)布到兩個獨立的broker上.
    在這個例子中,消息不是持久化的,且沒有使用tx事務(wù).

    TIP
    TX事務(wù)會扼殺性能,尤其是當你試圖提交每一條消息的時候,因為它會等待每條消息的磁盤刷新。
    更多
    由于在一個分布式應(yīng)用程序中有大量的可變因素,因此在性能和可靠性之間找到正確的折衷是非常困難的。
    一個典型的錯誤是試圖優(yōu)化每一個單個應(yīng)用程序流丟失的可擴展性或最終高可用性的好處。
    本章介紹了極端的情況下,但我們已經(jīng)看到,有改善的利潤率。

    也可參考
    性能是RabbitMQ郵件列表中非常熱門的話題。你可在http://rabbitmq.markmail.org/中找到很多有用的信息.

    posted on 2016-07-15 14:53 胡小軍 閱讀(9372) 評論(0)  編輯  收藏 所屬分類: RabbitMQ
    主站蜘蛛池模板: 18以下岁毛片在免费播放| 久青草视频97国内免费影视| 91香蕉国产线在线观看免费| 国产aⅴ无码专区亚洲av| 亚欧洲精品在线视频免费观看 | 精品国产免费人成电影在线观看 | 91福利免费网站在线观看| 亚洲综合色视频在线观看| 九九九国产精品成人免费视频| 亚洲一区二区三区无码影院| a级毛片免费观看网站| 久久影视综合亚洲| 免费高清国产视频| 亚洲人成网www| 成人无码区免费视频观看 | 亚洲综合无码AV一区二区| 久久美女网站免费| 亚洲午夜电影在线观看高清| 在线免费观看a级片| 免费一级做a爰片久久毛片潮| 国产偷窥女洗浴在线观看亚洲| 中文无码日韩欧免费视频| 亚洲精品高清视频| 成年性生交大片免费看| 免费激情网站国产高清第一页| 亚洲中文字幕无码一区二区三区 | 亚洲无线一二三四区手机| 野花香高清在线观看视频播放免费| 亚洲一区中文字幕久久| 免费电影在线观看网站| 日日狠狠久久偷偷色综合免费| 亚洲国产精品va在线播放| 国内免费高清在线观看| 未满十八私人高清免费影院| 久久久无码精品亚洲日韩蜜桃| 又粗又大又黑又长的免费视频| 美女视频黄频a免费大全视频| 亚洲伦理一区二区| 波多野结衣免费视频观看| 日本在线免费观看| 久久精品国产亚洲AV电影网|