0. 集群介绍
(1)集群的目标
• 高可用(High Availability),是当一台服务器停止服务后,对于业务及用户毫无影
响。 停止服务的原因可能由于网卡、路由器、机房、CPU负载过高、内存溢出、自
然灾害等不可预期的原因导致,在很多时候也称单点问题。
• 突破数据量限制,一台服务器不能储存大量数据,需要多台分担,每个存储一部分,
共同存储完整个集群数据。最好能做到互相备份,即使单节点故障,也能在其他节点
找到数据。
• 数据备份容灾,单点故障后,存储的数据仍然可以在别的地方拉起。
• 压力分担,由于多个服务器都能完成各自一部分工作,所以尽量的避免了单点压力的
存在
(2)集群的基础形式
1. MySql集群
(1)企业级方案
(2)本项目方案
(3)代码
一. Docker 安装模拟 MySQL 主从复制集群
1)下载 mysql 镜像
2)创建 Master 实例并启动
docker run -p 3307:3306 --name mysql-master \
-v /mydata/mysql/master/log:/var/log/mysql \
-v /mydata/mysql/master/data:/var/lib/mysql \
-v /mydata/mysql/master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
参数说明
-p 3307:3306: 将容器的 3306 端口映射到主机的 3307 端口
-v /mydata/mysql/master/conf:/etc/mysql: 将配置文件夹挂在到主机
-v /mydata/mysql/master/log:/var/log/mysql: 将日志文件夹挂载到主机
-v /mydata/mysql/master/data:/var/lib/mysql/: 将配置文件夹挂载到主机
-e MYSQL_ROOT_PASSWORD=root: 初始化 root 用户的密码
修改 master 基本配置
vim /mydata/mysql/master/conf/my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
注意: skip-name-resolve 一定要加, 不然连接 mysql 会超级慢
添加 master 主从复制部分配置
server_id=1
log-bin=mysql-bin
read-only=0
binlog-do-db=gulimall_ums
binlog-do-db=gulimall_pms
binlog-do-db=gulimall_oms
binlog-do-db=gulimall_sms
binlog-do-db=gulimall_wms
binlog-do-db=gulimall_admin
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
重启 master
3)创建 Slave 实例并启动
docker run -p 3317:3306 --name mysql-slaver-01 \
-v /mydata/mysql/slaver/log:/var/log/mysql \
-v /mydata/mysql/slaver/data:/var/lib/mysql \
-v /mydata/mysql/slaver/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
修改 slave 基本配置
vim /mydata/mysql/slaver/conf/my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
添加 master 主从复制部分配置
server_id=2
log-bin=mysql-bin
read-only=1
binlog-do-db=gulimall_ums
binlog-do-db=gulimall_pms
binlog-do-db=gulimall_oms
binlog-do-db=gulimall_sms
binlog-do-db=gulimall_wms
binlog-do-db=gulimall_admin
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
重启 slaver
4)为 master 授权用户来他的同步数据
1、 进入 master 容器
docker exec -it mysql /bin/bash
2、 进入 mysql 内部 (mysql –uroot -p)
1) 、 授权 root 可以远程访问( 主从无关, 为了方便我们远程连接 mysql)
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;
2) 、 添加用来同步的用户
GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456';
3、 查看 master 状态
show master status\G;
5)配置 slaver 同步 master 数据
1、 进入 slaver 容器
docker exec -it mysql-slaver-01 /bin/bash
2、 进入 mysql 内部(mysql –uroot -p)
1) 、 授权 root 可以远程访问( 主从无关, 为了方便我们远程连接 mysql)
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;
2) 、 设置主库连接
change master to
master_host='mysql-master.gulimall',master_user='backup',master_password='123456',mas
ter_log_file='mysql-bin.000003',master_log_pos=0,master_port=3306;
3) 、 启动从库同步
start slave;
4) 、 查看从库状态
show slave status\G;
6)总结:主从数据库在自己配置文件中声明需要同步哪个数据库, 忽略哪个数据库等信息。并且 server-id 不能一样;主库授权某个账号密码来同步自己的数据;从库使用这个账号密码连接主库来同步数据
二. MyCat 或者 ShardingSphere 实现代理和分片
shardingSphere:shardingSphere JDBC,shardingSphere Proxy
auto_increment_offset: 1 从几开始增长
auto_increment_increment: 2 每次的步长
1)下载安装 Sharding-Proxy
docker pull apache/sharding-proxy
docker run -d -v /mydata/sharding-proxy/conf:/opt/sharding-proxy/conf -v
/mydata/sharding-proxy/lib:/opt/sharding-proxy/lib --env PORT=3308 -p13308:3308
apache/sharding-proxy:latest
2)配置数据分片+读写分离
server.yaml
config-readwrite-splitting.yaml
config-sharding.yaml
schemaName: sharding_db
#
dataSources:
ds_0:
# url: jdbc:postgresql://127.0.0.1:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
# username: postgres
# password: postgres
# connectionTimeoutMilliseconds: 30000
# idleTimeoutMilliseconds: 60000
# maxLifetimeMilliseconds: 1800000
# maxPoolSize: 50
# minPoolSize: 1
# maintenanceIntervalMilliseconds: 30000
ds_1:
# url: jdbc:postgresql://127.0.0.1:3317/demo_ds_1?serverTimezone=UTC&useSSL=false
# username: postgres
# password: postgres
# connectionTimeoutMilliseconds: 30000
# idleTimeoutMilliseconds: 60000
# maxLifetimeMilliseconds: 1800000
# maxPoolSize: 50
# minPoolSize: 1
# maintenanceIntervalMilliseconds: 30000
######################################################################################################
#rules:
#- !SHARDING
# tables:
# t_order:
# actualDataNodes: ds_${0..1}.t_order_${0..1}
# tableStrategy:
# standard:
shardingColumn: order_id # 根据这个字段分表
shardingAlgorithmName: t_order_inline
keyGenerateStrategy: # 主键生成策略 #雪花算法
column: order_id
keyGeneratorName: snowflake
t_order_item:
# actualDataNodes: ds_${0..1}.t_order_item_${0..1}
# tableStrategy:
# standard:
shardingColumn: order_id # 这样这2个表就在一个库中了
shardingAlgorithmName: t_order_item_inline
# keyGenerateStrategy:
# column: order_item_id
# keyGeneratorName: snowflake
bindingTables:
- t_order,t_order_item
defaultDatabaseStrategy: # 分库
standard:
shardingColumn: user_id # 根据用户id分库
shardingAlgorithmName: database_inline
config-master_slave.yaml
dataSources:
# 2主2从
master_0_ds:
url: jdbc:postgresql://192.168.56.10:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
slave_ds_0:
url: jdbc:postgresql://192.168.56.10:3317/demo_ds_0?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
master_1_ds:
url: jdbc:postgresql://192.168.56.10:3307/demo_ds_1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
slave_ds_1:
url: jdbc:postgresql://192.168.56.10:3317/demo_ds_1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
# 2套主从规则
masterSlaveRule:
name: ms_ds1
masterDataSourceName: master_0_ds
slaveDataSourceNames:
- slave_ds_0
# 另放到一个文件在
# name: ms_ds2:
# masterDataSourceName: master_1_ds
# slaveDataSourceNames:
# - slave_ds_1
2. redis集群
(1)redis 集群形式
1.1)数据分区方案
1.1.1)客户端分区
客户端分区方案 的代表为 Redis Sharding, Redis Sharding 是 Redis Cluster 出来之前, 业
界普遍使用的 Redis 多实例集群 方法。 Java 的 Redis 客户端驱动库 Jedis, 支持 Redis Sharding 功能, 即 ShardedJedis 以及 结合缓存池 的 ShardedJedisPool。
优点:不使用 第三方中间件, 分区逻辑 可控, 配置 简单, 节点之间无关联, 容易 线性扩展, 灵活性强。
缺点:客户端 无法 动态增删 服务节点, 客户端需要自行维护 分发逻辑, 客户端之间 无连接共享,会造成 连接浪费。
1.1.2)代理分区
代理分区常用方案有 Twemproxy 和 Codis。
1.1.3)redis cluster (官方推荐,采用 hash + slot 算法)
1.2)高可用方案
1.2.1)Sentinel( 哨兵机制) 支持高可用
主要功能:
1)监控(Monitoring): 哨兵(sentinel) 会不断地检查你的 Master 和 Slave 是否运作正常。
2)提醒(Notification): 当被监控的某个 Redis 出现问题时, 哨兵(sentinel) 可以通过 API向管理员或者其他应用程序发送通知。
3)自动故障迁移(Automatic failover): 当主数据库出现故障时自动将从数据库转换为主数据库。
哨兵的原理:Redis 哨兵的三个定时任务, Redis 哨兵判定一个 Redis 节点故障不可达主要就是通过三个定时监控任务来完成的。
1)每隔 10 秒每个哨兵节点会向主节点和从节点发送"info replication" 命令来获取最新的拓扑结构
2)每隔 2 秒每个哨兵节点会向 Redis 节点的_sentinel_:hello 频道发送自己对主节点是否故障的判断以及自身的节点信息, 并且其他的哨兵节点也会订阅这个频道来了解其他哨兵节点的信息以及对主节点的判断
3)每隔 1 秒每个哨兵会向主节点、 从节点、 其他的哨兵节点发送一个 “ping” 命令来做心跳检测
1.2.2)redis-cluster
(2)Hash算法
1)hash + slot
cluster是多主多从,用了16384个哈希槽,可以根据性能将不同的槽位分配给redis实例
CRC16(key)%16383
缺点:客户端会随便连个redis,然后redis告诉客户端去哪个redis里找,客户端重新请求一遍;mset、mget等操作,多个key批量时只支持slot值相同的批量操作;事务支持有限。但是我们一般使用lua脚本。
2)consistent hash
一致性哈希:可以很好的解决 稳定性问题, 可以将所有的 存储节点 排列在 收尾相接的Hash 环上, 每个 key 在计算 Hash 后会 顺时针 找到 临接 的 存储节点 存放。 而当有节点 加入 或 退出 时, 仅影响该节点在 Hash 环上 顺时针相邻 的 后续节点。
Hash 倾斜:如果节点很少, 容易出现倾斜, 负载不均衡问题。 一致性哈希算法, 引入了虚拟节点, 在整个环上, 均衡增加若干个节点。 比如 a1, a2, b1, b2, c1, c2, a1 和 a2 都是属于 A 节点的。 解决 hash 倾斜问题。
(3)Redis-Cluster
Scaling with Redis Cluster | Redis Redis 的官方多机部署方案, Redis Cluster。 一组 Redis Cluster 是由多个 Redis 实例组成, 官
方推荐我们使用 6 实例, 其中 3 个为主节点, 3 个为从结点。 一旦有主节点发生故障的时候,
Redis Cluster 可以选举出对应的从结点成为新的主节点, 继续对外服务, 从而保证服务的高
可用性。那么对于客户端来说, 知道知道对应的 key 是要路由到哪一个节点呢? Redis Cluster
把所有的数据划分为 16384 个不同的槽位, 可以根据机器的性能把不同的槽位分配给不同
的 Redis 实例, 对于 Redis 实例来说, 他们只会存储部分的 Redis 数据, 当然, 槽的数据是
可以迁移的, 不同的实例之间, 可以通过一定的协议, 进行数据迁移。
(4)代码
1)创建 6 个 redis 节点(3 主 3 从方式, 从为了同步备份, 主进行 slot 数据分片)
for port in $(seq 7001 7006); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port ${port}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.56.10
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
appendonly yes
EOF
docker run -p ${port}:${port} -p 1${port}:1${port} --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d redis:5.0.7 redis-server /etc/redis/redis.conf; \
done
docker stop $(docker ps -a |grep redis-700 | awk '{ print $1}')
docker rm $(docker ps -a |grep redis-700 | awk '{ print $1}')
2)使用 redis 建立集群
docker exec -it redis-7001 bash
redis-cli --cluster create 192.168.56.10:7001 192.168.56.10:7002 192.168.56.10:7003
192.168.56.10:7004 192.168.56.10:7005 192.168.56.10:7006 --cluster-replicas 1
3. ES集群
(1)介绍
elasticsearch 是天生支持集群的, 他不需要依赖其他的服务发现和注册的组件, 因为他内置了一个名字叫 ZenDiscovery 的模块。
Elasticsearch: 权威指南 | Elastic
集群内的原理 | Elasticsearch: 权威指南 | Elastic
健康:
Elasticsearch 的集群监控信息中包含了许多的统计数据, 其中最为重要的一项就是 集群健
康 , 它在 status 字段中展示为 green 、 yellow 或者 red 。
status 字段指示着当前集群在总体上是否工作正常。 它的三种颜色含义如下:
green: 所有的主分片和副本分片都正常运行。
yellow: 所有的主分片都正常运行, 但不是所有的副本分片都正常运行。
red: 有主分片没能正常运行。
分片:
在索引建立的时候就已经确定了主分片数, 但是副本分片数可以随时修改。
一份数据的多个副本存在不同分片上,分片要有一定冗余。
(2)代码
1)准备 docker 网络
Docker 创建容器时默认采用 bridge 网络,自行分配 ip,不允许自己指定。
在实际部署中, 我们需要指定容器 ip, 不允许其自行分配 ip, 尤其是搭建集群时, 固定 ip 是必须的。
我们可以创建自己的 bridge 网络 : mynet, 创建容器的时候指定网络为 mynet 并指定 ip 即可。
查看网络模式 docker network ls;
创建一个新的 bridge 网络
docker network create --driver bridge --subnet=172.18.12.0/16 --gateway=172.18.1.1
mynet
查看网络信息
docker network inspect mynet
以后使用--network=mynet --ip 172.18.12.x 指定 ip
2)Master 节点创建
for port in $(seq 1 3); \
do \
mkdir -p /mydata/elasticsearch/master-${port}/config
mkdir -p /mydata/elasticsearch/master-${port}/data
chmod -R 777 /mydata/elasticsearch/master-${port}
cat << EOF >/mydata/elasticsearch/master-${port}/config/elasticsearch.yml
cluster.name: my-es #集群的名称, 同一个集群该值必须设置成相同的
node.name: es-master-${port} #该节点的名字
node.master: true #该节点有机会成为 master 节点
node.data: false #该节点可以存储数据
network.host: 0.0.0.0
http.host: 0.0.0.0 #所有 http 均可访问
http.port: 920${port}
transport.tcp.port: 930${port}
#discovery.zen.minimum_master_nodes: 2 #设置这个参数来保证集群中的节点可以知道其
它 N 个有 master 资格的节点。 官方推荐(N/2) +1
discovery.zen.ping_timeout: 10s #设置集群中自动发现其他节点时 ping 连接的超时时间
discovery.seed_hosts: ["172.18.12.21:9301", "172.18.12.22:9302", "172.18.12.23:9303"] #设置集
群中的 Master 节点的初始列表, 可以通过这些节点来自动发现其他新加入集群的节点, es7
的新增配置
cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始时的候选主节点, es7 的新增配置
EOF
docker run --name elasticsearch-node-${port} \
-p 920${port}:920${port} -p 930${port}:930${port} \
--network=mynet --ip 172.18.12.2${port} \
-e ES_JAVA_OPTS="-Xms300m -Xmx300m" \
-v
/mydata/elasticsearch/master-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/el
asticsearch.yml \
-v /mydata/elasticsearch/master-${port}/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/master-${port}/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
done
docker stop $(docker ps -a |grep elasticsearch-node-* | awk '{ print $1}')
docker rm $(docker ps -a |grep elasticsearch-node-* | awk '{ print $1}')
3)Data-Node 创建
for port in $(seq 4 6); \
do \
mkdir -p /mydata/elasticsearch/node-${port}/config
mkdir -p /mydata/elasticsearch/node-${port}/data
chmod -R 777 /mydata/elasticsearch/node-${port}
cat << EOF >/mydata/elasticsearch/node-${port}/config/elasticsearch.yml
cluster.name: my-es #集群的名称, 同一个集群该值必须设置成相同的
node.name: es-node-${port} #该节点的名字
node.master: false #该节点有机会成为 master 节点
node.data: true #该节点可以存储数据
network.host: 0.0.0.0
#network.publish_host: 192.168.56.10 #互相通信 ip, 要设置为本机可被外界访问的 ip, 否则
无法通信
http.host: 0.0.0.0 #所有 http 均可访问
http.port: 920${port}
transport.tcp.port: 930${port}
#discovery.zen.minimum_master_nodes: 2 #设置这个参数来保证集群中的节点可以知道其
它 N 个有 master 资格的节点。 官方推荐(N/2) +1
discovery.zen.ping_timeout: 10s #设置集群中自动发现其他节点时 ping 连接的超时时间
discovery.seed_hosts: ["172.18.12.21:9301", "172.18.12.22:9302", "172.18.12.23:9303"] #设置集
群中的 Master 节点的初始列表, 可以通过这些节点来自动发现其他新加入集群的节点, es7
的新增配置
cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始时的候选主节点, es7 的新增配置
EOF
docker run --name elasticsearch-node-${port} \
-p 920${port}:920${port} -p 930${port}:930${port} \
--network=mynet --ip 172.18.12.2${port} \
-e ES_JAVA_OPTS="-Xms300m -Xmx300m" \
-v
/mydata/elasticsearch/node-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/ela
sticsearch.yml \
-v /mydata/elasticsearch/node-${port}/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/node-${port}/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
done
4. RabbitMQ
(1)介绍
RabbiMQ 是用 Erlang 开发的, 集群非常方便, 因为 Erlang 天生就是一门分布式语言, 但其
本身并不支持负载均衡。RabbitMQ 集群中节点包括内存节点(RAM)、 磁盘节点(Disk, 消息持久化), 集群中至少有一个 Disk 节点。
(2)集群形式
1)普通模式(默认)
对于普通模式, 集群中各节点有相同的队列结构, 但消息只会存在于集群中的一个节点。 对于消费者来说, 若消息进入 A 节点的 Queue 中, 当从 B 节点拉取时, RabbitMQ 会将消息从 A 中取出, 并经过 B 发送给消费者。应用场景: 该模式各适合于消息无需持久化的场合, 如日志队列。 当队列非持久化, 且创建该队列的节点宕机, 客户端才可以重连集群其他节点, 并重新创建队列。 若为持久化,只能等故障节点恢复。
2)镜像模式
与普通模式不同之处是消息实体会主动在镜像节点间同步, 而不是在取数据时临时拉取, 高可用; 该模式下, mirror queue 有一套选举算法, 即 1 个 master、 n 个 slaver, 生产者、 消费者的请求都会转至 master。应用场景: 可靠性要求较高场合, 如下单、 库存队列。缺点: 若镜像队列过多, 且消息体量大, 集群内部网络带宽将会被此种同步通讯所消耗。
镜像集群也是基于普通集群, 即只有先搭建普通集群, 然后才能设置镜像队列。若消费过程中, master 挂掉, 则选举新 master, 若未来得及确认, 则可能会重复消费。
(3)代码
1)搭建集群
mkdir /mydata/rabbitmq
cd rabbitmq/
mkdir rabbitmq01 rabbitmq02 rabbitmq03
docker run -d --hostname rabbitmq01 --name rabbitmq01 -v
/mydata/rabbitmq/rabbitmq01:/var/lib/rabbitmq -p 15673:15672 -p 5673:5672 -e
RABBITMQ_ERLANG_COOKIE='atguigu' rabbitmq:management
docker run -d --hostname rabbitmq02 --name rabbitmq02 -v/mydata/rabbitmq/rabbitmq02:/var/lib/rabbitmq -p 15674:15672 -p 5674:5672 -e
RABBITMQ_ERLANG_COOKIE='atguigu' --link rabbitmq01:rabbitmq01
rabbitmq:management
docker run -d --hostname rabbitmq03 --name rabbitmq03 -v
/mydata/rabbitmq/rabbitmq03:/var/lib/rabbitmq -p 15675:15672 -p 5675:5672 -e
RABBITMQ_ERLANG_COOKIE='atguigu' --link rabbitmq01:rabbitmq01 --link
rabbitmq02:rabbitmq02 rabbitmq:management
--hostname 设置容器的主机名
RABBITMQ_ERLANG_COOKIE 节点认证作用, 部署集成时 需要同步该值
2)节点加入集群
docker exec -it rabbitmq01 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
Exit
进入第二个节点
docker exec -it rabbitmq02 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit
进入第三个节点
docker exec -it rabbitmq03 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit
3)实现镜像集群
docker exec -it rabbitmq01 bash标签:atguigu8,mydata,port,master,mysql,集群,节点 From: https://blog.51cto.com/u_15905340/5919895
rabbitmqctl set_policy -p / ha "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
可以使用 rabbitmqctl list_policies -p /; 查看 vhost/下面的所有 policy
在 cluster 中任意节点启用策略, 策略会自动同步到集群节点
rabbitmqctl set_policy-p/ha-all"^"’{“ha-mode”:“all”}’
策略模式 all 即复制到所有节点, 包含新增节点, 策略正则表达式为 “^” 表示所有匹配所有队列名称。 “^hello”表示只匹配名为 hello 开始的队列