目录
本文利用一台Linux示范三节点RabbitMQ集群。RabbitMQ版本:3.12.11.
重点:
.erlang.cookie是erlang框架实现分布式的必要文件。三节点集群需要每个节点的.erlang.cookie文件相同。文件的位置:$home/.erlang.cookie.
erlang安装之后文件就已经存在,如果使用三台不同的机器,需要将其中一台的文件拷贝三份。用一台机器做示范,我们不需要再做额外的动作。
RabbitMQ的nodename有固定的格式
如果是部署在不同的机器上,所有的hostname需要明确配置在/etc/hosts文件中。
nodename配置在rabbitmq-env.conf文件中。
部署在同一台机器上,需要解决三个端口的冲突。
信息要放在enabled_plugin文件中。这个文件要手工添加,插件在RabbitMQ第一次启动的时候初始化。
高可用需要同一条消息要同时复制到三个节点上面,这样应用连接的当前节点下线后,还可以从其它另外两个节点读取还未消费完的消息。没有replica,虽然Rabbitmq依然可用,但会有消息丢失的情况。
要实现消息node间复制,需要创建Queue的时候, queue type设置成Quorum。
两种方式:

- Map QUEUE_ARGS = new HashMap
(); - QUEUE_ARGS.put("x-queue-type", "quorum");
-
- new Queue("queue_name", true, false, false, QUEUE_ARGS);
对于匿名Queue不能配置这个属性,当一个node down以后,应用会在新的节点重新创建临时Queue。可能产生message丢失的情况。
在rabbitmq.conf中配置,两种client-local(by default)和balanced.
Download rabbitmq package, rabbitmq-server-generic-unix-3.12.11.tar.xz. 解压后拷贝三份,作为三个node。
下面的文件除了.erlang.cookie都需要手动添加。
/opt/rabbitmq/rabbitmq-node-1
$home/.erlang.cookie
File path: /opt/rabbitmq/rabbitmq-node-1/etc/rabbitmq/rabbitmq-env.conf
- # Example rabbitmq-env.conf file entries. Note that the variables
- # do not have the RABBITMQ_ prefix.
- #
- # Overrides node name
- RABBITMQ_NODENAME=rabbitmq-node-1@DESKTOP-B5WANG
-
- # Specifies new style config file location
- RABBITMQ_CONFIG_FILE=/opt/rabbitmq/rabbitmq-node-1/etc/rabbitmq/rabbitmq.conf
-
- # Specifies advanced config file location
- # RABBITMQ_ADVANCED_CONFIG_FILE=/etc/rabbitmq/advanced.config
-
- # CLI port
- RABBITMQ_DIST_PORT=25672
File path: /opt/rabbitmq/rabbitmq-node-1/etc/rabbitmq/rabbitmq.conf
- # port
- listeners.tcp.default = 5672
- # listeners.tcp.1 = 0.0.0.0:5672
-
- # default user
- default_vhost = /
- default_user = admin
- default_pass = admin
- default_permissions.configure = .*
- default_permissions.read = .*
- default_permissions.write = .*
- default_user_tags.administrator = true
- default_user_tags.management = true
- default_user_tags.custom_tag = true
-
- # management plugin
- management.tcp.port = 15672
- management.tcp.ip = 0.0.0.0
-
- # cluster
- cluster_name = rabbitmq-cluster
- cluster_keepalive_interval = 10000
- cluster_formation.peer_discovery_backend = classic_config
- cluster_formation.classic_config.nodes.1 = rabbitmq-node-1@DESKTOP-B5WANG
- cluster_formation.classic_config.nodes.2 = rabbitmq-node-2@DESKTOP-B5WANG
- cluster_formation.classic_config.nodes.3 = rabbitmq-node-3@DESKTOP-B5WANG
-
- # queue location strategy
- queue_master_locator = client-local
File path: /opt/rabbitmq/rabbitmq-node-1/etc/rabbitmq/enabled_plugins
[rabbitmq_management].
/opt/rabbitmq/rabbitmq-node-2
$home/.erlang.cookie
File path: /opt/rabbitmq/rabbitmq-node-2/etc/rabbitmq/rabbitmq-env.conf
- # Example rabbitmq-env.conf file entries. Note that the variables
- # do not have the RABBITMQ_ prefix.
- #
- # Overrides node name
- RABBITMQ_NODENAME=rabbitmq-node-2@DESKTOP-B5WANG
-
- # Specifies new style config file location
- RABBITMQ_CONFIG_FILE=/opt/rabbitmq/rabbitmq-node-2/etc/rabbitmq/rabbitmq.conf
-
- # Specifies advanced config file location
- # RABBITMQ_ADVANCED_CONFIG_FILE=/etc/rabbitmq/advanced.config
-
- # CLI port
- RABBITMQ_DIST_PORT=25673
File path: /opt/rabbitmq/rabbitmq-node-2/etc/rabbitmq/rabbitmq.conf
- # port
- listeners.tcp.default = 5673
- # listeners.tcp.1 = 0.0.0.0:5673
-
- # default user
- default_vhost = /
- default_user = admin
- default_pass = admin
- default_permissions.configure = .*
- default_permissions.read = .*
- default_permissions.write = .*
- default_user_tags.administrator = true
- default_user_tags.management = true
- default_user_tags.custom_tag = true
-
- # management plugin
- management.tcp.port = 15673
- management.tcp.ip = 0.0.0.0
-
- # cluster
- cluster_name = rabbitmq-cluster
- cluster_keepalive_interval = 10000
- cluster_formation.peer_discovery_backend = classic_config
- cluster_formation.classic_config.nodes.1 = rabbitmq-node-1@DESKTOP-B5WANG
- cluster_formation.classic_config.nodes.2 = rabbitmq-node-2@DESKTOP-B5WANG
- cluster_formation.classic_config.nodes.3 = rabbitmq-node-3@DESKTOP-B5WANG
-
- # queue location strategy
- queue_master_locator = client-local
File path: /opt/rabbitmq/rabbitmq-node-2/etc/rabbitmq/enabled_plugins
[rabbitmq_management].
/opt/rabbitmq/rabbitmq-node-3
$home/.erlang.cookie
File path: /opt/rabbitmq/rabbitmq-node-3/etc/rabbitmq/rabbitmq-env.conf
- # Example rabbitmq-env.conf file entries. Note that the variables
- # do not have the RABBITMQ_ prefix.
- #
- # Overrides node name
- RABBITMQ_NODENAME=rabbitmq-node-3@DESKTOP-B5WANG
-
- # Specifies new style config file location
- RABBITMQ_CONFIG_FILE=/opt/rabbitmq/rabbitmq-node-3/etc/rabbitmq/rabbitmq.conf
-
- # Specifies advanced config file location
- # RABBITMQ_ADVANCED_CONFIG_FILE=/etc/rabbitmq/advanced.config
-
- # CLI port
- RABBITMQ_DIST_PORT=25674
File path: /opt/rabbitmq/rabbitmq-node-3/etc/rabbitmq/rabbitmq.conf
- # port
- listeners.tcp.default = 5674
- # listeners.tcp.1 = 0.0.0.0:5674
-
- # default user
- default_vhost = /
- default_user = admin
- default_pass = admin
- default_permissions.configure = .*
- default_permissions.read = .*
- default_permissions.write = .*
- default_user_tags.administrator = true
- default_user_tags.management = true
- default_user_tags.custom_tag = true
-
- # management plugin
- management.tcp.port = 15674
- management.tcp.ip = 0.0.0.0
-
- # cluster
- cluster_name = rabbitmq-cluster
- cluster_keepalive_interval = 10000
- cluster_formation.peer_discovery_backend = classic_config
- cluster_formation.classic_config.nodes.1 = rabbitmq-node-1@DESKTOP-B5WANG
- cluster_formation.classic_config.nodes.2 = rabbitmq-node-2@DESKTOP-B5WANG
- cluster_formation.classic_config.nodes.3 = rabbitmq-node-3@DESKTOP-B5WANG
-
- # queue location strategy
- queue_master_locator = client-local
File path: /opt/rabbitmq/rabbitmq-node-3/etc/rabbitmq/enabled_plugins
[rabbitmq_management].
- spring:
- rabbitmq:
- # Connect rabbitmq cluster
- addresses: localhost:5672,localhost:5673,localhost:5674
- username: admin
- password: admin
- Map arg = new HashMap
(); - arg.put("x-queue-type", "quorum");
- arg.put("x-queue-leader-locator", "client-local");
- new Queue(QUEUE_NAME_TEXT_MESSAGE, true, false, false, arg);
AnonymousQueue aq = new AnonymousQueue(new Base64UrlNamingStrategy("queue-prefix-"));
AnonymousQueue本质上还是Queue,只是属性不同。所以不需要配置quorum,否则应用会报错。
- public class AnonymousQueue extends Queue {
- public AnonymousQueue() {
- this((Map)null);
- }
-
- public AnonymousQueue(Map
arguments) { - this(Base64UrlNamingStrategy.DEFAULT, arguments);
- }
-
- public AnonymousQueue(NamingStrategy namingStrategy) {
- this(namingStrategy, (Map)null);
- }
-
- public AnonymousQueue(NamingStrategy namingStrategy, Map
arguments) { - super(namingStrategy.generateName(), false, true, true, arguments);
- if (!this.getArguments().containsKey("x-queue-master-locator")) {
- this.setLeaderLocator("client-local");
- }
-
- }
- }