首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Linux 下 LNMP 生產環境部署全紀錄:Nginx + PHP-FPM + MySQL 編譯安裝與優化實戰

     編輯:PHP 相關知識

前言

本文記錄一次在 CentOS 6/7 上從源碼編譯部署 LNMP(Linux + Nginx + MySQL + PHP-FPM)的完整過程,涵蓋依賴安裝、核心軟體編譯參數調優、配置文件模板、啟動腳本、內核參數優化、日誌切割、平滑重載等生產級細節。版本選擇:Nginx 1.24、PHP 8.2、MySQL 8.0(文中以經典 5.5/5.2 版本為例說明編譯邏輯,實際生產請升級至維護版本)。

一、系統依賴包安裝

# CentOS 7/8
yum -y install gcc gcc-c++ make autoconf \
    libjpeg-turbo-devel libpng-devel freetype-devel \
    libxml2-devel zlib-devel bzip2-devel \
    libcurl-devel openssl-devel openldap-devel \
    libxslt-devel libzip-devel oniguruma-devel \
    sqlite-devel libicu-devel systemd-devel

# CentOS 6 需額外安裝 libmcrypt、mhash 等舊庫

二、MySQL 8.0 編譯安裝(CMake 方式)

# 建立用戶與目錄
groupadd mysql && useradd -r -g mysql -s /sbin/nologin mysql
mkdir -p /data/mysql/{data,logs,tmp} && chown -R mysql:mysql /data/mysql

# 下載並編譯
tar xf mysql-8.0.36-linux-glibc2.28-x86_64.tar.xz -C /usr/local/
ln -s /usr/local/mysql-8.0.36 /usr/local/mysql

# 初始化
/usr/local/mysql/bin/mysqld --initialize-insecure \
    --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data

# systemd 服務
cat > /etc/systemd/system/mysqld.service <<'EOF'
[Unit]
Description=MySQL Server
After=network.target

[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE=65535
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload && systemctl enable --now mysqld

核心 my.cnx 模板(重點優化參數)

[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql/data
socket=/tmp/mysql.sock
port=3306

# 連接層
max_connections=2000
thread_cache_size=300
table_open_cache=4000
open_files_limit=65535

# InnoDB 核心
innodb_buffer_pool_size=4G        # 物理記憶體 60-70%
innodb_log_file_size=1G
innodb_log_files_in_group=3
innodb_flush_log_at_trx_commit=2  # 性能優先,允許 1 秒丟失
innodb_file_per_table=1
innodb_io_capacity=2000
innodb_read_io_threads=8
innodb_write_io_threads=8

# 查詢快取(8.0 已移除,改用 ProxySQL 或 Redis)
# query_cache_type=0

# 二進位日誌
log_bin=/data/mysql/logs/binlog
binlog_format=ROW
expire_logs_days=7
max_binlog_size=1G

# 安全
skip-name-resolve
sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

三、PHP 8.2 編譯安裝(FPM 模式)

tar xf php-8.2.18.tar.gz && cd php-8.2.18
./configure --prefix=/usr/local/php \
    --with-config-file-path=/usr/local/php/etc \
    --with-config-file-scan-dir=/usr/local/php/etc/php.d \
    --enable-fpm --with-fpm-user=www --with-fpm-group=www \
    --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \
    --with-iconv --with-freetype --with-jpeg --with-webp --with-zlib \
    --with-libxml --enable-xml --disable-rpath \
    --enable-bcmath --enable-shmop --enable-sysvsem \
    --enable-mbstring --enable-intl --enable-pcntl \
    --enable-sockets --enable-gd --enable-opcache \
    --with-curl --with-mhash --with-xsl --with-zip \
    --with-openssl --with-sodium --with-password-argon2 \
    --enable-calendar --enable-exif --enable-ftp \
    --with-pear --enable-cli

make -j$(nproc) && make install

# 配置文件
cp php.ini-production /usr/local/php/etc/php.ini
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf

php.ini 關鍵調優

# /usr/local/php/etc/php.ini
memory_limit = 256M
max_execution_time = 30
post_max_size = 50M
upload_max_filesize = 50M
date.timezone = Asia/Shanghai
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
cgi.fix_pathinfo=0          # 防 Nginx 解析漏洞
expose_php=Off
display_errors=Off
log_errors=On
error_log=/data/logs/php/error.log

php-fpm 池配置(www.conf)

[www]
user = www
group = www
listen = 127.0.0.1:9000
listen.owner = www
listen.group = www
listen.mode = 0660
pm = dynamic
pm.max_children = 200
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 50
pm.max_requests = 1000
request_terminate_timeout = 60s
request_slowlog_timeout = 5s
slowlog = /data/logs/php/slow.log
catch_workers_output = yes
php_admin_value[error_log] = /data/logs/php/fpm-error.log
php_admin_flag[log_errors] = on

四、Nginx 1.24 編譯與配置

tar xf nginx-1.24.0.tar.gz && cd nginx-1.24.0
./configure --prefix=/usr/local/nginx \
    --user=www --group=www \
    --with-http_ssl_module --with-http_v2_module \
    --with-http_realip_module --with-http_stub_status_module \
    --with-http_gzip_static_module --with-pcre-jit \
    --with-threads --with-file-aio \
    --with-http_sub_module --with-stream \
    --with-stream_ssl_module
make -j$(nproc) && make install

nginx.conf 核心模板

user www www;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;

error_log /data/logs/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    use epoll;
    worker_connections 65535;
    multi_accept on;
}

http {
    include mime.types;
    default_type application/octet-stream;

    # 緩衝與快取
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 60;
    keepalive_requests 1000;

    # FastCGI
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;

    # Gzip
    gzip on;
    gzip_min_length 1k;
    gzip_comp_level 2;
    gzip_types text/plain application/javascript text/css application/xml application/json;
    gzip_vary on;

    # 日誌格式
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    # 虛擬主機示例
    server {
        listen 80;
        server_name example.com;
        root /data/www/example.com;
        index index.php index.html;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        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 ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
            expires 30d;
            access_log off;
        }

        access_log /data/logs/nginx/example.com.log main;
    }
}

五、Linux 內核參數優化(/etc/sysctl.d/99-lnmp.conf)

# 連接隊列
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 32768
net.ipv4.tcp_max_syn_backlog = 65535

# 內存緩衝
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216

# TCP 優化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_mem = 786432 1048576 1572864

# 端口範圍
net.ipv4.ip_local_port_range = 1024 65535

# 文件句柄
fs.file-max = 1000000
fs.nr_open = 1000000

執行 sysctl --system 生效,並將 ulimit -SHn 65535 加入 /etc/profile 或服務啟動腳本。

六、平滑重載與日誌切割

Nginx 平滑重載

# 檢查配置
/usr/local/nginx/sbin/nginx -t
# 重載
/usr/local/nginx/sbin/nginx -s reload

日誌切割腳本(/usr/local/nginx/sbin/cut_log.sh)

#!/bin/bash
LOG_DIR="/data/logs/nginx"
DATE=$(date -d "yesterday" +%Y%m%d)
mkdir -p ${LOG_DIR}/$(date -d "yesterday" +%Y/%m)

mv ${LOG_DIR}/access.log ${LOG_DIR}/$(date -d "yesterday" +%Y/%m)/access_${DATE}.log
mv ${LOG_DIR}/error.log  ${LOG_DIR}/$(date -d "yesterday" +%Y/%m)/error_${DATE}.log

# 通知 Nginx 重新打開日誌
kill -USR1 $(cat /var/run/nginx.pid)

加入 crontab:0 0 * * * /bin/bash /usr/local/nginx/sbin/cut_log.sh

七、開機自啟與服務管理

# systemd 管理 Nginx
cat > /etc/systemd/system/nginx.service <<'EOF'
[Unit]
Description=Nginx HTTP Server
After=network.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now nginx php-fpm mysqld

八、安全加固清單

  • MySQL:mysql_secure_installation、禁用 root 遠程登錄、強密碼策略。
  • PHP:disable_functions=exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source。
  • Nginx:隱藏版本號 server_tokens off、限制請求體大小 client_max_body_size 10m、配置 HTTPS 與 HSTS。
  • 系統:關閉 SELinux(或配置策略)、iptables 僅開放 80/443/22、定期 yum update。

總結

源碼編譯部署雖繁瑣,但能精確控制版本、模組與優化參數,適合對性能、安全有嚴格要求的生產環境。配合 Ansible/Playbook 自動化,可將上述流程標準化、可重複執行。關鍵成功因素:內核參數優化、PHP-FPM 池合理規劃、MySQL InnoDB 緩衝池適配記憶體、Nginx 緩衝與快取策略、完善的日誌與監控體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved