7

我試圖從SQS轉移到RabbitMQ以進行消息傳遞服務。我期待構建一個穩定的高可用性排隊服務。現在我要和集羣一起去。如何設置自動縮放RabbitMQ集羣AWS

當前實現, 我有安裝在AMI管理插件的RabbitMQ 3噸EC2的機器,然後我明確到每個機器,並添加

sudo rabbitmqctl join_cluster [email protected]<hostnameOfParentMachine> 

隨着HA屬性設置爲所有並且同步起作用。並在負載平衡器上面分配一個DNS。到目前爲止,這件事情有效

預期實現:創建一個自動縮放羣集環境,其中上/下行的機器必須動態地加入/移除羣集。達到此目的的最佳方法是什麼?請幫忙。

+0

基於的自動縮放? CloudWatch的? – Gabriele

+0

是的。但是,縮放後的實例必須自動加入羣集。 – Karthik

+1

小心 - 集羣模式下的Erlang不能容忍網絡分區(包括微分區),並且可能會導致一些問題;我在AWS上定期使用微分區來降低集羣的性能。我建議在投入生產之前先運行暫存集羣一段時間。 –

回答

11

2年前我有類似的配置。

我決定使用amazon VPC,默認情況下,我的設計有兩個RabbitMQ實例始終運行,並在集羣中配置(稱爲主節點)。 rabbitmq集羣位於internal amazon load balancer之後。

我創建了一個配置了RabbitMQ和管理插件的AMI(稱爲「master-AMI」),然後我配置了自動縮放規則。

如果發生自動調節報警,則啓動新的主AMI。 這AMI執行後續的腳本執行的第一次:

#!/usr/bin/env python 
import json 
import urllib2,base64 

if __name__ == '__main__': 
    prefix ='' 
    from subprocess import call 
    call(["rabbitmqctl", "stop_app"]) 
    call(["rabbitmqctl", "reset"]) 
    try: 
     _url = 'http://internal-myloadbalamcer-xxx.com:15672/api/nodes' 
     print prefix + 'Get json info from ..' + _url 
     request = urllib2.Request(_url) 

     base64string = base64.encodestring('%s:%s' % ('guest', 'guest')).replace('\n', '') 
     request.add_header("Authorization", "Basic %s" % base64string) 
     data = json.load(urllib2.urlopen(request)) 
     ##if the script got an error here you can assume that it's the first machine and then 
     ## exit without controll the error. Remember to add the new machine to the balancer 
     print prefix + 'request ok... finding for running node' 


     for r in data: 
      if r.get('running'): 
       print prefix + 'found running node to bind..' 
       print prefix + 'node name: '+ r.get('name') +'- running:' + str(r.get('running')) 
       from subprocess import call 
       call(["rabbitmqctl", "join_cluster",r.get('name')]) 
       break; 
     pass 
    except Exception, e: 
     print prefix + 'error during add node' 
    finally: 
     from subprocess import call 
     call(["rabbitmqctl", "start_app"]) 


    pass 

腳本使用HTTP API「http://internal-myloadbalamcer-xxx.com:15672/api/nodes」找到節點,然後選擇一個,並結合新的AMI到集羣。

由於HA的政策,我決定用這個:

rabbitmqctl set_policy ha-two "^two\."^
    "{""ha-mode"":""exactly"",""ha-params"":2,"ha-sync-mode":"automatic"}" 

好了,加入「非常」容易,問題是決定時,你可以從集羣中刪除節點。

您不能根據自動縮放規則刪除節點,因爲您可以將消息發送到必須使用的隊列。

我決定執行腳本週期性地運行於兩個主節點實例是:

  • 檢查消息通過API計數http://node:15672/api/queues
  • 如果消息計數所有隊列是零,我可以從負載均衡器中刪除實例,然後從rabbitmq集羣中刪除實例。

這大致是我所做的,希望它有幫助。

[編輯]

我編輯的答案,因爲有這個插件,可以幫助:

我建議看看這個:https://github.com/rabbitmq/rabbitmq-autocluster

該插件已被移動官方RabbitMQ存儲庫,並可以輕鬆解決這類問題

+0

你的劇本就像一個魅力!萬分感謝 。關於使用基於存儲器利用率的自動縮放策略(即<40%)從負載均衡器離開節點。 – Karthik

+0

我能夠通過自定義度量標準爲內存做到這一點,根據自定義指標的aws文檔。感謝代碼。 – Karthik

+3

是不是集羣點,因爲您可以刪除節點,因爲數據在節點之間複製? – Volte