博客 / Linux/ 网站搬家笔记,记录lnmp生产环境搬家及优化升级过程

网站搬家笔记,记录lnmp生产环境搬家及优化升级过程

网站搬家笔记,记录lnmp生产环境搬家及优化升级过程

最后更新:2018年8月10日

我的一个网站目前日访问量约为3.2万独立IP、3.5万独立访客、15万+页面浏览量。它运行在一台最低配置的阿里云服务器上,虽然经过大量优化,但已显得非常吃力。考虑到云服务成本持续上升,我决定进行服务器迁移,并借此机会对整个生产环境进行优化升级。

本文旨在记录这次生产环境部署与调优的过程。生产环境的配置必须基于实际业务需求,既不能“小马拉大车”导致系统过载,也不能“大马拉小车”造成资源浪费。

我的网站程序基于PHP,本次重新部署的核心目标是:以最低成本应对日常访问,保持较低的系统负载,避免因php-fpm进程崩溃导致网站出现502错误,并防止MySQL数据库崩溃或CPU占用率过高。其中,MySQL数据库是本次优化的重点,其次是php-fpm。

一个大胆的存储方案

我计划将缓存、静态文件以及MySQL数据库文件放置在高速的本地磁盘上,以利用其高IOPS特性来提升性能。

为了保证数据安全,我将通过脚本或lsyncd工具,将数据目录实时增量备份到云磁盘。一旦本地磁盘出现问题,可以立即修改配置文件,切换到云磁盘上的备份数据。

这个方案可能看起来有些冒险,因为通常认为将重要数据放在本地盘不够安全,官方文档也建议本地盘用于非关键数据的读写。但我之所以考虑此方案,是因为新服务器的云磁盘IO性能较低,而本地盘的IO性能是其20倍以上。将数据库放在本地盘预计会带来显著的性能提升,因此我打算在这次迁移后进行尝试。

一、服务器操作系统基本配置

操作系统:CentOS 6.8 64bit

通过SSH登录服务器后,进行以下操作:

  1. 挂载云磁盘。
  2. 加强服务器安全:修改SSH端口、禁用root账户密码登录、限制使用密钥登录。

安装基础工具和依赖:

yum install wget screen -y && screen -S lnmp
sudo yum check-update || sudo yum update -y
yum groupinstall -y 'Development Tools'
yum install -y epel-release
yum install -y perl perl-devel perl-ExtUtils-Embed libxslt libxslt-devel libxml2 libxml2-devel gd gd-devel GeoIP GeoIP-devel

二、安装LNMP环境

需求:

  1. 使用高IO的本地盘存放数据库文件(安全性后续加强)。
  2. 为Nginx安装ngx_cache_purge模块(LNMP一键安装包默认不包含)。

由于以上需求,需要修改LNMP一键安装包的配置。

首先,创建一个目录用于管理安装文件:

cd / && mkdir codefiles && cd codefiles

下载LNMP 1.4安装包并解压,但不立即执行安装脚本,以便手动修改配置:

wget -c http://soft.vpser.net/lnmp/lnmp1.4.tar.gz && tar zxf lnmp1.4.tar.gz && cd lnmp1.4

下载ngx_cache_purge模块源码包并解压到指定目录:

cd src && wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz && tar zxvf ngx_cache_purge-2.3.tar.gz && rm -rf ngx_cache_purge-2.3.tar.gz && cd ..

修改LNMP根目录下的lnmp.conf配置文件,添加Nginx模块参数,并启用ngx_http_realip_module模块以备后续扩展:

vi lnmp.conf

修改后的配置内容如下:

Download_Mirror='https://soft.vpser.net'

Nginx_Modules_Options='--add-module=/codefiles/lnmp1.4/src/ngx_cache_purge-2.3 --with-http_realip_module'
PHP_Modules_Options=''

##MySQL/MariaDB database directory##
MySQL_Data_Dir='/mnt/mysql/var'
MariaDB_Data_Dir='/mnt/mariadb/var'
##Default website home directory##
Default_Website_Dir='/home/wwwroot/default'

Enable_Nginx_Openssl='y'

配置中将数据库默认数据目录从/usr/local/修改为/mnt/下的路径,因为本地磁盘挂载在/mnt目录。

提示:在继续安装前,建议先在云服务器控制台为系统盘创建一个快照。这样,如果后续安装出现问题,可以快速回滚到当前状态。

更新系统并开始安装:

yum update -y
./install.sh lnmp

根据提示选择需要安装的数据库类型、设置root密码以及PHP版本。

安装完成后,系统环境如下:

  • CentOS 6.8 64bit
  • Nginx 1.12.2
  • MariaDB 10.1.23
  • PHP 5.5.38

三、安装其他必要软件

清理安装过程中下载的临时文件:

rm -rf /codefiles/lnmp1.4.tar.gz && rm -rf /codefiles/lnmp1.4/src/ngx_cache_purge-2.3.tar.gz

安装Memcached:

cd /codefiles/lnmp1.4/ && ./addons.sh

对于WordPress,需要下载Memcached对象缓存插件(如原链接失效,可使用备用链接),将解压得到的object-cache.php文件上传至wp-content目录即可启用。

若要查看Memcached状态,可下载官方探针。编辑其中的memcache.php文件,修改服务器地址和登录凭证:

define('ADMIN_USERNAME','memcache');    // 登录用户名,请自行修改
define('ADMIN_PASSWORD','password');    // 登录密码,请自行修改
define('DATE_FORMAT','Y/m/d H:i:s');
define('GRAPH_SIZE',200);
define('MAX_ITEM_DUMP',50);
// 定义Memcached服务器,单机部署通常为127.0.0.1:11211
$MEMCACHE_SERVERS[] = '127.0.0.1:11211'; // add more as an array
//$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array

将文件上传到网站的非公开目录(临时测试可放根目录),通过浏览器访问该文件并输入用户名密码即可查看状态。

如果页面能打开但没有命中数据,说明WordPress未成功连接Memcached。此时可在wp-config.php中加入以下配置:

global $memcached_servers;
$memcached_servers = array(
    array(
        '127.0.0.1', // Memcached服务器IP地址
         11211        // Memcached服务器端口
    )
);

可通过以下命令查看Memcached实际监听的IP和端口:

netstat -nutlp | grep memcache

启用OPcache优化PHP执行(LNMP已包含但默认未启用):

./addons.sh install opcache

从原服务器复制以下配置文件到新服务器备用:

  • Nginx主配置文件:/usr/local/nginx/conf/nginx.conf
  • 虚拟主机配置文件:/usr/local/nginx/conf/vhost/域名.conf
  • MySQL配置文件:/etc/my.cnf
  • PHP配置文件:/usr/local/php/etc/php.ini
  • php-fpm配置文件:/usr/local/php/etc/php-fpm.conf
  • SNMP监控配置文件:/etc/snmp/snmpd.conf

检查并迁移原服务器的Crontab计划任务,例如:

*/5 * * * * /bin/bash /codefiles/lnmp1.4/tools/checkmysql.sh
*/5 * * * * /bin/bash /codefiles/lnmp1.4/tools/check502.sh
00 03 * * * /bin/bash /codefiles/lnmp1.4/tools/cut_nginx_logs.sh
00 23 * * 3 /bin/bash /codefiles/lnmp1.4/tools/backup.sh

四、网站配置

  1. 新建虚拟主机、绑定域名、开启SSL,并将原服务器的PHP和Nginx配置文件拷贝过来进行优化。
  2. 配置正确的iptables防火墙规则。

五、LNMP日志记录与处理

  1. 使用脚本配合Crontab任务,对日志进行按天切割保存,并设置30天后自动删除。
  2. 禁用MySQL的日志功能(如二进制日志),防止日志文件占满磁盘空间。

六、防火墙规则

注意iptables规则需与云主机的安全组策略相匹配。

如果服务器或程序需要发送邮件(例如监控脚本发送告警),需要开启相应端口(如25或465)。若使用第三方SMTP服务,则需配置发件人信息。编辑/etc/mail.rc文件:

set from=username@126.com
set smtp=smtp.126.com
set smtp-auth-user=username
set smtp-auth-password=password
set smtp-auth=login

注意:smtp-auth-password通常是邮箱的SMTP授权码,而非登录密码。

七、开启SNMP监控

安装SNMP服务:

yum install net-snmp net-snmp-devel -y

SNMP有v2c和v3两种版本,验证方式不同。

V2c版本配置

清空默认配置文件并编辑:

> /etc/snmp/snmpd.conf
vi /etc/snmp/snmpd.conf

加入以下内容(将192.168.1.1替换为服务器IP,public可替换为自定义字符串):

rocommunity public 127.0.0.1
rocommunity public 192.168.1.1
# 如果您使用的是采集器,以下IP应该是安装采集器的服务器的IP
rocommunity public 60.195.252.107
rocommunity public 60.195.252.110

V3版本配置

停止服务并创建用户:

service snmpd stop
net-snmp-config --create-snmpv3-user -ro -A snmp@jiankongbao -a MD5 jiankongbao

启动服务并设置开机自启:

service snmpd start
chkconfig snmpd on

服务检测

V2c版本检测:

netstat –antupl
snmpwalk -v2c –c commity target_ip

V3版本检测:

snmpwalk -v 3 -u jiankongbao -a MD5 -A "snmp@jiankongbao" -l authNoPriv 127.0.0.1 sysDescr

如果提示命令无效,安装net-snmp-utils

yum install net-snmp-utils -y

防火墙设置

V2c版本,允许UDP 161端口:

iptables -I INPUT -p udp --dport 161 -j ACCEPT

更严格的规则可以限定只允许特定监控服务器IP访问。

八、完善服务器备份策略

  1. 使用Crontab每天凌晨执行脚本,将本地磁盘/mnt目录下的数据库数据增量备份到云磁盘(排除缓存目录)。
  2. 利用云磁盘的自动快照功能,每天凌晨对系统盘和数据盘进行快照。注意备份脚本和快照任务的执行顺序,应先完成数据库备份再进行快照。
  3. 使用脚本每月自动打包数据库及网站文件(不含缓存)到远程FTP或对象存储,并定期清理超过30天的历史备份。

九、网站优化

  1. 实现网站动静分离。
  2. 部署全站HTTPS。

拓展:为什么选择Nginx + PHP-FPM?

相比Apache + MOD_PHP,Nginx + PHP-FPM具有以下优势:

  • 易于实现动静分离。
  • 支持通过upstream配置PHP-FPM集群,实现负载均衡和故障转移。
  • PHP-FPM配置更灵活,可以在php-fpm.conf中配置监听不同端口的多个进程池(pool),每个池可以独立设置进程数,实现资源隔离。
  • 一台服务器上可以运行多个版本的PHP-FPM,便于横向扩展。

Nginx返回502错误通常是由于后端PHP-FPM进程崩溃。可以通过配置fastcgi_next_upstream指令,让Nginx将请求转发给其他可用的上游服务器:

fastcgi_next_upstream error timeout invalid_header http_500 http_502 http_504;

PHP-FPM配合Nginx还可以将I/O密集型操作(如下载、cURL请求)分离到独立的进程池中处理,避免阻塞主应用。例如,可以创建一个监听9001端口的名为io的进程池专门处理此类请求,而主应用池www监听9000端口。

Nginx配置示例:

location = /io.php {
    include fastcgi_params;
    fastcgi_pass 127.0.0.1:9001;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

PHP-FPM配置示例(php-fpm.conf):

[www]
listen = 127.0.0.1:9000
pm = static
pm.max_children = 4

[io]
listen = 127.0.0.1:9001
pm = dynamic
pm.max_children = 8
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 4

通过这种池隔离的方式,可以有效减少I/O阻塞对整个PHP应用的影响。

发表评论

您的邮箱不会公开。必填项已用 * 标注。