• atguigu8 集群


    0. 集群介绍

    (1)集群的目标

    • 高可用(High Availability),是当一台服务器停止服务后,对于业务及用户毫无影
    响。 停止服务的原因可能由于网卡、路由器、机房、CPU负载过高、内存溢出、自
    然灾害等不可预期的原因导致,在很多时候也称单点问题。
    • 突破数据量限制,一台服务器不能储存大量数据,需要多台分担,每个存储一部分,
    共同存储完整个集群数据。最好能做到互相备份,即使单节点故障,也能在其他节点
    找到数据。
    • 数据备份容灾,单点故障后,存储的数据仍然可以在别的地方拉起。
    • 压力分担,由于多个服务器都能完成各自一部分工作,所以尽量的避免了单点压力的
    存在

    (2)集群的基础形式

    1. MySql集群

    (1)企业级方案

    (2)本项目方案

     (3)代码

    一. Docker 安装模拟 MySQL 主从复制集群

    1)下载 mysql 镜像

    2)创建 Master 实例并启动

    1. docker run -p 3307:3306 --name mysql-master \
    2. -v /mydata/mysql/master/log:/var/log/mysql \
    3. -v /mydata/mysql/master/data:/var/lib/mysql \
    4. -v /mydata/mysql/master/conf:/etc/mysql \
    5. -e MYSQL_ROOT_PASSWORD=root \
    6. -d mysql:5.7
    7. 参数说明
    8. -p 3307:3306: 将容器的 3306 端口映射到主机的 3307 端口
    9. -v /mydata/mysql/master/conf:/etc/mysql: 将配置文件夹挂在到主机
    10. -v /mydata/mysql/master/log:/var/log/mysql: 将日志文件夹挂载到主机
    11. -v /mydata/mysql/master/data:/var/lib/mysql/: 将配置文件夹挂载到主机
    12. -e MYSQL_ROOT_PASSWORD=root: 初始化 root 用户的密码
    13. 修改 master 基本配置
    14. vim /mydata/mysql/master/conf/my.cnf
    15. [client]
    16. default-character-set=utf8
    17. [mysql]
    18. default-character-set=utf8
    19. [mysqld]
    20. init_connect='SET collation_connection = utf8_unicode_ci'
    21. init_connect='SET NAMES utf8'
    22. character-set-server=utf8
    23. collation-server=utf8_unicode_ci
    24. skip-character-set-client-handshake
    25. skip-name-resolve
    26. 注意: skip-name-resolve 一定要加, 不然连接 mysql 会超级慢
    27. 添加 master 主从复制部分配置
    28. server_id=1
    29. log-bin=mysql-bin
    30. read-only=0
    31. binlog-do-db=gulimall_ums
    32. binlog-do-db=gulimall_pms
    33. binlog-do-db=gulimall_oms
    34. binlog-do-db=gulimall_sms
    35. binlog-do-db=gulimall_wms
    36. binlog-do-db=gulimall_admin
    37. replicate-ignore-db=mysql
    38. replicate-ignore-db=sys
    39. replicate-ignore-db=information_schema
    40. replicate-ignore-db=performance_schema
    41. 重启 master

    3)创建 Slave 实例并启动

    1. docker run -p 3317:3306 --name mysql-slaver-01 \
    2. -v /mydata/mysql/slaver/log:/var/log/mysql \
    3. -v /mydata/mysql/slaver/data:/var/lib/mysql \
    4. -v /mydata/mysql/slaver/conf:/etc/mysql \
    5. -e MYSQL_ROOT_PASSWORD=root \
    6. -d mysql:5.7
    7. 修改 slave 基本配置
    8. vim /mydata/mysql/slaver/conf/my.cnf
    9. [client]
    10. default-character-set=utf8
    11. [mysql]
    12. default-character-set=utf8
    13. [mysqld]
    14. init_connect='SET collation_connection = utf8_unicode_ci'
    15. init_connect='SET NAMES utf8'
    16. character-set-server=utf8
    17. collation-server=utf8_unicode_ci
    18. skip-character-set-client-handshake
    19. skip-name-resolve
    20. 添加 master 主从复制部分配置
    21. server_id=2
    22. log-bin=mysql-bin
    23. read-only=1
    24. binlog-do-db=gulimall_ums
    25. binlog-do-db=gulimall_pms
    26. binlog-do-db=gulimall_oms
    27. binlog-do-db=gulimall_sms
    28. binlog-do-db=gulimall_wms
    29. binlog-do-db=gulimall_admin
    30. replicate-ignore-db=mysql
    31. replicate-ignore-db=sys
    32. replicate-ignore-db=information_schema
    33. replicate-ignore-db=performance_schema
    34. 重启 slaver

    4)为 master 授权用户来他的同步数据

    1. 1、 进入 master 容器
    2. docker exec -it mysql /bin/bash
    3. 2、 进入 mysql 内部 (mysql –uroot -p)
    4. 1) 、 授权 root 可以远程访问( 主从无关, 为了方便我们远程连接 mysql)
    5. grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
    6. flush privileges;
    7. 2) 、 添加用来同步的用户
    8. GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456';
    9. 3、 查看 master 状态
    10. show master status\G;

    5)配置 slaver 同步 master 数据

    1. 1、 进入 slaver 容器
    2. docker exec -it mysql-slaver-01 /bin/bash
    3. 2、 进入 mysql 内部(mysql –uroot -p)
    4. 1) 、 授权 root 可以远程访问( 主从无关, 为了方便我们远程连接 mysql)
    5. grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
    6. flush privileges;
    7. 2) 、 设置主库连接
    8. change master to
    9. master_host='mysql-master.gulimall',master_user='backup',master_password='123456',mas
    10. ter_log_file='mysql-bin.000003',master_log_pos=0,master_port=3306;
    11. 3) 、 启动从库同步
    12. start slave;
    13. 4) 、 查看从库状态
    14. show slave status\G;

     6)总结:主从数据库在自己配置文件中声明需要同步哪个数据库, 忽略哪个数据库等信息。并且 server-id 不能一样;主库授权某个账号密码来同步自己的数据;从库使用这个账号密码连接主库来同步数据

    二. MyCat 或者 ShardingSphere 实现代理和分片

    Apache ShardingSphere

    shardingSphere:shardingSphere JDBC,shardingSphere Proxy
    auto_increment_offset: 1 从几开始增长
    auto_increment_increment: 2 每次的步长

    1)下载安装 Sharding-Proxy

    1. docker pull apache/sharding-proxy
    2. docker run -d -v /mydata/sharding-proxy/conf:/opt/sharding-proxy/conf -v
    3. /mydata/sharding-proxy/lib:/opt/sharding-proxy/lib --env PORT=3308 -p13308:3308
    4. apache/sharding-proxy:latest

    2)配置数据分片+读写分离

    server.yaml

    config-readwrite-splitting.yaml

    config-sharding.yaml

    1. schemaName: sharding_db
    2. #
    3. dataSources:
    4. ds_0:
    5. # url: jdbc:postgresql://127.0.0.1:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
    6. # username: postgres
    7. # password: postgres
    8. # connectionTimeoutMilliseconds: 30000
    9. # idleTimeoutMilliseconds: 60000
    10. # maxLifetimeMilliseconds: 1800000
    11. # maxPoolSize: 50
    12. # minPoolSize: 1
    13. # maintenanceIntervalMilliseconds: 30000
    14. ds_1:
    15. # url: jdbc:postgresql://127.0.0.1:3317/demo_ds_1?serverTimezone=UTC&useSSL=false
    16. # username: postgres
    17. # password: postgres
    18. # connectionTimeoutMilliseconds: 30000
    19. # idleTimeoutMilliseconds: 60000
    20. # maxLifetimeMilliseconds: 1800000
    21. # maxPoolSize: 50
    22. # minPoolSize: 1
    23. # maintenanceIntervalMilliseconds: 30000
    24. ######################################################################################################
    25. #rules:
    26. #- !SHARDING
    27. # tables:
    28. # t_order:
    29. # actualDataNodes: ds_${0..1}.t_order_${0..1}
    30. # tableStrategy:
    31. # standard:
    32. shardingColumn: order_id # 根据这个字段分表
    33. shardingAlgorithmName: t_order_inline
    34. keyGenerateStrategy: # 主键生成策略 #雪花算法
    35. column: order_id
    36. keyGeneratorName: snowflake
    37. t_order_item:
    38. # actualDataNodes: ds_${0..1}.t_order_item_${0..1}
    39. # tableStrategy:
    40. # standard:
    41. shardingColumn: order_id # 这样这2个表就在一个库中了
    42. shardingAlgorithmName: t_order_item_inline
    43. # keyGenerateStrategy:
    44. # column: order_item_id
    45. # keyGeneratorName: snowflake
    46. bindingTables:
    47. - t_order,t_order_item
    48. defaultDatabaseStrategy: # 分库
    49. standard:
    50. shardingColumn: user_id # 根据用户id分库
    51. shardingAlgorithmName: database_inline

    config-master_slave.yaml

    1. dataSources:
    2. # 22
    3. master_0_ds:
    4. url: jdbc:postgresql://192.168.56.10:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
    5. username: root
    6. password: root
    7. connectionTimeoutMilliseconds: 30000
    8. idleTimeoutMilliseconds: 60000
    9. maxLifetimeMilliseconds: 1800000
    10. maxPoolSize: 50
    11. slave_ds_0:
    12. url: jdbc:postgresql://192.168.56.10:3317/demo_ds_0?serverTimezone=UTC&useSSL=false
    13. username: root
    14. password: root
    15. connectionTimeoutMilliseconds: 30000
    16. idleTimeoutMilliseconds: 60000
    17. maxLifetimeMilliseconds: 1800000
    18. maxPoolSize: 50
    19. master_1_ds:
    20. url: jdbc:postgresql://192.168.56.10:3307/demo_ds_1?serverTimezone=UTC&useSSL=false
    21. username: root
    22. password: root
    23. connectionTimeoutMilliseconds: 30000
    24. idleTimeoutMilliseconds: 60000
    25. maxLifetimeMilliseconds: 1800000
    26. maxPoolSize: 50
    27. slave_ds_1:
    28. url: jdbc:postgresql://192.168.56.10:3317/demo_ds_1?serverTimezone=UTC&useSSL=false
    29. username: root
    30. password: root
    31. connectionTimeoutMilliseconds: 30000
    32. idleTimeoutMilliseconds: 60000
    33. maxLifetimeMilliseconds: 1800000
    34. maxPoolSize: 50
    35. # 2套主从规则
    36. masterSlaveRule:
    37. name: ms_ds1
    38. masterDataSourceName: master_0_ds
    39. slaveDataSourceNames:
    40. - slave_ds_0
    41. # 另放到一个文件在
    42. # name: ms_ds2:
    43. # masterDataSourceName: master_1_ds
    44. # slaveDataSourceNames:
    45. # - 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( 哨兵机制) 支持高可用

    深入理解Redis哨兵搭建及原理_nuomizhende45的博客-CSDN博客

    主要功能:
    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 数据分片)

    1. for port in $(seq 7001 7006); \
    2. do \
    3. mkdir -p /mydata/redis/node-${port}/conf
    4. touch /mydata/redis/node-${port}/conf/redis.conf
    5. cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
    6. port ${port}
    7. cluster-enabled yes
    8. cluster-config-file nodes.conf
    9. cluster-node-timeout 5000
    10. cluster-announce-ip 192.168.56.10
    11. cluster-announce-port ${port}
    12. cluster-announce-bus-port 1${port}
    13. appendonly yes
    14. EOF
    15. docker run -p ${port}:${port} -p 1${port}:1${port} --name redis-${port} \
    16. -v /mydata/redis/node-${port}/data:/data \
    17. -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
    18. -d redis:5.0.7 redis-server /etc/redis/redis.conf; \
    19. done
    20. docker stop $(docker ps -a |grep redis-700 | awk '{ print $1}')
    21. docker rm $(docker ps -a |grep redis-700 | awk '{ print $1}')

    2)使用 redis 建立集群

    1. docker exec -it redis-7001 bash
    2. redis-cli --cluster create 192.168.56.10:7001 192.168.56.10:7002 192.168.56.10:7003
    3. 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 网络

    1. Docker 创建容器时默认采用 bridge 网络,自行分配 ip,不允许自己指定。
    2. 在实际部署中, 我们需要指定容器 ip, 不允许其自行分配 ip, 尤其是搭建集群时, 固定 ip 是必须的。
    3. 我们可以创建自己的 bridge 网络 : mynet, 创建容器的时候指定网络为 mynet 并指定 ip 即可。
    4. 查看网络模式 docker network ls;
    5. 创建一个新的 bridge 网络
    6. docker network create --driver bridge --subnet=172.18.12.0/16 --gateway=172.18.1.1
    7. mynet
    8. 查看网络信息
    9. docker network inspect mynet
    10. 以后使用--network=mynet --ip 172.18.12.x 指定 ip

    2)Master 节点创建

    1. for port in $(seq 1 3); \
    2. do \
    3. mkdir -p /mydata/elasticsearch/master-${port}/config
    4. mkdir -p /mydata/elasticsearch/master-${port}/data
    5. chmod -R 777 /mydata/elasticsearch/master-${port}
    6. cat << EOF >/mydata/elasticsearch/master-${port}/config/elasticsearch.yml
    7. cluster.name: my-es #集群的名称, 同一个集群该值必须设置成相同的
    8. node.name: es-master-${port} #该节点的名字
    9. node.master: true #该节点有机会成为 master 节点
    10. node.data: false #该节点可以存储数据
    11. network.host: 0.0.0.0
    12. http.host: 0.0.0.0 #所有 http 均可访问
    13. http.port: 920${port}
    14. transport.tcp.port: 930${port}
    15. #discovery.zen.minimum_master_nodes: 2 #设置这个参数来保证集群中的节点可以知道其
    16. 它 N 个有 master 资格的节点。 官方推荐(N/2+1
    17. discovery.zen.ping_timeout: 10s #设置集群中自动发现其他节点时 ping 连接的超时时间
    18. discovery.seed_hosts: ["172.18.12.21:9301", "172.18.12.22:9302", "172.18.12.23:9303"] #设置集
    19. 群中的 Master 节点的初始列表, 可以通过这些节点来自动发现其他新加入集群的节点, es7
    20. 的新增配置
    21. cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始时的候选主节点, es7 的新增配置
    22. EOF
    23. docker run --name elasticsearch-node-${port} \
    24. -p 920${port}:920${port} -p 930${port}:930${port} \
    25. --network=mynet --ip 172.18.12.2${port} \
    26. -e ES_JAVA_OPTS="-Xms300m -Xmx300m" \
    27. -v
    28. /mydata/elasticsearch/master-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/el
    29. asticsearch.yml \
    30. -v /mydata/elasticsearch/master-${port}/data:/usr/share/elasticsearch/data \
    31. -v /mydata/elasticsearch/master-${port}/plugins:/usr/share/elasticsearch/plugins \
    32. -d elasticsearch:7.4.2
    33. done
    34. docker stop $(docker ps -a |grep elasticsearch-node-* | awk '{ print $1}')
    35. docker rm $(docker ps -a |grep elasticsearch-node-* | awk '{ print $1}')

    3)Data-Node 创建

    1. for port in $(seq 4 6); \
    2. do \
    3. mkdir -p /mydata/elasticsearch/node-${port}/config
    4. mkdir -p /mydata/elasticsearch/node-${port}/data
    5. chmod -R 777 /mydata/elasticsearch/node-${port}
    6. cat << EOF >/mydata/elasticsearch/node-${port}/config/elasticsearch.yml
    7. cluster.name: my-es #集群的名称, 同一个集群该值必须设置成相同的
    8. node.name: es-node-${port} #该节点的名字
    9. node.master: false #该节点有机会成为 master 节点
    10. node.data: true #该节点可以存储数据
    11. network.host: 0.0.0.0
    12. #network.publish_host: 192.168.56.10 #互相通信 ip, 要设置为本机可被外界访问的 ip, 否则
    13. 无法通信
    14. http.host: 0.0.0.0 #所有 http 均可访问
    15. http.port: 920${port}
    16. transport.tcp.port: 930${port}
    17. #discovery.zen.minimum_master_nodes: 2 #设置这个参数来保证集群中的节点可以知道其
    18. 它 N 个有 master 资格的节点。 官方推荐(N/2+1
    19. discovery.zen.ping_timeout: 10s #设置集群中自动发现其他节点时 ping 连接的超时时间
    20. discovery.seed_hosts: ["172.18.12.21:9301", "172.18.12.22:9302", "172.18.12.23:9303"] #设置集
    21. 群中的 Master 节点的初始列表, 可以通过这些节点来自动发现其他新加入集群的节点, es7
    22. 的新增配置
    23. cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始时的候选主节点, es7 的新增配置
    24. EOF
    25. docker run --name elasticsearch-node-${port} \
    26. -p 920${port}:920${port} -p 930${port}:930${port} \
    27. --network=mynet --ip 172.18.12.2${port} \
    28. -e ES_JAVA_OPTS="-Xms300m -Xmx300m" \
    29. -v
    30. /mydata/elasticsearch/node-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/ela
    31. sticsearch.yml \
    32. -v /mydata/elasticsearch/node-${port}/data:/usr/share/elasticsearch/data \
    33. -v /mydata/elasticsearch/node-${port}/plugins:/usr/share/elasticsearch/plugins \
    34. -d elasticsearch:7.4.2
    35. 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)搭建集群

    1. mkdir /mydata/rabbitmq
    2. cd rabbitmq/
    3. mkdir rabbitmq01 rabbitmq02 rabbitmq03
    4. docker run -d --hostname rabbitmq01 --name rabbitmq01 -v
    5. /mydata/rabbitmq/rabbitmq01:/var/lib/rabbitmq -p 15673:15672 -p 5673:5672 -e
    6. RABBITMQ_ERLANG_COOKIE='atguigu' rabbitmq:management
    7. docker run -d --hostname rabbitmq02 --name rabbitmq02 -v/mydata/rabbitmq/rabbitmq02:/var/lib/rabbitmq -p 15674:15672 -p 5674:5672 -e
    8. RABBITMQ_ERLANG_COOKIE='atguigu' --link rabbitmq01:rabbitmq01
    9. rabbitmq:management
    10. docker run -d --hostname rabbitmq03 --name rabbitmq03 -v
    11. /mydata/rabbitmq/rabbitmq03:/var/lib/rabbitmq -p 15675:15672 -p 5675:5672 -e
    12. RABBITMQ_ERLANG_COOKIE='atguigu' --link rabbitmq01:rabbitmq01 --link
    13. rabbitmq02:rabbitmq02 rabbitmq:management
    14. --hostname 设置容器的主机名
    15. RABBITMQ_ERLANG_COOKIE 节点认证作用, 部署集成时 需要同步该值

    2)节点加入集群

    1. docker exec -it rabbitmq01 /bin/bash
    2. rabbitmqctl stop_app
    3. rabbitmqctl reset
    4. rabbitmqctl start_app
    5. Exit
    6. 进入第二个节点
    7. docker exec -it rabbitmq02 /bin/bash
    8. rabbitmqctl stop_app
    9. rabbitmqctl reset
    10. rabbitmqctl join_cluster --ram rabbit@rabbitmq01
    11. rabbitmqctl start_app
    12. exit
    13. 进入第三个节点
    14. docker exec -it rabbitmq03 bash
    15. rabbitmqctl stop_app
    16. rabbitmqctl reset
    17. rabbitmqctl join_cluster --ram rabbit@rabbitmq01
    18. rabbitmqctl start_app
    19. exit

    3)实现镜像集群

    1. docker exec -it rabbitmq01 bash
    2. rabbitmqctl set_policy -p / ha "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
    3. 可以使用 rabbitmqctl list_policies -p /; 查看 vhost/下面的所有 policy
    4. 在 cluster 中任意节点启用策略, 策略会自动同步到集群节点
    5. rabbitmqctl set_policy-p/ha-all"^"’{“ha-mode”:“all”}’
    6. 策略模式 all 即复制到所有节点, 包含新增节点, 策略正则表达式为 “^” 表示所有匹配所有队列名称。 “^hello”表示只匹配名为 hello 开始的队列

  • 相关阅读:
    如何筛选出和产品相关的词,精准排除掉无效词
    idea使用Alibaba Cloud Toolkit实现自动部署
    Zookeeper:实现“分布式锁”的 Demo
    做短视频的赶紧用起来,超好用的配音神器~
    软件测试----基础篇(1)
    SpringCloud Alibaba-Sentinel
    Linux命令添加用户
    Solidity案例详解(四)投票智能合约
    JavaWeb-解析ServletCntext应用域
    比特米盒子刷CoreELEC
  • 原文地址:https://blog.csdn.net/xd592319702/article/details/127973543