
说实话在容器化和Ansible已经普及的今天还写zabbix源码安装多少有点“逆版本而行”的味道。官网明明把rpm包、deb包、容器镜像全给你备好了一条yum install就能把server拉起来为什么还要下载tarball一行行configure、make、make install答案其实很现实很多生产环境并没有那么幸福。有的是内网隔离没法访问外网yum仓库有的是对编译参数有特殊要求比如需要开启某些SNMP驱动或者指定安装路径还有的是要装到国产化系统或者特定的Linux发行版上官方仓库根本没有对应版本。再加上zabbix的整个体系涉及server、agent、前端PHP、数据库四个部分一旦某个环节需要定制用源码包从头走一遍反而是最可控的方式。这篇文章就按我实际部署的完整路径来写从依赖准备、MySQL 8源码安装、Zabbix Server编译、前端Nginx部署到Agent配置尽量把每一步背后的原因也讲清楚。内容比较长建议先收藏再往下看。1. 为什么放着现成的rpm不用偏要源码编译1.1 源码安装的适用场景如果你只是在自己的测试机上随便玩一玩确实没必要源码编译。yum install之后系统把所有依赖都帮你处理好了省时省力。但你一旦遇到下面这几种情况就会发现包管理器的方案根本走不通内网环境没有外网源rpm包虽然能手动下载但依赖关系能把人折腾死更直接的办法是预先在一台有网的机器上把所有rpm包拉下来再进内网装。官方rpm只提供固定的编译选项比如你想让zabbix_server支持更多的监控协议或者需要把某些驱动静态编译进去就只能从源码包配置。系统版本比较老或者比较偏比如CentOS 6、国产化Linux发行版官方源里没有对应版本。定制的安装路径比如公司规定软件必须装在/opt或者/data目录下二进制包虽然能用软链但还是不如编译时指定prefix干净。源码安装的本质不是“不能用包管理器”而是“包管理器解决不了的场景源码包是最后兜底的方案”。它让你对zabbix每个组件是什么、依赖什么、配置在哪、日志写在哪都一清二楚出了问题也更容易排查。1.2 源码安装的“坑”在哪儿源码安装最大的问题不是难而是繁琐。zabbix是C/S架构server端依赖的库特别多缺一个configure就报错。数据库方面如果你没有现成的MySQL或PostgreSQL还要额外解决。前端是PHP写的PHP版本、扩展、时区配置都有讲究。另外编译时间取决于机器配置。在2核4G的云主机上make -j4编译zabbix server大概需要5到10分钟MySQL 8的源码编译可能需要20分钟以上。这些心理准备先做好后面遇到报错就不会慌。2. 环境准备编译工具、依赖库与数据库三件套2.1 编译工具链和依赖库我这次的部署环境是CentOS 7.9内核3.10虽然有点老但在存量市场里占比依然很高。开始之前先把编译组件装齐yum install -y gcc gcc-c make autoconf automake pkgconfig然后装zabbix server编译时的核心依赖库yum install -y libevent-devel net-snmp-devel libcurl-devel libxml2-devel这几个库分别对应什么我简单说明一下。libeventzabbix server内部事件处理依赖的高性能网络库没有它connection处理都会出问题。net-snmpSNMP协议支持监控交换机、路由器、网络打印机基本上都靠它。libcurlHTTP请求支持用于Web监控、外部检查等。libxml2XML解析监控VMware时要用到这个库。如果你要装Agent端依赖会少很多只需要libpcre或pcre2的开发库因为agent的配置和数据采集逻辑对库的依赖要比server简单。对于zabbix 7.0版本还需要yum install -y pcre2-develzabbix 6.0和7.0默认使用PCRE2作为正则表达式库如果你不装configure会直接报错找不到PCRE2。2.2 数据库准备以MySQL 8源码安装为例zabbix的元数据、监控历史数据、趋势数据全都要落到数据库里。官方支持MySQL、PostgreSQL、SQLite仅用于proxy。生产环境用得最多的还是MySQL。这次我顺便把MySQL 8的源码安装也走了因为热词里反复提到“centos7源码安装mysql8”这说明很多人在做zabbix部署时数据库本身也是裸的。MySQL 8源码需要下载两个东西源码包和boost库。MySQL源码编译必须要boost库这个问题让不少新手卡了很久。wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.36.tar.gz wget https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.gz编译前需要安装一些额外的依赖yum install -y cmake ncurses-devel bison openssl-devel然后开始cmake配置tar -zxvf mysql-8.0.36.tar.gz tar -zxvf boost_1_77_0.tar.gz mv boost_1_77_0 /usr/local/boost cd mysql-8.0.36 cmake . \ -DCMAKE_INSTALL_PREFIX/usr/local/mysql \ -DDEFAULT_CHARSETutf8mb4 \ -DDEFAULT_COLLATIONutf8mb4_bin \ -DWITH_BOOST/usr/local/boost \ -DFORCE_INSOURCE_BUILD1 make -j4 make install这里有一个小技巧cmake的输出信息会清清楚楚显示每个检查项是否通过比如OpenSSL版本、ncurses库是否存在。如果某个依赖缺失直接根据提示安装即可。不用像autoconf那样去猜哪里出错。MySQL 8初始化时有个坑8.0版本在初始化时不会再像5.7那样随机生成root密码并输出日志而是完全静默初始化需要自己指定认证方式。建议用useradd -r -s /sbin/nologin mysql mkdir -p /usr/local/mysql/data chown -R mysql:mysql /usr/local/mysql /usr/local/mysql/bin/mysqld --initialize-insecure --usermysql --basedir/usr/local/mysql --datadir/usr/local/mysql/data--initialize-insecure的意思是生成一个root空密码账号方便第一次登录。然后写一个简单的my.cnf[mysqld] basedir/usr/local/mysql datadir/usr/local/mysql/data socket/tmp/mysql.sock pid-file/tmp/mysql.pid port3306 character-set-serverutf8mb4启动MySQL后再把它注册成systemd服务或者写进rc.local这个看个人习惯。2.3 为Zabbix创建数据库和账号MySQL启动之后接下来就是建库建用户。这一步是有标准模板的直接照抄mysql -uroot -p CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE USER zabbixlocalhost IDENTIFIED BY YourStrongPassword; GRANT ALL PRIVILEGES ON zabbix.* TO zabbixlocalhost; FLUSH PRIVILEGES; QUIT这里有个注意事项数据库的字符集一定要用utf8mb4不要用utf8。因为Zabbix在存储一些多字节字符或者emoji时utf8mb4更稳妥。另外如果你用的是MySQL 8默认的认证插件是caching_sha2_passwordzabbix 6.0以上默认支持但如果你正在使用zabbix 5.0或者更早版本需要在创建用户时指定mysql_native_passwordCREATE USER zabbixlocalhost IDENTIFIED WITH mysql_native_password BY YourStrongPassword;这个问题我当年第一次部署时踩过zabbix_server启动后一直报无法连接数据库查了好多资料才发现是认证插件不兼容。3. Zabbix Server端源码编译全流程3.1 下载源码包与configure参数详解源码包从官网的SourceForge或者GitHub仓库都可以下载。我这次顺手测试了两个版本zabbix-6.0.32和最新的7.0.4。7.0版本在界面上改版不小但在源码安装流程上差异不大关键是依赖要提前满足。wget https://cdn.zabbix.com/zabbix/sources/stable/7.0/zabbix-7.0.4.tar.gz tar -zxvf zabbix-7.0.4.tar.gz cd zabbix-7.0.4然后就是重头戏——configure。这一步是整个源码安装里最容易出错的环节。我先给出我最终使用的参数再逐项解释./configure \ --prefix/usr/local/zabbix \ --enable-server \ --enable-agent \ --with-mysql/usr/local/mysql/bin/mysql_config \ --with-net-snmp \ --with-libcurl \ --with-libxml2 \ --with-libpcre2先说明--prefix。这个参数指定安装目录默认是/usr/local也就是说zabbix_server会装到/usr/local/sbin下面。我这里指定到/usr/local/zabbix好处是所有Zabbix相关文件都放在同一个目录下后续升级或者卸载比较方便。再说--enable-server和--enable-agent。这两个开关会同时编译出zabbix_server和zabbix_agentd。如果你只需要装server可以只加--enable-server但实际工作中还是两个都编上因为Agent在排查问题时经常要用到。最后是那一堆--with-*参数。这里有个很容易踩的坑--with-mysql后面如果没有指定路径它默认会去PATH里找mysql_config。如果你用了非标准路径安装MySQL或者MySQL是源码安装的就必须明确指出来否则configure会报错“MySQL library not found”。3.2 编译安装与配置文件的生成configure通过之后会生成Makefile文件。然后执行make编译make -j4这里的-j4表示用4个线程并行编译能明显缩短编译时间。但也要注意并行编译会比较吃内存2G内存的小机器建议用-j2否则有可能会出现编译进程被OOM杀掉的情况。编译完成后执行make install它会把二进制文件、配置文件模板以及脚本都安装到/usr/local/zabbix下面。查看一下安装结果ls -l /usr/local/zabbix/sbin/ ls -l /usr/local/zabbix/etc/正常情况下sbin下会有zabbix_server和zabbix_getetc下会有zabbix_server.conf模板等文件。安装完成后需要创建zabbix运行用户并导入数据库groupadd --system zabbix useradd --system -g zabbix -s /sbin/nologin zabbix导入数据库时需要注意数据库schema文件的位置。在源码包的database/mysql目录下mysql -uroot -p zabbix database/mysql/schema.sql mysql -uroot -p zabbix database/mysql/images.sql mysql -uroot -p zabbix database/mysql/data.sql这三个文件里面schema是建表语句images是图形相关的默认图片data是默认模板、主机组、监控项等基础数据。导入顺序不能乱而且导入时要指定数据库名zabbix否则会导入到默认数据库。导入数据量不大正常几秒就完成。3.3 启动服务前的必备检查导入完成后把配置文件从模板复制成正式文件cp /usr/local/zabbix/etc/zabbix_server.conf /usr/local/zabbix/etc/zabbix_server.conf.bak然后把关键参数改好LogFile/var/log/zabbix/zabbix_server.log DBHostlocalhost DBNamezabbix DBUserzabbix DBPasswordYourStrongPassword这里有个小细节如果日志目录没有创建服务启动会失败日志本身会打印“cannot open log file”。先创建好目录并授权mkdir -p /var/log/zabbix chown zabbix:zabbix /var/log/zabbix然后用命令行直接启动测试/usr/local/zabbix/sbin/zabbix_server -c /usr/local/zabbix/etc/zabbix_server.conf启动后立刻查看日志tail -f /var/log/zabbix/zabbix_server.log正常会输出类似“starting Zabbix server”和“server started”的日志如果看到数据库连接错误或者配置错误根据提示修改即可。确认启动无误后建议注册systemd服务方便开机自启。在/etc/systemd/system/zabbix-server.service写入[Unit] DescriptionZabbix Server Aftermysql.service [Service] Userzabbix Groupzabbix ExecStart/usr/local/zabbix/sbin/zabbix_server -c /usr/local/zabbix/etc/zabbix_server.conf Restartalways [Install] WantedBymulti-user.target配置完成后执行systemctl daemon-reload systemctl enable zabbix-server systemctl start zabbix-server4. 前端部署从PHP到Nginx的落地细节4.1 拷贝PHP代码与目录权限zabbix的前端代码在源码包的ui目录下。很多人第一次装的时候会一头雾水以为前端需要单独编译其实不用前端就是一堆PHP文件直接拷贝到Web目录就能用。mkdir -p /var/www/html/zabbix cp -r ui/* /var/www/html/zabbix/如果你用的是Nginx还需要确认PHP-FPM已经装好。CentOS 7默认的PHP版本是5.4但zabbix 7.0要求PHP 7.4以上更推荐PHP 8.0及以上。这里我用的remi源安装PHP 8.1yum install -y epel-release yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm yum install -y yum-utils yum-config-manager --enable remi-php81 yum install -y php php-fpm php-mysqlnd php-gd php-bcmath php-mbstring php-xml php-ldap这些PHP扩展里面最关键的是php-mysqlnd没有它前端连不上数据库php-gd是Zabbix画图功能依赖的库不装的话图形界面会报错php-bcmath则在部分计算场景下需要。4.2 Nginx和PHP-FPM配置要点PHP装好后需要调整php.ini里的几个参数。zabbix安装向导会在前端检查这些参数不满足会提示但最好现在就直接改date.timezone Asia/Shanghai max_execution_time 300 max_input_time 300 memory_limit 256M post_max_size 16M upload_max_filesize 2M重点说下date.timezone。如果不设置时区PHP会抛warningzabbix前端安装向导会把这一项标红导致无法继续。所以一定要提前配好。PHP-FPM默认监听的可能是127.0.0.1:9000这个保持默认即可。启动并设置开机自启systemctl start php-fpm systemctl enable php-fpmNginx的站点配置如下server { listen 80; server_name zabbix.example.com; root /var/www/html/zabbix; index index.php index.html; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }这里的location匹配PHP请求时fastcgi_param的SCRIPT_FILENAME一定要正确。如果root路径配错了前端打开会直接返回空白页。配置完成后重载Nginxnginx -t systemctl reload nginx4.3 通过浏览器完成初始化在浏览器里访问http://你的服务器IP/zabbix就能看到zabbix的安装向导。向导会检查PHP环境、数据库连接、文件权限等其中有一个比较关键的要求是conf目录必须可写。chmod -R 777 /var/www/html/zabbix/conf注意这一步是安装向导要求的临时权限安装完成后最好把conf目录恢复到755。如果不恢复会有安全隐患。向导中填写数据库信息时需要填数据库主机、端口、用户名、密码和数据库名。填好后提交系统会自动导入所需的初始数据并生成zabbix.conf.php配置文件。安装完成后默认登录账号是Admin密码是zabbix首次登录后建议立刻修改密码。到这里zabbix的Server端和前端就都完成了。5. Agent端源码编译与监控链路验证5.1 Agent源码编译和配置server端装好之后还要在需要监控的机器上装Agent。Agent端的编译要比Server简单得多依赖也少很多。如果你已经有了zabbix源码包在源码包目录下直接编译./configure --prefix/usr/local/zabbix --enable-agent make -j4 make installAgent的配置文件在/usr/local/zabbix/etc/zabbix_agentd.conf需要修改下面几个参数Serverzabbix-server的IP ServerActivezabbix-server的IP Hostname被监控机器的主机名Server参数是允许哪个IP的zabbix_server来获取Agent数据ServerActive是Agent主动上报数据时连接的server地址。Hostname必须和zabbix Server前端添加主机时设置的主机名保持一致否则数据会采集不到。5.2 服务端与代理端连通性验证Agent启动后可以先用zabbix_get验证连通性/usr/local/zabbix/bin/zabbix_get -s 192.168.1.100 -k agent.ping这里-s指定Agent的IP-k指定要获取的监控项键值。如果返回一个数字1说明Agent正常如果返回空或者提示timeout就要检查防火墙是否放行了10050端口。另外zabbix_server默认只监听10051端口Agent默认监听10050端口两个端口在防火墙上都要放行。如果使用systemd管理Agent也可以参考Server的方法写一个zabbix-agent.service单元文件。没有systemd的老系统直接改/etc/rc.local即可。6. 高频故障排查从configure到history syncer6.1 configure阶段缺依赖、缺路径源码安装过程中configure阶段是最容易报错的。常见的几种情况我列在下面。第一种是configure: error: MySQL library not found。这个报错一看就知道是MySQL开发库没装或者mysql_config的路径不对。解决方法是在--with-mysql参数后面明确指定mysql_config的完整路径同时确认mysql-devel确实安装了。第二种是configure: error: LIBXML2 library not found。这个简单就是libxml2-devel没装直接yum安装即可。第三种是configure: error: condition pcre2 is not met。这是zabbix 6.0之后典型的问题需要安装pcre2-devel。6.2 运行阶段数据库连接、时区、性能告警数据库连接问题是第二阶段最常见的。zabbix_server启动时报“Access denied for user zabbixlocalhost”基本就是认证插件或密码问题。MySQL 8下建议创建用户时指定mysql_native_password或者在my.cnf中配置default_authentication_pluginmysql_native_password。还有一个比较隐晦的问题zabbix_server启动后日志显示“database is not up to date”。这是因为源码包里的SQL文件没有正确导入或者导入顺序乱了。解决办法是重新按schema、images、data的顺序导入一次。性能方面热词里那个“zabbix server: utilization of history syncer processes over 75%”是非常典型的告警。这个告警的意思是历史数据同步进程的繁忙率超过了75%说明数据库写入跟不上数据采集速度了。常见的优化思路如下在zabbix_server.conf里调大HistoryCacheSize和TrendCacheSize。默认是16M/4M可以先改成64M/16M观察效果。优化MySQL调大innodb_buffer_pool_size。对于只有Zabbix业务的机器可以设为物理内存的50%到70%。清理历史数据压缩保留周期。把History Storage周期从30天缩短到7天Trends从365天缩短到90天。如果数据量实在大建议把Partition表结构用上或者干脆迁移到TimescaleDB。这个告警的本质是“写入瓶颈”所以单纯调高配置不一定能解决需要先确认瓶颈在数据库还是磁盘IO再针对性处理。6.3 常见问题速查表我把部署过程中最容易遇到的一批问题整理成了速查表供你直接对照排查。现象原因解决办法configure报C compiler cannot create executables缺gcc或makeyum install -y gcc gcc-c makeconfigure报MySQL library not found缺mysql-devel或未指定路径安装mysql-devel--with-mysql指向mysql_config路径configure报LIBXML2 not found缺libxml2-develyum install -y libxml2-develconfigure报PCRE2 not met缺pcre2-develyum install -y pcre2-develzabbix_server启动失败配置错误或日志目录不存在查看/var/log/zabbix/zabbix_server.log逐项排查Access denied for user zabbix数据库密码错误或认证插件不兼容重新GRANT并指定mysql_native_password前端打不开返回空白页Nginx的SCRIPT_FILENAME错误检查fastcgi_param配置和root路径history syncer processes over 75%数据库写入慢或缓存参数小调大缓存参数优化数据库配置agent采集不到数据防火墙未放行或Hostname不匹配放行10050/10051端口检查Hostname7. 装完之后还能做什么钉钉告警、交换机与VMware扩展7.1 钉钉告警配置思路zabbix原生的告警媒介是邮件但在国内环境里钉钉、企业微信机器人的使用频率反而更高。源码安装的好处是前端目录完全自己掌控告警脚本放哪里都不会被包管理器覆盖。在“报警媒介类型”中创建一个自定义的媒介类型脚本类型选择“脚本”然后准备一个调用钉钉Webhook的Python或Shell脚本。脚本接收三个参数收件人和告警消息内容然后通过curl POST到钉钉机器人地址。import json, requests, sys webhook https://oapi.dingtalk.com/robot/send?access_tokenxxxx message {msgtype: text, text: {content: sys.argv[1]}} requests.post(webhook, jsonmessage)在“用户”中把这个媒介类型分配给用户并在“动作”里配置触发条件比如故障级别为“严重”或“灾难”时发送。配置好后可以手动发送测试消息验证端到端链路。7.2 SNMP监控交换机的准备监控交换机本身和源码安装的关系不大但你在编译zabbix server时如果带了--with-net-snmp就说明已经支持SNMP了。配置交换机监控时需要做两件事第一在交换机上开启SNMP服务并设置只读团体名或SNMP v3用户。如果交换机连接了无线AP比如热词里提到的Cisco 8540无线控制器那么在zabbix里添加主机时只要通过SNMP和无线控制器的IP再关联Cisco Wireless Controller模板就能把下面的AP在线数、客户端数量、信道利用率监控起来。第二在zabbix前端添加主机时SNMP接口填交换机的IP然后关联“Template Network Generic by SNMP”模板。这个模板会自动发现接口、CPU、内存等信息。需要注意不同厂商的设备SNMP OID可能有差异如果模板里某些监控项没有数据需要排查站点的SNMP版本和OID是否正确。7.3 VMware监控的额外配置如果你想把VMware vCenter或ESXi主机纳入监控源码安装时就需要带上--with-libxml2因为vmware监控的数据来源是SOAP接口需要解析XML响应。另外还需要在zabbix_server.conf里配置StartVMwareCollectors2 VMwareFrequency60 VMwareCacheSize8M然后在zabbix前端“管理-一般-VMware”里填上vCenter的地址、账号、密码和虚拟机唯一标识。Zabbix会自动发现vCenter下面的宿主机、虚拟机、Datastore等对象。注意vCenter账号建议使用只读权限不需要管理员权限。8. 离线环境部署的经验补充8.1 离线依赖包准备很多生产环境是不允许访问外网的这时候“zabbix离线部署”就很关键。源码安装本身适合离线环境因为只要把源码包传进去剩下的就是本地编译。但依赖库怎么解决是个问题。最好的方案是准备一台和目的服务器同版本、同架构的机器用yumdownloader把需要的依赖全部下载下来yum install -y yum-utils yumdownloader --resolve --destdir/tmp/zabbix-rpms \ gcc gcc-c make libevent-devel net-snmp-devel libcurl-devel libxml2-devel \ pcre2-devel php php-fpm php-mysqlnd php-gd php-bcmath php-mbstring php-xml php-ldap把/tmp/zabbix-rpms整个目录打包拷进内网然后执行yum install -y /tmp/zabbix-rpms/*.rpm这样依赖就全部解决了。注意不同系统版本依赖可能不一样一定要用同系统版本的最小机器来下载依赖。8.2 离线安装的注意事项离线安装还有几个经验值得说。一是源码包和数据库安装包要提前准备好包括MySQL的源码包、boost库、zabbix源码包。二是PHP的离线安装比较麻烦如果remi源里的PHP版本没法直接用yumdownloader拉全可以考虑直接用PHP官方源码包编译但这会加大工作量。三是离线环境下不要轻易使用最新版本因为最新版本依赖关系更复杂旧版本的依赖相对稳定。另外在离线机器上执行yum安装本地rpm包时如果出现依赖冲突可以加上--setoptskip_missing_names_on_installTrue但这个命令只是跳过了包名不存在的检查真正的依赖冲突还是要手动解决。9. 与Prometheus的选型对比Zabbix和普罗米修斯区别9.1 定位与架构差异装完Zabbix之后很多人会问它和Prometheus到底怎么选。这两个都属于开源监控领域的主流方案但设计思路差异很大。Zabbix的核心思路是“主动采集集中存储”。你装一个Agent在服务器上然后由Server端按设定的频率去轮询取值或者Agent主动上报。数据存在MySQL/PostgreSQL里自带告警、图形、报表开箱即用。它特别适合传统的服务器、网络设备、VMware虚拟化环境的监控。Prometheus的核心思路是“Pull模型时序数据库”。它自己去各个目标拉取指标数据每个被监控对象暴露一个HTTP接口就行。它的原生语言是Go对容器的自动发现支持非常成熟特别适合Kubernetes、微服务架构下的监控。但它本身没有“告警媒介”概念告警依赖AlertManager去分发图形也需要搭配Grafana。9.2 选型建议我的个人看法是如果当前监控对象主要是物理机、VMware虚拟机、交换机、UPS等传统IT基础设施Zabbix的成熟度和低成本优势非常明显。如果监控对象是容器化应用并且希望以指标为中心做统一采集那Prometheus是更合适的选择。两者也可以并存Zabbix管基础设施Prometheus管应用和容器。对比项ZabbixPrometheus采集方式Server轮询Agent主动上报服务端主动Pull指标数据存储MySQL/PostgreSQL/TimescaleDB自带TSDB时序数据库告警分发内置多种媒介邮件、钉钉、脚本AlertManager配合配置UI图形自带图形模板通常搭配Grafana容器云原生支持一般需要额外适配原生支持自动发现机制强网络设备监控天然支持SNMP需要exporter辅助学习曲线中等自带界面引导较陡配置以yml为主10. 最后说几句实在话从我个人的使用体验来说zabbix源码安装这条路虽然绕远但走一次之后你对这套系统的依赖关系、运行原理、配置结构都会建立起肌肉记忆。以后再遇到打包安装方式解决不了的问题你会清楚问题可能出在哪一层。最后再分享一个小技巧每次编译完把configure参数、依赖包的版本号、数据库初始化命令都记到一个install.md文件里。下次升级版本或者换个机器重新部署时直接对着文档操作比重新回忆要省几倍时间。这个习惯帮我避开了很多坑希望对你也一样。