运维-扩展服务¶
1. APC安装指南¶
目前改善 PHP 性能的主流技术体系,已经不再推荐使用 APC 或 eAccelerator,而是全面转向以下现代化、高性能、高稳定性的方案:
1. Opcache(Zend Opcache) – 官方主力推荐¶
简介:
- 从 PHP 5.5 起默认内置,不再需要单独安装扩展;
- 由 Zend 官方开发,替代了 APC 的 Opcode 缓存功能;
- 支持预加载(PHP 7.4+)、优化 opcode 执行路径、并支持多线程共享内存。
优势:
- 性能最高:Zend 官方内建,几乎为所有 PHP 安装默认启用;
- 兼容性强:兼容主流框架(Laravel、Symfony)、CMS(WordPress、Discuz!);
- 安全可靠:代码优化与 opcode 校验机制更健壮。
2. PHP-FPM 配置优化(FastCGI Process Manager)¶
- 使用 静态/动态进程池管理,可避免进程频繁创建/销毁带来的开销;
- 调整 pm.max_children、pm.start_servers、pm.max_requests 可提升并发能力;
- 与 Opcache 配合使用效果极佳。
3. 数据缓存:使用 Redis / Memcached¶
推荐方式:
- 使用 Redis / Memcached 替代 APCu 进行 用户数据缓存;
- 例如:登录态、权限缓存、SQL 查询缓存等;
- 支持集群、高可用、数据持久化等特性。
4. 框架级缓存机制¶
- Laravel、Symfony、ThinkPHP 等现代框架内建多级缓存支持(文件、Redis、数据库);
- Discuz! X3.5 本身也支持切换缓存驱动(如 memory.php 配置文件中切换为 Redis);
- 实际部署中建议将常用缓存(如模板缓存、配置缓存)迁移到内存型服务中。
| 功能类型 | 推荐技术 | 说明 |
|---|---|---|
| Opcode 缓存 | Opcache | PHP 官方维护,取代 APC |
| 数据缓存 | Redis | 替代 APCu,支持更多场景 |
| 会话/共享内存 | Redis / Memcached | 跨进程共享缓存首选 |
| Web 服务器性能 | PHP-FPM 优化 + Nginx | 保持请求处理高并发 |
2. MySQL主从设置¶
进行 MySQL 主从配置(Replication) 的目的主要是为了解决 性能瓶颈、数据安全、扩展性 三个方面的问题,尤其是在高并发网站(如 Discuz!)部署中尤为重要。
以下是从架构、运维和性能三个维度讲解为什么要配置 MySQL 主从:
1. 读写分离 – 提升性能¶
说明:
- 在 MySQL 主从架构中,主库(Master)负责写操作,如:发帖、注册、评论等;
- 从库(Slave)负责读操作,如:访问帖子、浏览列表、查看用户资料等。
优势:
- 将查询压力分散到多个从库,避免主库 CPU 和 I/O 过载;
- 支持横向扩展,从库可根据访问量增加节点(负载均衡);
- 在 Discuz! 中开启“读写分离”可直接利用这一优势。
2. 数据冗余 – 提高安全性¶
说明:
- 从库保存主库的实时备份副本;
- 即使主库数据损坏或丢失,也可以从从库中恢复。
优势:
- 提高灾难恢复能力(Disaster Recovery);
- 支持定点恢复(通过 binlog 和 position);
- 可搭配 延迟复制 防止误操作(例如删库)同步。
3. 支持热备 – 不中断业务地进行维护¶
说明:
- 在从库上做备份,不影响主库写入;
- 可在从库进行复杂查询、分析、统计任务。
优势:
- 避免主库锁表、影响在线用户体验;
- 支持更平滑的数据库升级、迁移或大表维护。
4. 便于扩展和分布式部署¶
说明:
- 可以为每个地理区域、业务模块设置多个从库;
- 支持分布式查询、跨机房部署、读流量就近调度。
5. 总结:Discuz! 项目的数据库部署推荐方案(2025年版)¶
| 网站规模 | 推荐部署形式 |
|---|---|
| 小型站点 | 单实例 MySQL + Redis 缓存 |
| 中等站点 | 主从部署(1 主 N 从)+ Redis + 读写分离 |
| 高并发社区论坛 | MGR 高可用主集群 + 多只读节点 + Redis + 分库表策略 |
| 企业私有部署 | 可考虑 TiDB(MySQL 协议兼容)或 Vitess(逻辑分布式) |
6. MySQL 主库(Master)配置¶
在 [mysqld] 部分添加以下内容(确保无重复项):
log-bin=mysql-bin # 启用二进制日志功能,是主从复制的基础
server-id=1 # 主服务器唯一 ID,不能与从库重复
binlog-do-db=dzx2 # 指定要复制的数据库,避免复制所有数据库
expire-logs-days=7 # 设置二进制日志保留 7 天,防止磁盘被日志占满
创建复制账户:
mysql -uroot -p # 登录主库 MySQL 控制台
GRANT REPLICATION SLAVE ON *.* TO 'rep'@'192.168.1.3' IDENTIFIED BY '123'; # 授权从库使用复制账号连接主库
重启 MySQL 服务以应用配置:
7. 复制数据前,锁表并获取主库同步位置¶
mysql -uroot -p # 登录 MySQL 控制台
FLUSH TABLES WITH READ LOCK; # 锁定所有表以保持备份一致性
SHOW MASTER STATUS; # 获取当前二进制日志文件名和位置,需记录 file 和 position
保持当前窗口打开,不要执行 UNLOCK TABLES,直到完成备份
执行备份操作(任选一种):
mysqldump -uroot -p --single-transaction --databases dzx2 > dzx2.sql # 使用 mysqldump 导出数据
# 或者直接复制数据库文件(需关闭 MySQL)
解锁表并恢复正常服务:
恢复论坛访问:
8. 从库(Slave)配置¶
在 [mysqld] 部分添加以下内容:
server-id=2 # 从库的唯一 ID,与主库不同
master-port=3306 # 主库监听的端口(默认 3306)
replicate-do-db=dzx2 # 需要复制的数据库
replicate-ignore-table=dzx2.pre_common_session # 排除无意义的临时表(如会话表)
slave-skip-errors=1032,1062,126,1114,1146,1048,1396 # 自动跳过常见错误,防止复制中断
重启从库 MySQL:
恢复主库备份数据:
配置主从连接参数:
mysql -uroot -p # 登录从库控制台
CHANGE MASTER TO
MASTER_HOST='192.168.1.2', # 主库 IP
MASTER_USER='rep', # 主库创建的复制账户
MASTER_PASSWORD='123', # 复制账户密码
MASTER_LOG_FILE='mysql-bin.000001', # 主库记录的日志文件名
MASTER_LOG_POS=154; # 主库记录的 POS 位置,注意无引号
启动从库复制线程:
START SLAVE; # 启动 IO 和 SQL 线程以开始复制
SHOW SLAVE STATUS\G; # 检查 Slave_IO_Running 和 Slave_SQL_Running 是否为 Yes
补充(可选):my.cnf 设置简化连接信息(部分 MySQL 版本支持)
9. Discuz! 中的读写分离配置¶
$_config['db']['slave']['1']['dbhost'] = '192.168.1.3'; # 从库 IP
$_config['db']['slave']['1']['dbuser'] = 'rep'; # 从库连接用户名
$_config['db']['slave']['1']['dbpw'] = '123'; # 密码
$_config['db']['slave']['1']['dbcharset'] = 'utf8';
$_config['db']['slave']['1']['pconnect'] = 0;
$_config['db']['slave']['1']['dbport'] = 3306;
$_config['db']['slave']['1']['weight'] = 1; # 权重,数值越大被调度概率越高
3. Discuz! X2.5读写分离¶
1. 配置读写分离的排除表¶
架构说明:
common_session是用户会话表,频繁读写,存在主从同步延迟风险;- 若未排除,用户登录后会出现“未登录”或“掉线”现象。
2. 配置第一个从库信息¶
$_config['db']['slave']['1']['dbhost'] = '192.168.1.2'; # 第一个从库的 IP 地址或主机名
$_config['db']['slave']['1']['dbuser'] = 'root'; # 从库连接用户名,应具备只读权限
$_config['db']['slave']['1']['dbpw'] = 'password'; # 数据库密码(生产环境应使用只读账户)
$_config['db']['slave']['1']['dbcharset'] = 'gbk'; # 数据库字符集,需与主库保持一致(常见为 utf8 或 gbk)
$_config['db']['slave']['1']['pconnect'] = '0'; # 是否启用持久连接,建议关闭以避免连接泄露
$_config['db']['slave']['1']['dbname'] = 'discuz'; # 目标数据库名称
$_config['db']['slave']['1']['tablepre'] = 'pre_'; # 表前缀,需与主库一致
架构说明:
- Discuz! 会根据内置的 slave_except_table 和数据操作类型(SELECT vs INSERT/UPDATE)动态决定是否使用从库;
- 多个从库将使用 轮询调度策略,可通过 weight 参数配置优先级(在 X3 之后支持)。
3. 如需添加第二个从库,继续追加如下配置¶
$_config['db']['slave']['2']['dbhost'] = '192.168.1.3'; # 第二个从库的 IP
$_config['db']['slave']['2']['dbuser'] = 'root'; # 用户名,通常与主库相同
$_config['db']['slave']['2']['dbpw'] = 'password'; # 密码
$_config['db']['slave']['2']['dbcharset'] = 'gbk'; # 字符集,与主库保持一致
$_config['db']['slave']['2']['pconnect'] = '0'; # 持久连接开关,建议设为 0
$_config['db']['slave']['2']['dbname'] = 'discuz'; # 数据库名
$_config['db']['slave']['2']['tablepre'] = 'pre_'; # 表前缀
调度说明:
- 当配置多个从库时,Discuz! 默认在其间轮询调度;
- 若需按访问量自动分配,可升级到 X3+ 并使用 weight 参数配置负载分担比例。
4. 修改完成后保存文件,系统会自动启用读写分离,无需额外操作。¶
补充说明:读写分离的适用条件与风险控制
| 条件 | 是否必须 | 原因说明 |
|---|---|---|
| 主从已配置完成 | 是 | 从库必须能同步主库数据,否则查询数据会不一致 |
| 时间同步准确 | 是 | 防止从库落后于主库太多,影响论坛用户体验 |
| 会话、缓存排除 | 是 | 推荐将如 common_session 及临时表排除,避免不一致 |
| 数据库字符集统一 | 是 | 字符集不一致可能导致乱码或查询失败 |
| 使用 Redis 缓存 | 推荐 | 可降低主库写压力,减少读写分离同步延迟风险 |
4. Discuz! X2.5安全配置指引¶
1. 系统安装阶段安全配置¶
# 推荐最小化安装系统
# 安装过程软件包选择:全部不选,仅安装最小化系统(无 GUI),降低攻击面
# 设置 root 密码
# 密码必须 ≥ 8 位,包含大小写、数字、符号,提高破解成本
# 精简服务,关闭无用或高危服务
chkconfig kudzu off # 关闭硬件变更探测服务
chkconfig cpuspeed off # 节能控制,服务器不推荐使用
chkconfig isdn off # ISDN 拨号服务
chkconfig portmap off # RPC 映射器,NFS 用到,默认关闭
chkconfig nfslock off # NFS 文件锁支持
chkconfig rpcidmapd off # RPC id 映射守护进程
chkconfig rpcgssd off # RPC 安全认证支持
chkconfig bluetooth off # 蓝牙服务
chkconfig netfs off # 挂载网络文件系统
chkconfig pcscd off # 智能卡支持服务
chkconfig apmd off # 电源管理(APM)
chkconfig hidd off # 蓝牙鼠标支持
chkconfig autofs off # 自动挂载服务
chkconfig hplip off # HP 打印机服务
chkconfig cups off # 打印服务
chkconfig gpm off # 控制台鼠标服务
chkconfig xfs off # 字体服务
chkconfig avahi-daemon off # 本地网络自动发现服务(类似 Bonjour)
chkconfig yum-updatesd off # yum 自动更新守护进程
chkconfig firstboot off # 安装后首次启动配置
chkconfig haldaemon off # 硬件抽象层
# 数据挂载加强安全性
# 对 /home 或 /data 分区使用挂载选项 nodev,nosuid,nosetuid,禁止执行权限和设备节点
mount -o remount,nodev,nosuid,nosetuid /home # 示例挂载调整命令
# 设置所有服务脚本权限为 root:root 且 755
chmod 755 /etc/init.d/* && chown root:root /etc/init.d/* # 防止服务脚本被篡改
# 端口限制
# Web服务器:仅开放 80(HTTP) 和 22(SSH)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 开放 HTTP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 开放 SSH
# 数据库服务器:仅开放 3306(MySQL) 和 22(SSH)
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT # 仅内网访问
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 非核心端口应封闭,或设定特定 IP 白名单
iptables -A INPUT -p udp --dport 161 -s 10.0.0.0/8 -j ACCEPT # SNMP
iptables -A INPUT -p tcp --dport 5666 -s 10.0.0.0/8 -j ACCEPT # NRPE
# 禁止 FTP 服务(明文传输不安全)
chkconfig vsftpd off # 关闭 vsftpd 服务
# 禁止任何服务使用 root 账户运行
# 建议创建独立账户运行:如 www、mysql、redis 等
# 内核安全设置(/etc/sysctl.conf)
echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf # 防止 SYN Flood 攻击
echo "net.ipv4.conf.all.log_martians = 1" >> /etc/sysctl.conf # 记录可疑 ARP 数据包
sysctl -p # 应用内核参数
2. PHP 配置加强(php.ini)¶
disable_functions=passthru,exec,system,chroot,scandir,chgrp,chown,escapeshellcmd,escapeshellarg,shell_exec,proc_get_status,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,leak,popepassthru,stream_socket_server,popen # 禁用所有危险函数,防止命令执行漏洞
register_globals = Off # 防止全局变量覆盖漏洞
cgi.fix_pathinfo = 0 # 防止 Nginx + PHP 的路径解析漏洞
magic_quotes_gpc = On # 自动对 GPC 输入进行转义,防止 SQL 注入(已废弃特性)
allow_url_include = Off # 禁止远程文件包含漏洞
expose_php = Off # 禁止暴露 PHP 版本,防止指纹识别
3. 数据库安全¶
# 单机部署 MySQL 时,仅绑定本地地址
bind-address = 127.0.0.1 # 防止外网连接数据库
# 多服务器部署时仅绑定内网地址
bind-address = 192.168.1.10 # 仅内网可连
# 每个站点使用独立 php-fpm 池,运行在独立用户下
# /etc/php-fpm.d/site1.conf 中:
user = www_site1 # 站点1专用用户
group = www_site1
# 每个服务使用独立用户运行
useradd -r www # Web 服务用户
useradd -r mysql # MySQL 用户
useradd -r redis # Redis 用户
useradd -r memcache # Memcached 用户
4. Discuz! 站点目录安全加固¶
# 探针与管理工具必须临时性使用
rm -f /var/www/html/phpinfo.php # 删除探针文件
mv phpMyAdmin/ /root/phpMyAdmin_backup # 管理程序移出 Web 根目录
# 禁止站点目录中存在 bak、old、test 目录或文件
find /var/www/html -type d -name "*bak*" -exec rm -rf {} \; # 删除备份目录
find /var/www/html -type f -name "*.tar" -o -name "*.zip" -o -name "*.tar.gz" -exec rm -f {} \; # 删除压缩包
# 删除 install、upgrade、xconvert 等敏感目录
rm -rf install/ upgrade/ xconvert/ # 清除残留升级脚本
# 清理编辑器自动备份文件
find /var/www/html -type f -name "*.swp" -o -name "*.bak" -exec rm -f {} \;
# 设置除以下目录外,其余目录仅允许 root 修改
chown -R root:root /var/www/html/
chmod -R 755 /var/www/html/
chown -R www:www /var/www/html/config/ # 允许 web 写入的目录
chown -R www:www /var/www/html/data/
chown -R www:www /var/www/html/uc_client/data/
chown -R www:www /var/www/html/uc_server/data/
# 禁止访问敏感目录下的 PHP 文件(以 Nginx 为例)
# /etc/nginx/conf.d/discuz.conf 中添加:
location ~ ^/(config|data|uc_client/data|uc_server/data)/.*\.php$ {
deny all; # 拒绝直接访问这些目录下的 PHP 文件
}
5. 总结:Discuz! 安全部署三层策略¶
| 层级 | 策略关键点 |
|---|---|
| 系统层 | 关闭不必要服务、限制端口、配置内核安全参数 |
| PHP/MySQL层 | 禁用危险函数、限制访问地址、独立用户执行 |
| 应用层 | 清除敏感文件、隔离目录权限、Nginx 层禁止访问敏感脚本 |