1. 各角色介绍

Producer:消息的发送者;举例:发信者

Consumer:消息接收者;举例:收信者

Broker:暂存和传输信息;举例:邮局

NameServer:管理Broker;举例:各个邮局的管理机构

Topic:区分消息的种类;一个发送者可以发送消息给一个或多个Topic;一个接收者可以订阅一个或多个Topic消息

Message Queue:相当于是Topic的分区;用于并行发送和接收消息

2. 集群搭建方式

2.1 集群特点

NameServer是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。

Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与NameServer集群中的所有节点建立长连接,定时注册Topic信息到所有NameServer。

Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。

Consumer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。

2.2 集群模式

2.2.1 单Master模式

这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用。不建议线上环境使用,可以用于本地测试。

上一篇采用的就是这种方式部署的:1 - 【RocketMQ 系列】CentOS 7.6 安装部署RocketMQ

https://note.youdao.com/s/9DXcH2gh

2.2.2 多Master模式

一个集群无Slave,全是Master,例如2个Master或者3个Master,这种模式的优缺点如下:

优点:配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高;

缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。

2.2.3 多Master多Slave模式-异步复制

每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级),这种模式的优缺点如下:

优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时Master宕机后,消费者仍然可以从Slave消费,而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样;

缺点:Master宕机,磁盘损坏情况下会丢失少量消息。

2.2.4 多Master多Slave模式-同步双写

每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:

优点:数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高;

缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。(4.5版本之后提供DLedger多副本模式可实现主从自动切换)

2.3 双主双从集群搭建

2.3.1 总体架构

消息高可用采用2m-2s(同步双写)方式

2.3.2 集群工作流程

启动NameServer,NameServer起来后监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。

Broker启动,跟所有的NameServer保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer集群中就有Topic跟Broker的映射关系。

收发消息前,先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,也可以在发送消息时自动创建Topic。

Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Broker建立长连接从而向Broker发消息。

Consumer跟Producer类似,跟其中一台NameServer建立长连接,获取当前订阅Topic存在哪些Broker上,然后直接跟Broker建立连接通道,开始消费消息。

2.3.3 服务器环境

序号

IP(外/内)

角色

架构模式

1

81.71.157.232

172.16.0.8

nameserver、brokerserver

Master1、Slave2

2

106.55.35.2

172.16.0.2

nameserver、brokerserver

Master2、Slave1

服务器准备好了按照我上个教程配置好基础环境(安装 jdk1.8 、Maven 3.8.6 、RocketMQ 4.9.4)

https://note.youdao.com/s/9DXcH2gh

2.3.4 Host添加信息

vim /etc/hosts

在末尾加上配置内容如下:

# nameserver

81.71.157.232 rocketmq-nameserver1 # 9876

106.55.35.2 rocketmq-nameserver2 # 9876

# broker

81.71.157.232 rocketmq-master1 # 10910

81.71.157.232 rocketmq-slave2 # 10921

106.55.35.2 rocketmq-master2 # 10920

106.55.35.2 rocketmq-slave1 # 10911

配置完成后,重启网卡

systemctl restart network

2.3.5 安全组配置

为了安全只开放特定的端口号:9876(NameServer1 和 NameServer2)、10910(Master1)、10920(Master2)、10911(Slave1)、10921(Slave2)

2.3.6 环境变量配置

vim /etc/profile

在profile文件的末尾加入如下内容

# rocketmq

ROCKETMQ_HOME=/usr/local/rocketmq

PATH=$PATH:$ROCKETMQ_HOME/bin

export ROCKETMQ_HOME PATH

ESC 之后 输入 :wq! 回车保存并退出,再输入以下命令使得配置立刻生效:

source /etc/profile

2.3.7 创建消息存储路径

1号服务器:81.71.157.232

mkdir -p /usr/local/rocketmq/store/broker-a/commitlog

mkdir -p /usr/local/rocketmq/store/broker-a/consumequeue

mkdir -p /usr/local/rocketmq/store/broker-a/index

mkdir -p /usr/local/rocketmq/store/broker-b-s/commitlog

mkdir -p /usr/local/rocketmq/store/broker-b-s/consumequeue

mkdir -p /usr/local/rocketmq/store/broker-b-s/index

2号服务器 :106.55.35.2

mkdir -p /usr/local/rocketmq/store/broker-b/commitlog

mkdir -p /usr/local/rocketmq/store/broker-b/consumequeue

mkdir -p /usr/local/rocketmq/store/broker-b/index

mkdir -p /usr/local/rocketmq/store/broker-a-s/commitlog

mkdir -p /usr/local/rocketmq/store/broker-a-s/consumequeue

mkdir -p /usr/local/rocketmq/store/broker-a-s/index

2.3.8 broker配置文件

分别在2台服务器上执行以下命令,编辑 broker.conf 文件,红框部分改成对应服务器的外网IP

vim /usr/local/rocketmq/conf/broker.conf

2.3.8.1 master1

服务器:81.71.157.232 、172.16.0.8

vim /usr/local/rocketmq/conf/2m-2s-sync/broker-a.properties

修改配置如下:

#Broker服务地址

brokerIP1=81.71.157.232

#所属集群名字

brokerClusterName=rocketmq-cluster

#broker名字,注意此处不同的配置文件填写的不一样

brokerName=broker-a

#0 表示 Master,>0 表示 Slave

brokerId=0

#nameServer地址,分号分割

namesrvAddr=81.71.157.232:9876;106.55.35.2:9876

#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数

defaultTopicQueueNums=4

#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭

autoCreateTopicEnable=true

#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭

autoCreateSubscriptionGroup=true

#Broker 对外服务的监听端口

listenPort=10910

#删除文件时间点,默认凌晨 4点

deleteWhen=04

#文件保留时间,默认 48 小时

fileReservedTime=120

#commitLog每个文件的大小默认1G

mapedFileSizeCommitLog=1073741824

#ConsumeQueue每个文件默认存30W条,根据业务情况调整

mapedFileSizeConsumeQueue=300000

#destroyMapedFileIntervalForcibly=120000

#redeleteHangedFileInterval=120000

#检测物理文件磁盘空间

diskMaxUsedSpaceRatio=88

#存储路径

storePathRootDir=/usr/local/rocketmq/store/broker-a

#commitLog 存储路径

storePathCommitLog=/usr/local/rocketmq/store/broker-a/commitlog

#消费队列存储路径存储路径

storePathConsumeQueue=/usr/local/rocketmq/store/broker-a/consumequeue

#消息索引存储路径

storePathIndex=/usr/local/rocketmq/store/broker-a/index

#checkpoint 文件存储路径

storeCheckpoint=/usr/local/rocketmq/store/broker-a/checkpoint

#abort 文件存储路径

abortFile=/usr/local/rocketmq/store/broker-a/abort

#限制的消息大小

maxMessageSize=65536

#flushCommitLogLeastPages=4

#flushConsumeQueueLeastPages=2

#flushCommitLogThoroughInterval=10000

#flushConsumeQueueThoroughInterval=60000

#Broker 的角色

#- ASYNC_MASTER 异步复制Master

#- SYNC_MASTER 同步双写Master

#- SLAVE

brokerRole=SYNC_MASTER

#刷盘方式

#- ASYNC_FLUSH 异步刷盘

#- SYNC_FLUSH 同步刷盘

flushDiskType=SYNC_FLUSH

#checkTransactionMessageEnable=false

#发消息线程池数量

#sendMessageThreadPoolNums=128

#拉消息线程池数量

#pullMessageThreadPoolNums=128

2.3.8.2 slave2

服务器:81.71.157.232 、172.16.0.8

vim /usr/local/rocketmq/conf/2m-2s-sync/broker-b-s.properties

修改配置如下:

#Broker服务地址

brokerIP1=81.71.157.232

#所属集群名字

brokerClusterName=rocketmq-cluster

#broker名字,注意此处不同的配置文件填写的不一样

brokerName=broker-b

#0 表示 Master,>0 表示 Slave

brokerId=1

#nameServer地址,分号分割

namesrvAddr=81.71.157.232:9876;106.55.35.2:9876

#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数

defaultTopicQueueNums=4

#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭

autoCreateTopicEnable=true

#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭

autoCreateSubscriptionGroup=true

#Broker 对外服务的监听端口

listenPort=10921

#删除文件时间点,默认凌晨 4点

deleteWhen=04

#文件保留时间,默认 48 小时

fileReservedTime=120

#commitLog每个文件的大小默认1G

mapedFileSizeCommitLog=1073741824

#ConsumeQueue每个文件默认存30W条,根据业务情况调整

mapedFileSizeConsumeQueue=300000

#destroyMapedFileIntervalForcibly=120000

#redeleteHangedFileInterval=120000

#检测物理文件磁盘空间

diskMaxUsedSpaceRatio=88

#存储路径

storePathRootDir=/usr/local/rocketmq/store/broker-b-s

#commitLog 存储路径

storePathCommitLog=/usr/local/rocketmq/store/broker-b-s/commitlog

#消费队列存储路径存储路径

storePathConsumeQueue=/usr/local/rocketmq/store/broker-b-s/consumequeue

#消息索引存储路径

storePathIndex=/usr/local/rocketmq/store/broker-b-s/index

#checkpoint 文件存储路径

storeCheckpoint=/usr/local/rocketmq/store/broker-b-s/checkpoint

#abort 文件存储路径

abortFile=/usr/local/rocketmq/store/broker-b-s/abort

#限制的消息大小

maxMessageSize=65536

#flushCommitLogLeastPages=4

#flushConsumeQueueLeastPages=2

#flushCommitLogThoroughInterval=10000

#flushConsumeQueueThoroughInterval=60000

#Broker 的角色

#- ASYNC_MASTER 异步复制Master

#- SYNC_MASTER 同步双写Master

#- SLAVE

brokerRole=SLAVE

#刷盘方式

#- ASYNC_FLUSH 异步刷盘

#- SYNC_FLUSH 同步刷盘

flushDiskType=ASYNC_FLUSH

#checkTransactionMessageEnable=false

#发消息线程池数量

#sendMessageThreadPoolNums=128

#拉消息线程池数量

#pullMessageThreadPoolNums=128

2.3.8.3 master2

服务器:106.55.35.2、172.16.0.2

vim /usr/local/rocketmq/conf/2m-2s-sync/broker-b.properties

修改配置如下:

#Broker服务地址

brokerIP1=106.55.35.2

#所属集群名字

brokerClusterName=rocketmq-cluster

#broker名字,注意此处不同的配置文件填写的不一样

brokerName=broker-b

#0 表示 Master,>0 表示 Slave

brokerId=0

#nameServer地址,分号分割

namesrvAddr=81.71.157.232:9876;106.55.35.2:9876

#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数

defaultTopicQueueNums=4

#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭

autoCreateTopicEnable=true

#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭

autoCreateSubscriptionGroup=true

#Broker 对外服务的监听端口

listenPort=10920

#删除文件时间点,默认凌晨 4点

deleteWhen=04

#文件保留时间,默认 48 小时

fileReservedTime=120

#commitLog每个文件的大小默认1G

mapedFileSizeCommitLog=1073741824

#ConsumeQueue每个文件默认存30W条,根据业务情况调整

mapedFileSizeConsumeQueue=300000

#destroyMapedFileIntervalForcibly=120000

#redeleteHangedFileInterval=120000

#检测物理文件磁盘空间

diskMaxUsedSpaceRatio=88

#存储路径

storePathRootDir=/usr/local/rocketmq/store/broker-b

#commitLog 存储路径

storePathCommitLog=/usr/local/rocketmq/store/broker-b/commitlog

#消费队列存储路径存储路径

storePathConsumeQueue=/usr/local/rocketmq/store/broker-b/consumequeue

#消息索引存储路径

storePathIndex=/usr/local/rocketmq/store/broker-b/index

#checkpoint 文件存储路径

storeCheckpoint=/usr/local/rocketmq/store/broker-b/checkpoint

#abort 文件存储路径

abortFile=/usr/local/rocketmq/store/broker-b/abort

#限制的消息大小

maxMessageSize=65536

#flushCommitLogLeastPages=4

#flushConsumeQueueLeastPages=2

#flushCommitLogThoroughInterval=10000

#flushConsumeQueueThoroughInterval=60000

#Broker 的角色

#- ASYNC_MASTER 异步复制Master

#- SYNC_MASTER 同步双写Master

#- SLAVE

brokerRole=SYNC_MASTER

#刷盘方式

#- ASYNC_FLUSH 异步刷盘

#- SYNC_FLUSH 同步刷盘

flushDiskType=SYNC_FLUSH

#checkTransactionMessageEnable=false

#发消息线程池数量

#sendMessageThreadPoolNums=128

#拉消息线程池数量

#pullMessageThreadPoolNums=128

2.3.8.4 slave1

服务器:106.55.35.2、172.16.0.2

vim /usr/local/rocketmq/conf/2m-2s-sync/broker-a-s.properties

修改配置如下:

#Broker服务地址

brokerIP1=106.55.35.2

#所属集群名字

brokerClusterName=rocketmq-cluster

#broker名字,注意此处不同的配置文件填写的不一样

brokerName=broker-a

#0 表示 Master,>0 表示 Slave

brokerId=1

#nameServer地址,分号分割

namesrvAddr=81.71.157.232:9876;106.55.35.2:9876

#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数

defaultTopicQueueNums=4

#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭

autoCreateTopicEnable=true

#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭

autoCreateSubscriptionGroup=true

#Broker 对外服务的监听端口

listenPort=10911

#删除文件时间点,默认凌晨 4点

deleteWhen=04

#文件保留时间,默认 48 小时

fileReservedTime=120

#commitLog每个文件的大小默认1G

mapedFileSizeCommitLog=1073741824

#ConsumeQueue每个文件默认存30W条,根据业务情况调整

mapedFileSizeConsumeQueue=300000

#destroyMapedFileIntervalForcibly=120000

#redeleteHangedFileInterval=120000

#检测物理文件磁盘空间

diskMaxUsedSpaceRatio=88

#存储路径

storePathRootDir=/usr/local/rocketmq/store/broker-a-s

#commitLog 存储路径

storePathCommitLog=/usr/local/rocketmq/store/broker-a-s/commitlog

#消费队列存储路径存储路径

storePathConsumeQueue=/usr/local/rocketmq/store/broker-a-s/consumequeue

#消息索引存储路径

storePathIndex=/usr/local/rocketmq/store/broker-a-s/index

#checkpoint 文件存储路径

storeCheckpoint=/usr/local/rocketmq/store/broker-a-s/checkpoint

#abort 文件存储路径

abortFile=/usr/local/rocketmq/store/broker-a-s/abort

#限制的消息大小

maxMessageSize=65536

#flushCommitLogLeastPages=4

#flushConsumeQueueLeastPages=2

#flushCommitLogThoroughInterval=10000

#flushConsumeQueueThoroughInterval=60000

#Broker 的角色

#- ASYNC_MASTER 异步复制Master

#- SYNC_MASTER 同步双写Master

#- SLAVE

brokerRole=SLAVE

#刷盘方式

#- ASYNC_FLUSH 异步刷盘

#- SYNC_FLUSH 同步刷盘

flushDiskType=ASYNC_FLUSH

#checkTransactionMessageEnable=false

#发消息线程池数量

#sendMessageThreadPoolNums=128

#拉消息线程池数量

#pullMessageThreadPoolNums=128

2.3.9 服务启动

2.3.9.1 启动NameServer集群

分别在 81.71.157.232 和 106.55.35.2 启动 NameServer1 和 NameServer2

cd /usr/local/rocketmq/bin

nohup sh mqnamesrv &

jps

2.3.9.2 启动Broker集群

在 81.71.157.232 上启动 master1

在 106.55.35.2 上启动 slave1

在 106.55.35.2 上启动 master2

在 81.71.157.232 上启动 slave2

master1:

cd /usr/local/rocketmq/bin

nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-2s-sync/broker-a.properties &

jps

slave1:

cd /usr/local/rocketmq/bin

nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-2s-sync/broker-a-s.properties &

jps

master2:

cd /usr/local/rocketmq/bin

nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-2s-sync/broker-b.properties &

jps

slave2:

cd /usr/local/rocketmq/bin

nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-2s-sync/broker-b-s.properties &

jps

2.3.10 查看状态

分别在 81.71.157.232 和 106.55.35.2 执行以下命令:

jps

启动完成,分别在2台服务器查看集群信息:

sh mqadmin clusterlist -n 81.71.157.232:9876

sh mqadmin clusterlist -n 106.55.35.2:9876

或者执行以下命令:

sh mqadmin clusterlist -n localhost:9876

2.4 RocketMQ 仪表盘

按照上篇文章操作安装就行,链接地址:注意更改仪表盘端口(安全组端口开放),然后rocketmq.config.namesrvAddr配置项改成对应的外网IP

https://note.youdao.com/s/9DXcH2gh

2.4.1 访问仪表盘

http://81.71.157.232:8888/#/

http://106.55.35.2:8888/#/

到此部署完成!自启动服务可以按照我上篇文章的思路操作。https://note.youdao.com/s/9DXcH2gh

【RocketMQ 系列】 RocketMQ 双主双从(同步双写) 集群搭建的更多相关文章

  1. MySQL集群搭建(6)-双主+keepalived高可用

    双主 + keepalived 是一个比较简单的 MySQL 高可用架构,适用于中小 MySQL 集群,今天就说说怎么用 keepalived 做 MySQL 的高可用. 1 概述 1.1 keepa ...

  2. rocketmq 两主两从异步集群搭建

    1.安装JDK 需要先卸载系统默认的OPENJDK,安装 JDK1.8 64位的版本. 卸载open-jdk rpm -qa|grep java 查到open jdk的安装. 使用命令 rpm -e ...

  3. RocketMQ集群搭建(3m-3s-async)

    RocketMQ集群搭建(3m-3s-async) 各角色介绍 角色 作用 Producer 消息发送者,将消息发送到 Broker.无状态,其与NameServer集群中的一个节点建立长连接,定期从 ...

  4. RocketMQ集群搭建方式

    各角色介绍 Producer:消息的发送者:举例:发信者 Consumer:消息接收者:举例:收信者 Broker:暂存和传输消息:举例:邮局 NameServer:管理Broker:举例:各个邮局的 ...

  5. 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  6. 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解

    引言 在之前的大数据学习系列中,搭建了Hadoop+Spark+HBase+Hive 环境以及一些测试.其实要说的话,我开始学习大数据的时候,搭建的就是集群,并不是单机模式和伪分布式.至于为什么先写单 ...

  7. redis--主从同步,故障切换,集群搭建

    一 . redis主从同步 准备三个配置文件,实现一主两从的redis数据库结构(这三个配置文件仅仅端口不一样) # redis-6379.conf 文件, 写入下面数据: port 6379 dae ...

  8. 分布式缓存技术redis系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  9. .Net Core2.1 秒杀项目一步步实现CI/CD(Centos7.2)系列一:k8s高可用集群搭建总结以及部署API到k8s

    前言:本系列博客又更新了,是博主研究很长时间,亲自动手实践过后的心得,k8s集群是购买了5台阿里云服务器部署的,这个集群差不多搞了一周时间,关于k8s的知识点,我也是刚入门,这方面的知识建议参考博客园 ...

  10. redis系列之4----redis高级应用(集群搭建、集群分区原理、集群操作)

    文章主目录 Redis集群简介 Redis集群搭建 Redis集群分区原理 集群操作 参考文档 本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 ...

随机推荐

  1. WPF新建viewModel实例化成员的注意事项

    不要用表达式体去初始化一个用做数据源(比如ItemSource)的引用类型成员.比如这种 public List<MainWindowItem> Items => new List& ...

  2. C# 使用大数组内存溢出的解决办法

    在实际开发中,需要读取文件转成byte数组,文件大小四五百兆,采用win10系统,我那台电脑系统版本非常老了,一直没升级,读取文件时,就会出现OutOfMemeory异常,时不时的出现.我程序用的an ...

  3. winform 绘图控件 chart 实时曲线图

    官方教程:http:////files.cnblogs.com/files/HelloQLQ/Winform图表.rar 更多参考:https://blog.csdn.net/boxuming/art ...

  4. MyBatis数据源模块源码分析

    数据源对象是比较复杂的对象,其创建过程相对比较复杂,对于 MyBatis 创建数据源,具体来讲有如下难点: MyBatis 不但要能集成第三方的数据源组件,自身也提供了数据源的实现: 数据源的初始化参 ...

  5. 深入探讨Function Calling:在Semantic Kernel中的应用实践

    引言 上一章我们熟悉了 OpenAI 的 function calling 的执行原理,这一章节我们讲解一下 function calling 在 Semantic Kernel 的应用. 在Open ...

  6. Swift 排查引用循环

    ------------恢复内容开始------------ 一.最近使用RxSwift在多次信号的嵌套中,发现一个对象始终始终无法释放 开始想通过Memory Graph验证是否没有释放,一直报错, ...

  7. win11启动虚拟机出现蓝屏

    win11虚拟机启动出现蓝屏 问题 我的电脑是win11系统,最近在安装vmware后装了centos7.6,发现一启动centos,电脑就出现蓝屏,如图 解决 这个问题搞了好久,最终发现是win11 ...

  8. .net framework 使用Apollo 配置中心

    参照了:https://www.cnblogs.com/xichji/p/11324893.html Apollo默认有一个"SampleApp"应用,"DEV" ...

  9. vm ware 虚拟WIN XP 时卡

    主机是I7 9700,SN750 NVME 1T SSD, 32G 内存,VM WARE 14,理论上虚拟WIN XP 不会卡,但实际情况就是很卡. 虚拟WIN7 ,WIN 10,UBUNTU LIN ...

  10. flutter 环境搭配 (一)

    首先下载flutter SDK Flutter中文网 官网 (p2hp.com 选择下载 SDK 解压后 ,添加到环境变量中. 配置国内镜像, PUB_HOSTED_URL=https://pub.f ...