単一サーバー Docker で RabbitMQ クラスターを構築する方法

1.この記事には同じサーバー上に異なる Docker コンテナがあり、各コンテナには独自の Rabbitmq サービスがあります
2.ここでは 3 つの Docker のデモを示します (15672 がマスター ノード、15673 と 15674 がスレーブ ノード)

1. 複数の RabbitMQ コンテナを作成する

1. 15672 個のマスター ノード コンテナーを作成する

docker run -d --hostname rabbitmq1 --name myrabbit1 -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:management

2. 15673 個のスレーブ ノード 1 コンテナを作成します

ポート 15673、-p 5673:5672 -p 15673:15672 に注目してください。

docker run -d --hostname rabbitmq2 --name myrabbit2 -p 5673:5672 -p 15673:15672 --link myrabbit1:rabbit1 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:management

3. 15674 スレーブ ノード 2 コンテナ 1 を作成します。

docker run -d --hostname rabbitmq3 --name myrabbit3 -p 5674:5672 -p 15674:15672 --link myrabbit1:rabbit1 --link myrabbit2:rabbit2 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:management

パラメータの説明:

-d 容器后台运行

--hostname rabbitmq1 容器的主机名为 rabbitmq1,到时候从节点进行绑定的时候,需要根据这个节点名进行映射

--name myrabbit1 容器名为myrabbit1 ,在宿主机上运行“docker ps”命令时显示的名称

-p "5672:5672" 消息通讯端口,容器端口:宿主机端口

-p "15672:15672" 后台管理端口

--link  myrabbit1:rabbit1 (必须)容器互通,相当于myrabbit2 ping 成功 myrabbit1

-e RABBITMQ_DEFAULT_USER=admin 设置rabbitmq默认用户为admin

-e RABBITMQ_DEFAULT_PASS=admin 设置rabbitmq默认密码为admin

-e RABBITMQ_ERLANG_COOKIE='rabbitcookie' 设置rabbitmq的cookie为“rabbitcookie”,可以自定义为其他文本,容器保持一致即可

--add-host="rabbitmq1":192.168.12.186  (可选)修改容器内部的hosts名,即rabbitmq1对应该ip

--restart=unless-stopped docker (可选)容器重启后重启MQ
  1. 起動が完了したら、Web ページで ip:15672 アクセスを開いて正常かどうかを確認します。

  2. ユーザー: 管理者

  3. パスワード: 管理者

  4. それでもアクセスできない場合は、サーバーのファイアウォールが対応するポートを開いているかどうかを確認してください。

  5. サーバーのファイアウォールがポートを開くと、まだアクセスできませんが、コンテナーに入り、rabbitMQ サービスを開始できます。

docker exec -it myrabbit1 bash
rabbitmqctl start_app

ここに画像の説明を挿入

知らせ:

  1. Rabbitmq の Cookie も一貫している必要があります。そうでないと、クラスター関係を確立できません。
  2. 別のサーバー上にある場合は、-add-host の後のパラメーターに対応する IP を忘れずに入力してください。

2. RabbitMQ ノードをクラスターに追加します

1. 15672 マスターノードコンテナ

# 命令行的形式进入myrabbit1容器
docker exec -it myrabbit1 bash
#停止当前的MQ
rabbitmqctl stop_app
#目的是清除节点上的历史数据(如果不清除,无法将节点加入到集群)
rabbitmqctl reset
#启动应用
rabbitmqctl start_app
exit

2. 15673 スレーブノード 1 コンテナ

# 命令行的形式进入myrabbit2容器
docker exec -it myrabbit2 bash
#首先停止当前MQ
rabbitmqctl stop_app
rabbitmqctl reset
#将rabbitmq2节点加入到rabbitmq1(主节点)集群当中【rabbitmq1服务器的主机名】
rabbitmqctl join_cluster --ram rabbit@rabbitmq1
#重新启动MQ
rabbitmqctl start_app
# 退出容器
exit
#按下CTRL+Q+P 不停止运行,退出容器

3. 15674 スレーブノード 2 コンテナ

docker exec -it myrabbit3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq1
rabbitmqctl start_app
exit

3. テスト

1. マスターノード、IP: 15672 にログインします。

ここに画像の説明を挿入

2. マスターノード15672にスイッチを作成します。

ここに画像の説明を挿入

3. スレーブノード 15673 にもスイッチがあることがわかります。

ここに画像の説明を挿入

4. 受付15673からキューを作成し、メッセージを送信する

ここに画像の説明を挿入

5. マスターノード 15672 がメッセージを受信します。

ここに画像の説明を挿入

6. クラスターのステータスを確認する

root@rabbitmq1:/# rabbitmqctl cluster_status -n rabbit@rabbitmq1
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
Cluster status of node rabbit@rabbitmq1 ...
Basics

Cluster name: rabbit@rabbitmq1

Disk Nodes

rabbit@rabbitmq1

RAM Nodes

rabbit@rabbitmq2
rabbit@rabbitmq3

Running Nodes

rabbit@rabbitmq1
rabbit@rabbitmq2
rabbit@rabbitmq3

Versions

rabbit@rabbitmq1: RabbitMQ 3.9.11 on Erlang 24.2
rabbit@rabbitmq2:   on Erlang 
rabbit@rabbitmq3:   on Erlang 
......

ここまでで、単一サーバーの docker による Rabbitmq クラスターの構築が完了しました。

4. RabbitMQ クラスターを複数のサーバーにデプロイする

RabbitMQ は Erlang を介して実装されているため、Erlang Cookie は異なるノード間の相互通信の秘密鍵に相当し、Erlang ノードは Erlang Cookie を交換することで認証を取得します。

1. RabbitMQ コンテナ起動ログのホーム ディレクトリ パスをルート パスとして使用して、Erlang Cookie の場所を取得します。表示するには「docker logs コンテナ名/ID」を使用します。したがって、Erlang Cookie のフルパスは「/var/lib/rabbitmq/.erlang.cookie」になります。

2. Erlang Cookie を他の RabbitMQ ノードにコピーする

いずれかのノードの Cookie を読み取り、それを他のノードにコピーする必要があります (ノードは Cookie を使用して、相互に通信できるかどうかを判断します)。Cookie は /var/lib/rabbitmq/.erlang.cookie に保存されます。つまり、そのうちの 1 つのサーバーの .erlang.cookie を他のサーバーの .erlang.cookie に置き換えます。他の手順はスタンドアロン展開方法と同様です。

  • ホストとコンテナーの間でコピーするコマンドは次のとおりです。
    • コンテナはファイルをホストにコピーします: docker cp コンテナ名: コンテナ ディレクトリ 物理マシン ディレクトリ
    • ホストからコンテナにファイルをコピーします: docker cp 物理マシン ディレクトリ コンテナ名: コンテナ ディレクトリ
  • Erlang Cookie ファイルのアクセス許可を「chmod 600 /var/lib/rabbitmq/.erlang.cookie」に設定します。

3. ノードをクラスターに追加し、--add-host パラメーターを追加します。

5. nginx による負荷分散の実装

ここでは、負荷分散サーバーとして別のサーバーを見つけ、nginx 構成ファイルを保存するフォルダーをサービス上に作成する必要があります: /home/nginx/nginx_rabbitmq.conf
ファイルの内容:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    
    
    worker_connections  1024;
}


http {
    
    
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
	
	proxy_redirect          off;
	proxy_set_header        Host $host;
	proxy_set_header        X-Real-IP $remote_addr;
	proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
	client_max_body_size    10m;
	client_body_buffer_size   128k;
	proxy_connect_timeout   5s;
	proxy_send_timeout      5s;
	proxy_read_timeout      5s;
	proxy_buffer_size        4k;
	proxy_buffers           4 32k;
	proxy_busy_buffers_size  64k;
	proxy_temp_file_write_size 64k;
	#rabbitmq管理界面
	upstream rabbitManage {
    
     # 负载均衡配置,默认轮询,将客户的请求,平均分摊到下面的服务器上
		server ip1主:15672;
		server ip2从:15672;
		server ip3从:15672;
	}
	server {
    
    
        listen       15673;
        server_name  ip_nginx;  # 负载均衡服务器Ip
        location / {
    
      
            proxy_pass   http://rabbitManage;
            index  index.html index.htm;  
        }  
    }
}
# rabbitmq通信
stream{
    
    
	upstream rabbitTcp{
    
    
        server ip1主:5672;
        server ip2从:5672;
        server ip3从:5672;
    }

    server {
    
    
        listen       5673;
        server_name  ip_nginx;  # 负载均衡服务器Ip 
        location / {
    
      
            proxy_pass   http://rabbitTcp;
            index  index.html index.htm;  
        } 
    }
}

設定後に nginx を起動します。

docker run -it -d --name nginxMQ -v /home/nginx/nginx_rabbitmq.conf:/etc/nginx/nginx.conf  --privileged --net=host nginx

起動完了後、ロードのアドレスを使用してMQ
バックグラウンドアドレス: ip_nginx:15673
通信アドレス: ip_nginx:5673に一律にアクセスします。

6. RabbitMQ コンテナにユーザーを追加する方法

スーパー管理者の役割と権限を持つユーザー名テスト、パスワードテストをここに追加します

rabbitmqctl -n rabbit@rabbitmq1 add_user test test
rabbitmqctl -n rabbit@rabbitmq1 set_user_tags test administrator
rabbitmqctl -n rabbit@rabbitmq1 set_permissions -p / test ".*" ".*" ".*"

7. 発生した問題

Rabbitmq1 上の epmd (ポート 4369) に接続できません: nxdomain (存在しないドメイン)

理由: Rabbitmq1 ホスト名を解決できません

詳細なエラー内容
[root@rabbitmq2 ~]# Rabbitmqctl join_cluster Rabbit@rabbitmq1

Clustering node rabbit@rabbitmq2 with rabbit@rabbitmq1
Error: unable to perform an operation on node 'rabbit@rabbitmq1'. Please see diagnostics information and suggestions below.

Most common reasons for this are:

 * Target node is unreachable (e.g. due to hostname resolution, TCP connection or firewall issues)
 * CLI tool fails to authenticate with the server (e.g. due to CLI tool's Erlang cookie not matching that of the server)
 * Target node is not running

In addition to the diagnostics info below:

 * See the CLI, clustering and networking guides on https://rabbitmq.com/documentation.html to learn more
 * Consult server logs on node rabbit@rabbitmq1
 * If target node is configured to use long node names, don't forget to use --longnames with CLI tools

DIAGNOSTICS
===========

attempted to contact: ['rabbit@rabbitmq1']

rabbit@rabbitmq1:
  * unable to connect to epmd (port 4369) on vm-246: nxdomain (non-existing domain)


Current node details:
 * node name: 'rabbitmqcli-11445-rabbit@rabbitmq2'
 * effective user's home directory: /var/lib/rabbitmq
 * Erlang cookie hash: NhgpfPAyGCfXaw13WdYU9w==

解決

vim /etc/hosts に、各サーバーの IP とコンテナーのホスト名、つまり hostname を追加します。

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
ip1主 rabbitmq1
ip2从 rabbitmq2
ip3从 rabbitmq3

注: これを追加しないでくださいrabbit@。たとえば、以前に ip1 master Rabbit@rabbitmq1 を作成しました。

まとめ

マルチマシン展開方式を採用する場合、いずれかのノードの Cookie を読み取って他のノードにコピーする必要があります (ノードは Cookie を使用して、相互に通信できるかどうかを判断します)。Cookie は /var/lib/rabbitmq/.erlang.cookie に保存されます。つまり、そのうちの 1 つのサーバーの .erlang.cookie を他のサーバーの .erlang.cookie に置き換えます。他の手順はスタンドアロン展開方法と同様です。

おすすめ

転載: blog.csdn.net/qq_44231797/article/details/125965826