ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Discuz迁移实战:从LNMP到LNAMP与Nginx动静分离部署笔记

Discuz迁移实战:从LNMP到LNAMP与Nginx动静分离部署笔记 最近朋友找我迁移一套 Discuz 论坛开口就问到底是 LNMP 还是 LNAMP这个问题看起来很基础但真正动手配置过的人都知道里面藏着不少门道。我从一开始就在一台 CentOS 7 机器上从零搭建 LNAMP到把论坛跑起来、再一步步把 Nginx 动静分离做出来前后踩了不少坑。这篇就当是我的完整操作笔记把从选型、编译、部署到验证的所有环节都捋一遍也给正准备折腾 LNMP/LNAMP 和 Discuz 的朋友一个可以直接抄的参考。先说个结论如果你的站点是 Discuz 这类老牌 PHP 程序或者是从虚拟主机、Apache 环境迁移过来的LNAMP 往往比单纯 LNMP 更稳如果追求极致性能、又愿意折腾各类伪静态规则转换LNMP 也完全够用。但不管选哪种动静分离这件事早晚都要做因为 Nginx 天生就是干这个的。1. 动手前先做一道选择题LNMP、LAMP和LNAMP各什么时候用1.1 三套架构的本质差异很多人把 LNMP、LAMP、LNAMP 当成三种“安装方法”其实它们对应的运行链路完全不同架构处理链PHP 执行方式静态文件处理典型场景LAMPLinux Apache MySQL PHPApache 的 mod_php 模块Apache 自身老虚拟主机、迁移老站LNMPLinux Nginx MySQL PHPNginx 转发给 PHP-FPMNginx新站、接口服务、并发高LNAMPLinux Nginx Apache MySQL PHPNginx 转发给 ApacheApache 通过 mod_php 执行NginxDiscuz 老站、依赖 .htaccess 的程序LAMP 的问题在于 Apache 对并发静态请求的承载能力偏弱一个静态文件请求和一个 PHP 请求在 Apache 里都要走整套进程池很容易把进程占满。LNMP 把 Nginx 放到最前面高并发静态请求被 Nginx 这个轻量级选手直接拦下PHP 才由 PHP-FPM 单独处理性能差距非常明显。但 LNMP 下 PHP-FPM 是独立进程不再依赖 Apache 的 .htaccess 规则很多老程序、老插件的伪静态规则没法直接照搬需要转写成 Nginx 格式规则一多就容易出幺蛾子。LNAMP 的定位正好卡在两者之间Nginx 在最前挡静态Apache 躲在后端跑动态。它保留了 mod_php 的模式Discuz 那种依赖 Apache 环境的历史包袱可以直接继承伪静态规则、目录权限、老插件的行为都跟以前一样迁移成本最低。代价是 Nginx 转发动态请求多了一层代理PHP 执行效率比纯 LNMP 低一点但换来的是不需要反复调整程序代码的兼容性。1.2 为什么老 Discuz 站点优先考虑 LNAMPDiscuz 在老站长圈子里已经存在了十几年很多站点的插件、模板、数据都是从最初就一直在迭代的。这类站点对 PHP 执行环境非常敏感最常见的问题就是伪静态规则Discuz 后台开启静态化之后URL 会变成/thread-1-1-1.html这种形式Apache 下面只要一个.htaccess就能处理但搬到 Nginx 环境就要把 RewriteRule 一条条转成location或rewrite语法。偶尔遇上一个插件里带了自己的一套 RewriteRule就会跟你现有的规则打架。所以在帮朋友迁移时我直接选择了 LNAMP。这样伪静态规则仍然放在 Apache 层面处理Discuz 后台怎么开、插件怎么配置行为跟原来一模一样。Nginx 就专注一件事把所有非静态文件请求转发给 Apache同时把图片、CSS、JS 直接吃掉。架构清晰后期排查也不用在一个 Nginx 配置里翻几百行 rewrite 规则。1.3 我的 LNAMP 拓扑与端口规划动手之前先把完整拓扑定下来省得后面配置乱了。用户请求 - Nginx (80端口) ├── .jpg/.css/.js 等静态文件Nginx 直接在本地找找到就返回 ├── /forum.php 或 /thread-1-1-1.html 动态请求proxy_pass 转发 └── Apache (127.0.0.1:8080) - PHP(module) - MySQL(3306)端口规划说明Nginx 对外监听 80Apache 只监听127.0.0.1:8080不让外部直接访问。这样做的好处是用户没法绕过 Nginx 直接打到 Apache静态安全风险少一半也方便以后在 Nginx 上统一加缓存、限流、防盗链。2. CentOS 7 建站前的基础准备编译依赖与安全策略2.1 为什么我这里坚持源码编译而不是 yum 一把梭CentOS 7 自带的 yum 源里PHP 是 5.4MySQL 已经换成了 MariaDBNginx 版本也偏老编译开关全是默认的想加个--with-http_stub_status_module这种扩展都得自己折腾。Discuz X3.4 在 PHP 5.4 下能跑但功能和安全性都已经落后了。源码编译的好处是可定制、版本可控、目录位置自己说了算坏处是耗时间、依赖要自己补齐。对于要长期维护的论坛站点我宁可第一天多花点时间编译也懒得三个月后因为扩展不够用再重装一遍。编译前先把工具链装好yum install -y epel-release yum groupinstall -y Development Tools yum install -y pcre pcre-devel zlib zlib-devel openssl openssl-devel \ libxml2-devel libcurl-devel libpng-devel libjpeg-turbo-devel \ freetype-devel gcc-c wget vim lrzsz net-tools机子内存如果只有 1G建议先加 2G swap不然编译 PHP 时可能直接被 OOM 干掉。编译版本我选的是nginx-1.24.0、httpd-2.4.58、apr-1.7.4、apr-util-1.6.3、mysql-5.7.44、php-7.4.33、Discuz X3.4。MySQL 这里不折腾源码编译直接下载官方二进制通用包生产环境完全够用后面会细说。2.2 关闭 SELinux、放行端口与切换 yum 源CentOS 7 默认 SELinux 是 enforcing它对 Apache 写目录这类行为限制很严我们用源码编译的路径它也不认识最容易出各种 403 和 Cannot write 错误。要么学会写 SELinux 策略要么建站初期直接关掉。既然目标是快速把环境搭起来我先关掉它setenforce 0 sed -i s/^SELINUXenforcing/SELINUXdisabled/ /etc/selinux/config getenforce防火墙放行 80同时 8080 不需要对外开但确保本机回环访问没问题firewall-cmd --permanent --add-port80/tcp firewall-cmd --reload yum makecache fast3. 源码编译四兄弟Nginx、Apache、MySQL、PHP逐个安装并验证这一步是整个部署里最耗时间、也最容易出问题的部分。我按照 Nginx - Apache - MySQL - PHP 的顺序装因为编译 PHP 时需要用到 Apache 的apxs工具来生成libphp7.so所以 Apache 必须先就位。3.1 Nginx 编译参数与服务启动Nginx 的编译参数不用追求多够用、简洁、容易维护就好。Discuz 站点必须要带的是 SSL、gzip、stub_status 和正则wget http://nginx.org/download/nginx-1.24.0.tar.gz tar zxvf nginx-1.24.0.tar.gz cd nginx-1.24.0 ./configure \ --prefix/usr/local/nginx \ --with-http_ssl_module \ --with-http_gzip_static_module \ --with-http_stub_status_module \ --with-pcre \ --with-stream make -j2 make install安装完成后写一个 systemd 服务文件方便用systemctl统一管理vi /usr/lib/systemd/system/nginx.service[Unit] Descriptionnginx server Afternetwork.target [Service] Typeforking PIDFile/usr/local/nginx/logs/nginx.pid ExecStart/usr/local/nginx/sbin/nginx ExecReload/usr/local/nginx/sbin/nginx -s reload ExecStop/usr/local/nginx/sbin/nginx -s quit [Install] WantedBymulti-user.target启动并验证systemctl daemon-reload systemctl start nginx systemctl enable nginx curl http://127.0.0.1/这里有个坑CentOS 7 自带的 gcc 版本是 4.8.5编译新版 Nginx 没问题但后面编译 PHP 7.4 时如果报编译器太老的错误需要装一个 Software Collections 里的新 gcc。我先提前做好这一步免得编译到一半卡住yum install -y centos-release-scl yum install -y devtoolset-7 scl enable devtoolset-7 bashdevtoolset-7会切换当前 shell 的 gcc 版本编译完 PHP 后退出就不影响系统其它内容。3.2 Apache 2.4 编译让 PHP 以模块方式运行的关键点Apache 编译依赖 apr 和 apr-util不能直接用系统自带的版本最好按源码方式装到统一目录wget https://mirrors.edge.kernel.org/pub/software/network/apache/apr-1.7.4.tar.gz wget https://mirrors.edge.kernel.org/pub/software/network/apache/apr-util-1.6.3.tar.gz wget https://archive.apache.org/dist/httpd/httpd-2.4.58.tar.gz tar zxvf apr-1.7.4.tar.gz cd apr-1.7.4 ./configure --prefix/usr/local/apr make make install tar zxvf apr-util-1.6.3.tar.gz cd ../apr-util-1.6.3 ./configure --prefix/usr/local/apr-util --with-apr/usr/local/apr make make install然后编译 Apachetar zxvf httpd-2.4.58.tar.gz cd httpd-2.4.58 ./configure \ --prefix/usr/local/apache \ --with-apr/usr/local/apr \ --with-apr-util/usr/local/apr-util \ --enable-so \ --enable-rewrite \ --enable-mods-sharedmost make -j2 make install--enable-so必须开否则后面 PHP 的--with-apxs2没法生成动态模块。--enable-rewrite给 Discuz 伪静态准备着。编译完随便改一个/usr/local/apache/conf/httpd.confServerName bbs.example.com:80 User apache Group apache Listen 127.0.0.1:8080Listen 这行一定改成127.0.0.1:8080这是让 Apache 只服务内部、不对外暴露的关键。先把用户建好useradd -M -s /sbin/nologin apache启动测试/usr/local/apache/bin/apachectl start curl http://127.0.0.1:8080/能出 It works! 就说明 Apache 起来了。3.3 MySQL 5.7 安装直接用二进制包是更靠谱的选择源码编译 MySQL 至少四五十分钟起步而且配置项多容易踩坑。生产环境我都是用官方二进制包。wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz tar zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz -C /usr/local/ mv /usr/local/mysql-5.7.44-linux-glibc2.12-x86_64 /usr/local/mysql创建数据目录mkdir -p /data/mysql useradd -M -s /sbin/nologin mysql chown -R mysql:mysql /usr/local/mysql /data/mysql准备/etc/my.cnf[mysqld] basedir/usr/local/mysql datadir/data/mysql socket/tmp/mysql.sock port3306 pid-file/tmp/mysqld.pid character-set-serverutf8mb4 lower_case_table_names0注意lower_case_table_names保持为 0也就是表名大小写敏感。Discuz 安装时创建的表名都是全小写后面基本不会出问题但如果从别的环境迁移过来的备份里包含大写表名改这个参数反而可能搞得一团糟。初始化数据目录/usr/local/mysql/bin/mysqld --initialize-insecure --usermysql --basedir/usr/local/mysql --datadir/data/mysql用--initialize-insecure会生成一个空密码的 root 账户方便第一次登录后面再改密码。启动 MySQLcp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld service mysqld start给 root 设置密码并建库/usr/local/mysql/bin/mysql -uroot --skip-passwordALTER USER rootlocalhost IDENTIFIED BY YourRootPass2024; CREATE DATABASE dzx DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER dzuser127.0.0.1 IDENTIFIED BY DzPass2024; GRANT ALL PRIVILEGES ON dzx.* TO dzuser127.0.0.1; CREATE USER dzuserlocalhost IDENTIFIED BY DzPass2024; GRANT ALL PRIVILEGES ON dzx.* TO dzuserlocalhost; FLUSH PRIVILEGES;这里授权了几户账号都给到因为 Discuz 安装时填的主机地址如果写127.0.0.1走 TCP 连接写localhost走 socket 连接两个都授权可以避免连接被拒。3.4 PHP 7.4 编译参数里决定 Discuz 兼容性的开关PHP 编译是整个环节里最需要耐心的一步先装扩展依赖yum install -y libxml2-devel curl-devel libpng-devel libjpeg-turbo-devel freetype-devel然后下载源码编译wget https://www.php.net/distributions/php-7.4.33.tar.gz tar zxvf php-7.4.33.tar.gz cd php-7.4.33 ./configure \ --prefix/usr/local/php \ --with-apxs2/usr/local/apache/bin/apxs \ --with-mysqli \ --with-pdo-mysql \ --with-gd \ --with-freetype \ --with-jpeg \ --with-curl \ --with-openssl \ --with-zlib \ --enable-mbstring \ --enable-zip \ --enable-bcmath \ --enable-fileinfo \ --with-config-file-path/usr/local/php/etc make -j2 make install几个关键点的分析--with-apxs2让 PHP 编译成libphp7.so并自动在 Apache 配置里加LoadModule php7_module这一行。LNAMP 的“Apache 执行 PHP”就是靠它。--with-freetype和--with-jpegPHP 7.4 里 GD 库的新写法老教程里的--with-freetype-dir已经废弃了照抄老教程会编译报错。--enable-fileinfoDiscuz 安装前检查的文件类型支持依赖它少了会直接提示不通过。--enable-mbstringDiscuz 处理中文、编码转换必需。生成 php.inicp php.ini-production /usr/local/php/etc/php.ini修改这几项Discuz 才能传大附件date.timezone Asia/Shanghai upload_max_filesize 32M post_max_size 40M max_execution_time 300 memory_limit 256M opcache.enable 1 opcache.memory_consumption 128重启 Apache确认 PHP 模块已经加载/usr/local/apache/bin/apachectl restart /usr/local/apache/bin/apachectl -M | grep php3.5 第一次联调在 Apache 后面跑通 PHP 和 MySQL在 Apache 的站点目录建一个测试文件mkdir -p /web/discuz chown -R apache:apache /web/discuz echo ?php phpinfo(); ? /web/discuz/info.php修改/usr/local/apache/conf/httpd.confDocumentRoot /web/discuz Directory /web/discuz Options FollowSymLinks AllowOverride All Require all granted /Directory注意Require all granted必须要写否则 Apache 2.4 默认配置下访问根目录会直接 403。然后访问curl http://127.0.0.1:8080/info.php如果看到一长串 HTML 里的 phpinfo 内容就说明 mod_php 已经工作。再确认 mysqli 扩展和 MySQL 连接是否正常curl http://127.0.0.1:8080/info.php | grep -i mysqli这一步过了LNAMP 的“LN AP MySQL PHP”四大件就算打通了。4. 部署 Discuz上传、建库、安装、伪静态一气呵成4.1 下载解压与目录权限的讲究下载 Discuz X3.4 源码包解压后把upload目录里的内容全部移动到/web/discuzcd /tmp wget ... (从 Discuz 官方应用中心下载) tar zxvf Discuz_X3.4_SC_UTF8.zip cp -r upload/* /web/discuz/这里最重要的不是解压是权限。Apache 的 worker 进程是以apache用户跑的所以/web/discuz及其子目录、包括data和config这两个可写目录都必须属于apachechown -R apache:apache /web/discuz chmod -R 755 /web/discuz chmod -R 777 /web/discuz/data /web/discuz/configDiscuz 安装时除了要能读文件还要写config/config_global.php、config/config_ucenter.php以及data/下的缓存文件。很多人最后安装卡在“无法写入配置文件”十有八九是这一步忘了。4.2 创建数据库与授权还有 PHP 上传限制数据库刚才已经建好了安装时填的信息如下数据库服务器127.0.0.1因为 PHP 和 MySQL 通过 TCP 走 3306已经授权数据库名dzx数据库用户dzuser数据库密码DzPass2024数据表前缀pre_生产环境强烈建议改一个自定义前缀防止注入时猜表名PHP 的上传限制也要一起调好。Discuz 用户传头像、传附件时如果单文件超过upload_max_filesize就直接报“文件无法上传”或提示 0 字节。php.ini 里我前面已经设置了 32M但如果还需要在 Apache 配置里做动态调整也可以加IfModule mod_php7.c php_value upload_max_filesize 64M php_value post_max_size 80M /IfModule这个设定写在 Apache 配置里是允许的还能按目录差异调整比如只对站点根目录生效。4.3 浏览器安装中常见错误与解决方案安装 Discuz 时最常遇到的三个错误现象原因解决方案环境检查 fileinfo 不支持PHP 编译时没加--enable-fileinfo重新编译 PHP加上该参数无法写入 config 文件目录属主不是 apachechown -R apache:apache /web/discuz数据表无法创建MySQL 账号权限不足重新执行 GRANT确认授权的是dzx.*而非其他库我这次编译 PHP 时已经加了--enable-fileinfo所以第一步直接通过。如果是从别处拷来的旧源码包检查一下php -m | grep fileinfo有没有输出没有的话只能回编译一步补上。安装完成进入后台后第一件事就是删除install目录避免别人二次安装rm -rf /web/discuz/install4.4 Discuz 伪静态规则与后台配置Discuz 后台开启伪静态全局 - SEO设置 - URL静态化勾选需要用到的规则比如 viewthread、forumdisplay。然后要确保 Apache 支持mod_rewrite把规则写进/web/discuz/.htaccessRewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [QSA,L]当然 Discuz 实际使用的完整规则比这个长一些在官方应用中心下载对应版本的 rewrite 规则文件复制进去就行核心逻辑就是非真实文件、非真实目录的请求都交给 index.php 处理。后面动静分离中才会真正体现这条规则的价值。5. 动静分离落到 Nginx配置规则、缓存与本地静态入口5.1 动静分离的一个关键误区不能把 .html 当作静态资源刚开始配 Nginx 动静分离时我按惯性把location ~ .*\.(html|htm|gif|jpg|js|css)$都当静态处理结果 Discuz 开启伪静态后/thread-1-1-1.html直接 404而 Apache 后端其实能正确处理这个地址。原因很简单Discuz 的伪静态 URL 虽然带.html它实际上不是一个真实文件而是要交给 Apache 的 mod_rewrite 转成forum.php?modviewthreadtid1的东西。如果 Nginx 看到.html就直接去磁盘找文件它永远找不到因为文件根本不存在。所以动静分离的正确姿势是真正的静态资源按扩展名本地处理其余请求全部转发。.html不应该出现在 Nginx 的静态扩展名列表里它要走动态通道。5.2 Nginx location 规则完整配置这是我实际在用的 server 配置去除了杂七杂八的干扰项upstream apache_backend { server 127.0.0.1:8080; } server { listen 80; server_name bbs.example.com; root /web/discuz; index index.php; # 真正的静态资源本地磁盘直接返回 location ~* \.(gif|jpg|jpeg|png|bmp|swf|css|js|ico|woff2?|ttf|svg)$ { root /web/discuz; expires 7d; access_log off; add_header Cache-Control public; try_files $uri $uri/ 404; } # 附件目录禁止执行 PHP安全兜底 location ~ ^/data/attachment/.*\.(php|php5|phtml)$ { deny all; } # 其余所有请求包括 .php、伪静态 .html、API接口都交给 Apache location / { proxy_pass http://apache_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE_ADDR $remote_addr; proxy_read_timeout 120s; } }分析一下每个部分的意图location ~* \.这一段只管真实静态资源。CSS、JS、图片这些请求直接被 Nginx 读取磁盘返回Apache 根本看不到。expires 7d给浏览器一星期的缓存重复访问时直接走本地缓存。access_log off减轻静态刷屏对日志的压力。location /兜底所有非静态请求不管是/forum.php还是伪静态的/thread-1-1-1.html还是 Discuz 后台 Ajax 接口/api/xxx全部转发给 Apache。因为 Apache 的根目录就是/web/discuz伪静态规则也在.htaccess里它能把请求继续处理下去。proxy_set_header X-Real-IP和X-Forwarded-For是把真实客户端 IP 传给后端Discuz 积分、防灌水、后台登录日志都依赖 IP不传的话全部都会显示成127.0.0.1。5.3 附件目录的单独处理Discuz 的附件上传到了/data/attachment下图片、压缩包都是静态文件理应由 Nginx 服务。但如果某个用户上传了一个伪装成.php的文件或者黑客利用漏洞上传可执行脚本Nginx 这边如果不过滤就可能被当作 PHP 解析执行。所以我把data/attachment里的 PHP 请求直接 denylocation ~ ^/data/attachment/.*\.(php|php5|phtml)$ { deny all; }这条规则不影响正常图片访问因为普通图片不匹配这个正则仍然会走前面静态资源的 location。5.4 浏览器实测分离是否生效的判断方法配置完成后重载 Nginx/usr/local/nginx/sbin/nginx -s reload然后从浏览器请求几个不同资源通过响应头判断是否生效curl -I http://bbs.example.com/static/image/common/logo.png curl -I http://bbs.example.com/forum.php假设静态文件返回头里有Server: nginx/1.24.0和Cache-Control: public说明它被 Nginx 直接处理了。而/forum.php返回头里是Server: Apache/2.4.58 (Unix)说明动态请求确实被转发到了后端 Apache。看到这两种 Server 头就说明动静分离已经生效了。这个方法比看流量、看统计都直观。6. 压测验证哪些调整值得做6.1 ab 压测动态与静态结果说明问题动静分离做得好不好用压测说话最直接ab -n 5000 -c 100 http://bbs.example.com/static/image/common/logo.png ab -n 500 -c 20 http://bbs.example.com/forum.php我这边测下来静态资源的 QPS 能到几千甚至上万动态页面的 QPS 一般在几百。差距非常大但这恰恰是健康的状态Nginx 当了合格的“守门员”把海量静态请求挡在 Apache 之前Apache 才有余力处理真正耗 CPU 的动态逻辑和数据库查询。如果压测时发现静态请求的响应时间也很高先看是不是静态 location 没生效比如静态文件还是被转发到了 Apache或者磁盘 IO 瓶颈。6.2 运行中踩过的坑与排查链路下面几个坑我是一次一次踩过来的整理成排查表症状日志位置根因处理方式访问首页报 403 Forbidden/usr/local/apache/logs/error_log目录没写Require all granted在 Directory 里补全图片能开但 PHP 页面 404Nginx error_logApache 的 DocumentRoot 跟 Nginx root 不一致统一为/web/discuz后台保存配置超时 504Nginx error_log动态请求处理超过默认 60s调大proxy_read_timeout到 120sDiscuz 安装提示无法连接数据库MySQL error log授权了localhost却用了127.0.0.1连接把两个 host 都授权头像上传总是失败php.ini 日志upload_max_filesize太小调到 32M 以上并重启用户 IP 全部显示 127.0.0.1Discuz 后台没设置X-Forwarded-For补proxy_set_header最麻烦的一个是“后台保存时偶尔 504”当时困扰了很久。后来看 Nginx 错误日志才知道是 Discuz 更新缓存的操作执行时间太长Nginx 默认proxy_read_timeout是 60 秒超过就断开。我把值改成 120s 之后问题再没出现过。这类问题如果不看日志、只盯着配置猜很容易浪费时间。6.3 一套经过验证的后续优化清单站点跑稳定后还能做这些优化PHP 开启 opcache 并设置opcache.revalidate_freq0开发环境关闭生产环境开启。Apache 的MaxRequestWorkers不要太大我 2G 内存的机器设置为 150太高反而容易内存不够。Nginx 开启gzip on; gzip_min_length 1k; gzip_types text/plain application/javascript text/css;压缩掉文本内容。MySQL 开slow_query_log把超过 2 秒的查询记下来再有卡顿就有的放矢。图片尽量交给 Nginx 的 expires 缓存但上传附件中经常变化的目录可以考虑缩短为 1 小时避免用户传了新图却一直看到旧图。最后说一个个人习惯这套 LNAMP 环境不要装完之后就不管了日志定期看/usr/local/nginx/logs/和/usr/local/apache/logs/里最骗不了人。我的做法是每周定时检查 Nginx 错误日志和 Apache 错误日志看到deny、proxy、filesize这类关键词再针对性排查。动静分离的乐趣不在配好那一刻而在后面每一次看日志都发现自己还能把系统调得更顺一点。
返回列表