
很多年前我还在靠着一台 MySQL 硬扛业务流量的时候就想着什么时候能把读和写拆开。当时项目越做越大单机数据库的 CPU 在晚间高峰直接拉满一条复杂报表查询能把所有线上请求拖慢半拍。后来我下定决心把架构改成 MySQL 主从同步 Mycat 2 读写分离一套流程跑下来读流量被分流到从库主库的写压力也降了下来。这篇文章就完整记录我当时从零到一落地的过程里面包含 MySQL 主从同步的具体配置、Mycat 2 的安装与读写分离配置、联调验证方法和一堆实测踩坑记录适合正在规划数据库读写分离、或者已经装了 MySQL 但不知道如何拆流量的同学参考。1. 先把架构思路理清楚为什么是 Mycat 2 主从同步1.1 读写分离解决的是哪个问题先说明一个容易混淆的点读写分离本身并不解决数据一致性问题它只是把读流量从主库搬走。MySQL 的瓶颈大多数时候出在“读”上尤其是互联网业务常见的读多写少场景首页、列表、详情页这些接口一次写操作会引来几十上百次读操作。单库单机的时候所有读和写都打到同一个实例慢查询一旦出现写事务也跟着排队整个库的吞吐量就上不去了。主从同步的意义在于它让多台 MySQL 实例之间保持近乎实时的数据复制。主库负责写从库负责读写完之后 binlog 异步传给从库并回放从库就有了近似一致的副本。Mycat 2 的作用则是中间代理层应用连的是 MycatMycat 根据 SQL 类型自动路由INSERT / UPDATE / DELETE 这类写操作发到主库SELECT 查询发到从库或者按策略分发到多个从库。业务代码完全不用感知底层有几台 MySQL连接地址从真实的 MySQL 地址换成 Mycat 地址就行。从这个角度看这套方案的核心链路是三层应用层只和 Mycat 打交道Mycat 作为 SQL 路由器MySQL 主从复制作为数据底座。三层各司其职缺了任何一层读写分离都跑不起来。1.2 选型对比为什么不直接在业务代码里做多数据源可能有人会问Spring Boot 里有 AbstractRoutingDataSourceShardingSphere 也可以做读写分离为什么我选了 Mycat 2。我能给出的实际考虑是第一中间件方式对应用最透明。改多数据源需要在代码里写路由逻辑至少要动 Service 层或者 Mapper 层项目里几十个接口都得跟着改改完还要重新测试。而 Mycat 2 对应用来说就是一个 MySQL 服务应用只改一个 JDBC 连接串不需要改业务代码。对于已经上线、不敢大改的项目来说这是最容易落地的路径。第二Mycat 2 基于 NIO 实现连接管理比老一代的 Mycat 1 轻量很多配置方式也更加简洁引入了更清晰的 datasource 和 replica 配置模型隔离了物理数据源和逻辑复制组的关系管理起来比一大堆 XML 舒服。第三ShardingSphere 也很好但它如果以 Proxy 模式部署本质上也是一个中间件功能和 Mycat 2 有重叠如果以 Jar 包模式嵌入应用对业务代码和依赖的侵入又比较明显。综合考虑团队技术栈和运维成本Mycat 2 当时最适合我们。下面这张图是我在规划时给团队画出的数据流逻辑虽然不画图了但你可以理解成应用 - Mycat 2根据 SQL 类型路由- 主库写 / 从库读binlog 从主库单向流向从库。理解这个逻辑之后配置起来就顺了。2. MySQL 主从同步的搭建过程先保证数据能可靠复制2.1 环境准备和版本选择我在搭建前先把两台机器的环境理顺。主库和从库都用的 CentOS 7.9MySQL 版本统一为 8.0.36这一步很重要——主从版本最好一致即使不一致也建议从库版本不低于主库否则容易遇到 binlog 格式解析不兼容的问题。主库 IP 是 192.168.1.10从库 IP 是 192.168.1.11后面配置里我都用这两个 IP 举例。你需要把它们替换成自己环境的实际 IP。服务器配置最好也别差距太大从库如果需要承载读流量硬件上不能比主库弱太多。安装 MySQL 的过程不算复杂但有几个细节想提醒如果你是离线环境记得提前准备 rpm 包或者 tar 包在线装的话用官方 yum 源最省事。装完之后先把 MySQL 服务启动起来确认能通过本地 socket 连接再开始改配置。我遇到过不少同学一上来就改主从配置结果 MySQL 本身都连不上排查了半天才发现是服务没起来或者配置文件权限不对。2.2 主库配置开 binlog、设 server_id主从同步的根基是 binlog主库必须开启二进制日志。我这边主库的 my.cnf 关键配置如下[mysqld] server_id 100 log_bin mysql-bin binlog_format ROW max_binlog_size 256M binlog_expire_logs_seconds 604800 gtid_mode ON enforce_gtid_consistency ON每一行都解释一下server_id 是整个复制拓扑中的实例标识主库从库必须不一样我用 100 表示主库200 表示从库方便排查问题。log_bin 开了之后MySQL 会把所有变更写入 mysql-bin 日志文件主从复制全靠它。binlog_format 建议用 ROW 模式因为 ROW 模式记录的是行级别的变更比 STATEMENT 更可靠不会因为函数、触发器导致从库回放结果不一样。gtid_mode 和 enforce_gtid_consistency 是 GTID 复制必需的。GTID 比传统的基于文件名位点的复制方式好维护得多每个事务都有全局唯一 ID从库不会记错位置。改完之后记得重启 MySQLsystemctl restart mysqld然后确认 binlog 已经开启SHOW MASTER STATUS;这个命令会返回当前 binlog 文件名和位置比如 mysql-bin.000001 和 154。在非 GTID 模式下等下配置从库会用到这两个信息GTID 模式则不需要。2.3 从库配置设置独立的 server_id 和中继日志从库的 my.cnf 配置如下[mysqld] server_id 200 relay_log relay-bin read_only ON super_read_only ON gtid_mode ON enforce_gtid_consistency ONread_only 和 super_read_only 一定要加。从库本身只应该被复制线程写入普通业务账号连从库做写入操作必须被拦截否则就会出现主库刚写入的数据被从库手工改动覆盖然后触发主键冲突、复制中断的惨剧。super_read_only 比 read_only 更严格连超级管理员也不能通过普通连接写入但不会影响复制 SQL 线程的回放操作。重启从库 MySQL 之后同样确认 server_id 生效SHOW VARIABLES LIKE server_id;2.4 创建复制专用账号主库上需要创建一个账号专门给从库拉取 binlog 用。我不建议直接用 root因为权限过大且容易混淆审计。创建一个最小权限账号CREATE USER repl192.168.1.% IDENTIFIED WITH mysql_native_password BY Repl2024; GRANT REPLICATION SLAVE ON *.* TO repl192.168.1.%; FLUSH PRIVILEGES;这里IDENTIFIED WITH mysql_native_password是 MySQL 8.0 里为了兼容旧客户端常用的写法。如果你用的 MySQL 版本默认禁用了这个认证插件也可以直接去掉 WITH 子句用默认的 caching_sha2_password后面配置从库连接时在 CHANGE MASTER 语句里加上GET_MASTER_PUBLIC_KEY 1即可。2.5 数据初始化两种方式对应不同场景如果主库上已经有业务数据从库不能是空库必须保证起点一致。我当时主库上有大概几十 GB 的数据采用的是 mysqldump 做逻辑备份再导入从库的方式mysqldump --single-transaction --set-gtid-purgedON --master-data2 -uroot -p shop shop.sql参数这里重点说三个--single-transaction 用于 InnoDB 表的一致性快照备份备份过程中不会锁住业务写入。--set-gtid-purgedON 会在备份文件里记录当前已经执行过的 GTID 集合导入从库后从库就知道该从哪个 GTID 之后开始复制。--master-data2 会把备份时刻的 binlog 文件名和位点注释记录在备份文件中传统复制模式要用它。如果数据量特别大逻辑备份恢复太慢可以用 xtrabackup 这类物理备份工具。但如果主库数据量不大mysqldump 完全够用而且逻辑备份还能顺便检查一遍数据完整性。导入从库mysql -uroot -p shop.sql这里有个容易踩的坑如果你用 --set-gtid-purgedON导入完成后从库的 gtid_executed 集合可能不是空的此时直接 CHANGE MASTER 到主库从库可能会因为 GTID 集合重叠而报错。最稳妥的办法是让从库以全新的 GTID 状态开始在导入前确认从库本身没有业务写入历史。如果是全新环境直接导入即可。2.6 配置 CHANGE MASTER 并启动复制GTID 模式的配置非常简单不需要关心 binlog 文件名和位点CHANGE MASTER TO MASTER_HOST 192.168.1.10, MASTER_PORT 3306, MASTER_USER repl, MASTER_PASSWORD Repl2024, GET_MASTER_PUBLIC_KEY 1; START SLAVE;如果你没有启用 GTID而是走传统位点复制那么需要把 MASTER_LOG_FILE 和 MASTER_LOG_POS 填上刚才 SHOW MASTER STATUS 看到的信息CHANGE MASTER TO MASTER_HOST 192.168.1.10, MASTER_PORT 3306, MASTER_USER repl, MASTER_PASSWORD Repl2024, MASTER_LOG_FILE mysql-bin.000001, MASTER_LOG_POS 154; START SLAVE;启动之后立刻检查复制状态SHOW SLAVE STATUS\G重点关注三个值Slave_IO_Running 必须为 Yes表示 IO 线程能正常从主库拉取 binlog。Slave_SQL_Running 必须为 Yes表示 SQL 线程能正常回放中继日志。Seconds_Behind_Master 表示从库落后主库的秒数初期如果是 0 或者很小的数字都是正常的。如果你看到 Slave_IO_Running 是 Connecting不要急按这个顺序排查先从从库机器 telnet 主库 3306 端口通不通防火墙有没有放行再确认 repl 账号能否登录最后看 CHANGE MASTER 语句里主机 IP、端口、账号密码是否填对。2.7 验证主从同步效果配置完成之后我自己建了一张表做验证。在主库执行CREATE DATABASE shop; USE shop; CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); INSERT INTO t_user(name) VALUES (alice), (bob), (carol);然后在从库查询SHOW DATABASES; USE shop; SELECT * FROM t_user;如果从库能看到 shop 库和刚才插入的三条数据说明 binlog - relay log - SQL 回放整条链路是通的。到这里MySQL 主从同步已经完成了后面 Mycat 2 才有一个可靠的数据底座可以用。3. Mycat 2 的部署与读写分离配置3.1 安装 Mycat 2依赖 JDK 和安装包结构Mycat 2 是 Java 写的机器上必须先有 JDK我这边用的是 JDK 11。安装包从官方 Release 页面下载解压后目录结构大体是这样的mycat2/ ├── bin/ ├── conf/ │ ├── datasource.yml │ ├── replica.yml │ ├── schema.yml │ └── server.json ├── lib/ └── logs/conf 目录下的 YAML 文件是 Mycat 2 的核心配置文件思路和 Mycat 1 的 XML 完全不同不再把数据源写在一大坨 XML 里而是拆分成 datasource、replica、schema 三层。我先提醒一句不同版本配置项的字段名可能略有差异我下面给出的写法基于我用过的 2.x 安装包模板你实际操作时以 conf 目录自带的示例文件为准把字段名对照着改即可。启动方式也很简单cd /opt/mycat2 ./bin/mycat start启动后留意两个端口8066 是应用连接 Mycat 的入口1984 是 Mycat 的集群管理端口。看到 8066 端口监听成功说明 Mycat 已经起来了。3.2 配置数据源把主库和从库连接信息告诉 Mycatdatasource 配置就是让 Mycat 知道它后面有哪几台 MySQL以及用什么账号去连接。我的 datasource 配置写法如下字段以你安装包自带模板为准dataSourceList: - name: ds_master url: jdbc:mysql://192.168.1.10:3306/shop?useSSLfalseallowPublicKeyRetrievaltrue user: mycat_conn password: YourPassword maxCon: 200 minCon: 10 - name: ds_slave1 url: jdbc:mysql://192.168.1.11:3306/shop?useSSLfalseallowPublicKeyRetrievaltrue user: mycat_conn password: YourPassword maxCon: 200 minCon: 10这里有几个容易踩的坑useSSLfalse 一定要加。MySQL 8 默认开了 SSL 相关行为如果连接串不带 useSSLfalseMycat 连接 MySQL 时可能报 SSL 连接错误应用层也会跟着报错。allowPublicKeyRetrievaltrue 是配合 caching_sha2_password 认证插件用的。如果你的 MySQL 用户是默认认证方式不加这个参数可能连不上。我建议在 MySQL 里单独创建一个给 Mycat 用的连接账号不要用 root。权限按照业务需要给比如 shop 库的 SELECT、INSERT、UPDATE、DELETE。账号密码统一管理别散落在一堆配置文件里。3.3 配置复制组告诉 Mycat 谁是主、谁是从replica 配置是 Mycat 2 里表达主从拓扑的核心它定义了一个逻辑复制组Mycat 根据这个组来理解写流量该发到哪个数据源读流量该从哪些数据源里选。我配置了一个名为 shop_rw 的复制组replicaList: - name: shop_rw rwType: 1 writeHost: ds_master readHosts: - ds_slave1 readBalanceType: 0 readBalanceRandom: false重点说一下 rwType 和 readBalanceTyperwType 用于标识这个复制组的读写属性1 表示这个组是读写分离的复制组写走 writeHost读走 readHosts。readBalanceType 控制多个从库之间的读流量调度策略0 通常是轮询方式。如果只有一个从库这个参数影响不大如果有多个从库可以按需调整负载策略。从 Mycat 的角度看ds_master 是逻辑组里的写节点ds_slave1 是逻辑组里的读节点。Mycat 不会自动探测复制状态它默认你配置的主从关系是真实成立的。所以这里再次强调MySQL 层的主从一定先验证好再配 Mycat。3.4 配置逻辑库让应用以逻辑库的方式访问schema 配置决定应用看到的数据库长什么样。Mycat 2 的逻辑库和物理库可以不同名我把逻辑库命名为 shop底层物理库也是 shop但数据节点指向刚才的复制组 shop_rwschemaList: - name: shop dataNode: dn_shop sqlMaxLimit: 1000 dataNodeList: - name: dn_shop replica: shop_rwsqlMaxLimit 是我比较喜欢的一项配置它能让 Mycat 对没有显式 LIMIT 的查询自动加限防止有人手滑执行了一个全表扫描把从库压垮。生产环境我一般建议设置数值按业务情况调整。配置全部改完之后重启 Mycatcd /opt/mycat2 ./bin/mycat restart然后用 MySQL 客户端连一下 Mycatmysql -h 127.0.0.1 -P 8066 -u mycat_user -pYourPassword -D shop能连上并正常执行 SQL说明 Mycat 这一层已经通了。3.5 验证读写分离让流量按预期分流配置完成后如何确认读真的走了从库、写真的走了主库我用了三个方法都很直接第一种看 Mycat 日志。logs 目录下的 mycat.log 会打印 SQL 执行记录里面能看到一条语句被路由到了哪个数据源。执行几条 SELECT 和 INSERT然后去日志里比对就能看到 INSERT 去到 ds_masterSELECT 去到 ds_slave1。第二种看从库的 processlist。在从库上执行SHOW PROCESSLIST;如果 Mycat 正在把读流量发往从库这里能看到来自 Mycat 这台机器的查询连接。配合在应用层刷几个查询接口观察效果非常直观。第三种做一次粗暴但有效的故障模拟直接从库停掉复制或者干脆把从库 MySQL 停掉然后让应用执行查询。如果查询依然能返回结果说明 Mycat 做了故障转移或者降级如果查询报错说明读流量确实依赖从库。注意这种验证要在业务低峰期或者测试环境做别在生产环境突然把从库停了。3.6 应用层切换只改一个连接串Mycat 配置完成后的应用改造说起来非常轻松把 Spring Boot 数据源配置里的 JDBC 地址从真实 MySQL 地址改成 Mycat 的地址即可spring.datasource.urljdbc:mysql://192.168.1.20:8066/shop?useSSLfalseallowPublicKeyRetrievaltrue spring.datasource.usernamemycat_user spring.datasource.passwordYourPassword这里 192.168.1.20 是我部署 Mycat 的机器地址。应用代码一行没改Mapper、Service 层全都原样复用这正是中间件方案的吸引力。4. 联调验证与性能表现读写分离到底值不值4.1 数据一致性验证反复对比主从两端读写分离上线前我最担心的就是 Mycat 把写发到主库后从库因为延迟读不到刚写的数据导致用户看到“数据消失”。联调的时候做了这么一组实验通过应用同时发起写请求和读请求每写完一条数据立刻去查连续跑了几百次观察从库返回的延迟情况。在异步复制默认配置下刚提交的写事务确实可能读不到这是异步复制的固有特性不是配置错误。如果业务要求写后必须能立刻读到我这里有两个思路供参考关键业务查询强制路由到主库。Mycat 的注解机制可以在 SQL 前加注释来指定数据源例如/*#mycat:db_typemaster */ SELECT ...把强一致读的请求打到主库。把复制模式从异步改成半同步。MySQL 的半同步复制会等待至少一个从库确认收到 binlog 后才返回事务提交成功能大幅降低数据丢失概率。MySQL 8.0 已经内置支持通过相关系统变量开启即可。实际业务中绝大多数读多写少场景能容忍零点几秒到几秒的复制延迟核心是你要知道这个延迟存在并针对强一致场景做特殊处理。4.2 压测直观感受读写分离的收益联调通过后我做了简单的读写压测。环境配置是主库和从库各 4 核 8G压测工具用的 sysbench混合读写比例设置成 8:2这符合我们业务实际读多写少的特征。压测方法很简单sysbench oltp_read_write \ --mysql-hostmycat_host \ --mysql-port8066 \ --mysql-usermycat_user \ --mysql-passwordYourPassword \ --mysql-dbshop \ --tables10 \ --table-size1000000 \ --threads50 \ --time300 \ --percentile99 \ run压测结果和单库对比下来同样的并发线程数下读 QPS 有明显提升简单查询为主的场景下读吞吐大约是单库时期的 1.5 到 2 倍。这里不给你一个精确到个位数的数字因为压测结果受表结构、查询复杂度和机器配置影响太大但趋势非常明显读流量被分流后主库的负载下降整体吞吐的瓶颈被推高了一个台阶。如果压测时发现性能提升不明显建议从两个方向排查一是看 Mycat 所在机器有没有成为新的瓶颈毕竟所有 SQL 都经过它转发二是看从库的并发复制能力是否跟得上如果主库写入频繁而复制线程只有一个从库可能会成为短板。第二个问题在后面的延迟章节会展开。4.3 监控主从延迟核心指标与报警阈值读写分离上线后监控主从延迟比做任何优化都重要。最直接的指标就是从库状态里的 Seconds_Behind_Master。我用如下 SQL 封装成监控脚本定时抓取SHOW SLAVE STATUS\G这个值代表从库 SQL 线程当前执行到的事务时间与 IO 线程已拉取到的最新事务时间之间的差距。我给自己定的规则是持续超过 10 秒就要注意超过 30 秒必须处理。毕竟延迟意味着用户读到的是旧数据延迟越大体验越差。需要特别提醒的是Seconds_Behind_Master 在某些情况下会显示 NULL比如从库重连主库期间它不是 0 也不是数字别把这个 NULL 误判成没有延迟。5. 常见问题与排查技巧实录把这些坑提前踩平5.1 部署和连接阶段的问题速查把我在实际部署过程中和身边同事经常遇到的问题整理成了一张表遇到同类问题可以直接对着查现象可能原因排查与解决办法MySQL 报 error 2002 (HY000): Cant connect through socket服务未启动或者客户端用 socket 方式连接先确认 mysqld 进程是否存在如果确认启动客户端连接时显式加 -h127.0.0.1 -P3306强制走 TCPMycat 启动后应用连接报 SSL 连接错误JDBC 连接串缺少 useSSLfalse数据源 url 加上 useSSLfalseallowPublicKeyRetrievaltrueNavicat 或客户端连接 MySQL 8 报认证失败caching_sha2_password 与旧客户端不兼容使用支持该认证的客户端或者创建用户时显式指定 mysql_native_password从库 IO 线程一直 Connecting网络不通、账号权限不对、主机地址填错逐层检查telnet IP 3306 - 检查 repl 账号能否登录 - 检查 CHANGE MASTER 参数Mycat 连接池连接耗尽maxCon 配置过小应用并发连接数量超出调大数据源 maxCon同时检查应用侧连接池是否有连接泄漏从库只读配置不生效业务账号以超级权限连接使用 super_read_onlyON 加强限制并确认业务账号确实不是超级权限5.2 复制最常见的两种中断主键冲突和位点错误先说主键冲突。我遇到过最典型的场景是从库被人工插入了一条 id100 的数据然后主库插入同 id 数据复制 SQL 线程执行到这条时直接报 Duplicate entry 100 for key PRIMARYSlave_SQL_Running 变成 No。处理步骤我当时是这样做的# 1. 先看具体错误 SHOW SLAVE STATUS\G如果确认是主键冲突先判断冲突数据到底是哪边不该有。如果是从库多了垃圾数据直接在从库手动删掉然后START SLAVE;如果只是临时业务原因且冲突无关紧要也可以通过跳过错误来恢复。但这里必须提醒跳过复制错误是有风险的它意味着从库会永久漏掉一个事务很可能造成后续数据不一致。不到万不得已不要用。再讲位点错误。在非 GTID 模式下如果主库的 binlog 格式变化、主库执行了 RESET MASTER 或者 binlog 被清理从库会报 Got fatal error 1236。遇到这种情况最简单的方案是重新搭建从库。不要试图去翻旧日志找位点耗时且容易出错直接用 mysqldump 重新初始化从库比修补快得多。当然如果你已经启用了 GTID这类问题会少很多这也是我一直推荐 GTID 的根本原因。5.3 从库延迟持续增长先分清瓶颈再动手从库延迟偏高时不要盲目加资源。我排查延迟的思路一般是按顺序来先看从库机器负载如果磁盘 IO 或 CPU 已经打满优先在硬件层面或者减少读流量上想办法再检查是否有大事务比如一条 UPDATE 影响几十万行这种事务在主库执行可能几秒在从库回放同样的时间延迟自然会被拉大最后看复制线程配置如果从库还在用默认的单线程复制而主库写入并发很高可以开启并行复制。MySQL 8.0 的并行复制配置相对简单相关系统变量可以关注 binlog_transaction_dependency_tracking默认可能是 COMMIT_ORDER可以按实际情况调整。这个方向能解决一部分高并发写入场景下的延迟问题但不是万能药大事务和慢 SQL 造成的延迟还是得从业务层面拆解。5.4 主从数据不一致之后的修复思路延迟只是表象真正可怕的是数据永久不一致。如果真的发现主从数据对不上我的建议是一步到位重建从库。用主库的备份重新初始化从库然后让从库重新开始复制比在从库上改数据要可靠得多。改从库数据只适合明确知道差异点且差异很小的场景否则改错一处后面又是无穷无尽的不一致。重建从库的大致流程是主库做一次全量备份导入从库然后清空从库的复制状态重新 CHANGE MASTER。如果数据量小这个方法十分钟内就能完成。顺便说一句在做数据校验时我可以使用 pt-table-checksum 这类工具定位差异这比随机抽样靠谱得多。5.5 一些必须提前说清楚的运维规矩最后补充几条我踩过坑之后定下来的规矩不要随手开 slave-skip-errors。这个参数能跳过很多复制错误但也掩盖了真正的问题。它会让从库在遇到异常时直接忽略后续数据不一致的时候你根本不知道从哪一秒开始对不上。从库要长期保持只读状态。我见过有人为了方便在从库执行报表 SQL 时把从库的只读关掉然后忘记打开。业务账号一旦误写从库轻则主键冲突中断复制重则两边数据分叉最后只能重建。Mycat 配置文件改动前先备份。Mycat 2 版本迭代过程中配置文件格式有过调整升级或者改动配置时拿 conf 目录里的示例文件做模板别凭记忆直接写。我们曾经因为一个字段命名和版本对不上导致复制组起不来排查了很久才发现是配置项名字差异。最后说几句实际操作层面的体会整套流程走完之后我最大的感受是读写分离这件事难点不在于 Mycat 的安装和配置而在于你愿不愿意在建从库、监控延迟、处理复制错误上花功夫。Mycat 2 只是个 SQL 路由器它把流量分得再漂亮底层主从数据不同步、不一致上层什么架构都白搭。所以我的建议是先把 MySQL 主从同步验收得明明白白再上 Mycat 2最后再改应用连接串。现在我再接新项目前期一定会先确认三件事业务到底读多写少到什么程度、能否接受主从延迟、有没有一套延迟监控和报警。想清楚这几个问题再动手搭建你会少走很多弯路。