記事ディレクトリ
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
-
起動が完了したら、Web ページで ip:15672 アクセスを開いて正常かどうかを確認します。
-
ユーザー: 管理者
-
パスワード: 管理者
-
それでもアクセスできない場合は、サーバーのファイアウォールが対応するポートを開いているかどうかを確認してください。
-
サーバーのファイアウォールがポートを開くと、まだアクセスできませんが、コンテナーに入り、rabbitMQ サービスを開始できます。
docker exec -it myrabbit1 bash
rabbitmqctl start_app
知らせ:
- Rabbitmq の Cookie も一貫している必要があります。そうでないと、クラスター関係を確立できません。
- 別のサーバー上にある場合は、-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 に置き換えます。他の手順はスタンドアロン展開方法と同様です。