Nginx动静分离

动静分离介绍

Nginx动静分离的核心:静态请求由Nginx直接处理,动态请求代理给后端(如PHP-FPM)。

Nginx的静态处理能力很强,但是动态处理能力不足,因此,在企业中常用动静分离技术。

  • 静态(如.jpg、.css、.html):走Nginx本地文件系统,直接返回。

  • 动态(如.php):通过proxy_pass或fastcgi_pass转发给PHP-FPM/Tomcat等应用服务器处理。

实验要求

部署wordpress实现整个网站的动静分离,实现如下要求:

1.前端Nginx收到静态请求,直接从NFS中返回给客户端。

2.前端Nginx收到动态请求转交给通过FastCGI交给PHP服务器处理。

  • 如果得到静态结果直接从NFS取出结果交给Nginx然后返回给客户端。

  • 如果需要数据处理PHP服务器连接数据库后将结果返回给Nginx

3.前端Nginx收到图片请求以.jpg、.png、.gif等请求交给后端Images服务器处理。

部署环境

IP

功能

软件

192.168.7.20

共享服务器

NFS服务

192.168.7.21

网络入口,数据转发,静态文件

Nginx服务

192.168.7.22

处理动态数据

PHP-FPM

192.168.7.23

图片服务器

Nginx服务

192.168.7.24

数据库服务

MySQL服务

配置详解

NFS服务器配置

 # 配置机器
 192.168.7.20  共享服务器  NFS服务
 ​
 # 安装NFS
 yum -y install nfs-utils
 ​
 # 创建共享目录
 mkdir -p /app/blog
 ​
 # 修改共享配置
 vim /etc/exports
 ​
 # 只允许内网网段挂载,提高安全性。(控制访问权限和用户映射行为)
 /app/blog   192.168.7.0/24(rw,sync,root_squash,no_all_squash,no_subtree_check)
 ​
 # 重启及开机自启服务
 systemctl start rpcbind nfs-server
 systemctl enable rpcbind nfs-server
 ​
 ​
 # 下载wordpress文件
 wget https://cn.wordpress.org/latest-zh_CN.tar.gz
 ​
 # 解压
 tar -zxvf latest-zh_CN.tar.gz
 ​
 # 复制到共享数据
 cp -r wordpress/*  /app/blog
 ​
 # 进入共享数据
 cd /app/blog
 ​
 # 创建apache用户,uid/gid必须与PHP服务器(192.168.7.22)的apache一致
 # (先到192.168.7.22执行 id apache 查看uid,本例为48;若NFS上已有apache用户则跳过)
 groupadd -g 48 apache
 useradd -u 48 -g 48 -s /sbin/nologin apache

 # 验证是否成功
 id apache

 # 让PHP-FPM(apache用户)可写,否则安装/上传图片/装插件会失败
 chown -R apache:apache /app/blog/wp-content

Nginx服务器配置

首先Nginx与PHP服务器都要挂载NFS。实现统一部署方便管理

 # 配置机器
 192.168.7.21网络入口,数据转发,静态文件Nginx服务
 ​
 # 安装依赖
 yum install -y nfs-utils 
 ​
 # 使用脚本安装Nginx
 wget https://fanxing97.cn/download/Nginx.sh
 ​
 # 使用方法(等待1-3分钟)
 bash Nginx.sh
 ​
 # 创建共享目录
 mkdir -p /app/blog
 ​
 # 将NFS的/app/blog挂载至本地的/app/blog
 mount 192.168.7.20:/app/blog /app/blog

然后再配置Nginx

Nginx主要是server中的location的配置。配置location将.php结尾的交给PHP服务器。将.jpg、gif结尾的交给Image。其他配置按默认即可。

 # 编辑配置文件
 vim /usr/local/nginx/conf/nginx.conf
 ​
 # 修改内容
 user  nginx;
 worker_processes  auto;
 ​
 error_log  /var/log/nginx/error.log warn;
 pid        /var/run/nginx.pid;
 ​
 events {
     worker_connections  1024;
 }
 ​
 http {
     include       /usr/local/nginx/conf/mime.types;
     default_type  application/octet-stream;
 ​
     # 日志格式
     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                       '$status $body_bytes_sent "$http_referer" '
                       '"$http_user_agent" "$http_x_forwarded_for"';
 ​
     access_log  /var/log/nginx/access.log  main;
 ​
     sendfile        on;
     tcp_nopush      on;
     tcp_nodelay     on;
     keepalive_timeout  65;
     types_hash_max_size 2048;
 ​
     # 加载额外站点配置(如果有多个虚拟主机,可以单独建文件放在这里)
     include /usr/local/nginx/conf/conf.d/*.conf;
 ​
     server {
         listen       80 default_server;
         server_name  www.test.com;
 ​
         root   /app/blog;
         index  index.php index.html index.htm;
 ​
         # 加载默认补充配置(如额外的location规则)
         include /usr/local/nginx/conf/default.d/*.conf;
         
         # WordPress 伪静态(文章固定链接 /archives/xxx)
         location / {
              try_files $uri $uri/ /index.php?$args;
         }
 ​
         # PHP动态请求 - 转发给PHP-FPM服务器
         location ~* \.php$ {
             fastcgi_pass   192.168.7.22:9000;
             fastcgi_index  index.php;
             fastcgi_param  SCRIPT_FILENAME  /app/blog$fastcgi_script_name;
             include        fastcgi_params;
         }
 ​
         # 图片静态资源 - 转发给Image服务器
         location ~* \.(jpg|jpeg|gif|png|webp|bmp|svg)$ {
             proxy_pass      http://192.168.7.23;
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             expires 30d;
         }
 ​
         # CSS/JS等静态文件 - 本机直接处理
         location ~* \.(css|js|woff|woff2|ttf|eot)$ {
             expires 7d;
             add_header Cache-Control "public, immutable";
         }
 ​
         error_page  404              /404.html;
         location = /40x.html {
             root   /app/blog;
         }
 ​
         error_page  500 502 503 504  /50x.html;
         location = /50x.html {
             root   /app/blog;
         }
     }
 }
 ​
 # 创建nginx用户(系统用户,不允许登录)
 useradd -r -s /sbin/nologin nginx
 ​
 # 创建日志目录(配置里 error_log/access_log 指向这里)
 mkdir -p /var/log/nginx
 ​
 # 重新加载Nginx配置
 /usr/local/nginx/sbin/nginx -s reload

PHP服务器配置

 # 配置机器
 192.168.7.22处理动态数据PHP-FPM
 ​
 # 安装依赖
 yum install -y nfs-utils
 ​
 # 创建共享目录
 mkdir -p /app/blog
 ​
 # 将NFS的/app/blog挂载至本地的/app/blog
 mount 192.168.7.20:/app/blog /app/blog

PHP服务器的配置比较简单,主要讲PHP以FPM模式安装后进行简单的配置即可

 # yum安装PHP 8.3.31
 yum -y install php php-cli php-common php-mysqlnd php-fpm
 ​
 # 编辑配置文件
 vim  /etc/php-fpm.d/www.conf
 ​
 # 只写监听端口,即监听所有IP(大约在第36行)
 listen = 9000
 ​
 # 将这行注释,可以允许所有IP进行访问,否则只能本机访问。(大约在第54行)
 ; listen.allowed_clients = 127.0.0.1
 ​
 # 重启及开机自启
 systemctl start php-fpm
 systemctl enable php-fpm
 ​
 # 注意:yum install php-fpm 后不一定有 apache 用户
 # 指令验证:id apache
 # 没有就建(uid 必须与 NFS 上一致)
 groupadd -g 48 apache && useradd -u 48 -g 48 -s /sbin/nologin apache

Image服务器配置

 # 配置机器
 192.168.7.23图片服务器Nginx服务
 ​
 # 安装依赖
 yum install -y nfs-utils
 ​
 # 使用脚本安装Nginx
 wget https://fanxing97.cn/download/Nginx.sh
 ​
 # 使用方法(等待1-3分钟)
 bash Nginx.sh
 ​
 # 创建共享目录
 mkdir -p /app/blog
 ​
 # 将NFS的/app/blog挂载至本地的/app/blog
 mount 192.168.7.20:/app/blog /app/blog
 ​
 # 编辑配配置文件
 vim /usr/local/nginx/conf/nginx.conf
 ​
 # 修改内容
 user  nginx;
 worker_processes  auto;
 error_log  /usr/local/nginx/logs/error.log  warn;
 pid        /usr/local/nginx/logs/nginx.pid;
 ​
 events {
     worker_connections  1024;
 }
 ​
 http {
     include       /usr/local/nginx/conf/mime.types;
     default_type  application/octet-stream;
     
     sendfile        on;
     keepalive_timeout  65;
     
     # 图片服务器配置
     server {
         listen       80 default_server;   # 加 default_server,任何域名都能兜底
         server_name  www.test.com;
 ​
         # 根目录指向NFS挂载点
         root   /app/blog;
         
         # 索引文件
         index  index.html index.htm;
         
         # 日志配置
         access_log  /usr/local/nginx/logs/images-access.log;
         error_log   /usr/local/nginx/logs/images-error.log;
         
         # 图片缓存优化
         location ~* \.(jpg|jpeg|png|gif|ico|webp|svg)$ {
             expires 30d;
             add_header Cache-Control "public, immutable";
         }
         
         # 禁止访问隐藏文件
         location ~ /\. {
             deny all;
         }
         
         # 错误页面
         error_page  404              /404.html;
         error_page  500 502 503 504  /50x.html;
     }
 }
 ​
 # 创建nginx用户(系统用户,不允许登录)
 useradd -r -s /sbin/nologin nginx
 ​
 # 重新加载Nginx配置
 /usr/local/nginx/sbin/nginx -s reload

MySQL服务器

 # 配置机器
 192.168.7.24数据库服务MySQL服务
 ​
 # 下载安装脚本
 wget https://fanxing97.cn/download/mysql_install.sh
 ​
 # 执行脚本
 source mysql_install.sh
 ​
 # 创建wordpress数据库与远程账号
 mysql -uroot -p
 ​
 CREATE DATABASE wordpress charset utf8mb4;
 CREATE USER 'wordpress'@'192.168.7.%' IDENTIFIED BY 'admin1234';
 GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'192.168.7.%';
 FLUSH PRIVILEGES;

在 NFS服务器 (192.168.7.20) 上配置WordPress:

 # 复制一个模板文件后改名作为主配置文件
 cp wp-config-sample.php wp-config.php           
 ​
 # 编辑配置文件
 vim wp-config.php
 ​
 # 编辑内容
 /** WordPress数据库的名称 */
 define('DB_NAME', 'wordpress');                      # wpdb为MySQL中创建的数据库
 ​
 /** MySQL数据库用户名 */
 define('DB_USER', 'wordpress');                     # wpadm为MySQL中授权的用户
 ​
 /** MySQL数据库密码 */
 define('DB_PASSWORD', 'admin1234');                # 授权用户的密码
 ​
 /** MySQL主机 */
 define('DB_HOST', '192.168.7.24');                # MySQL主机地址

统一验证

 # 验证 Nginx 配置
/usr/local/nginx/sbin/nginx -t

# 验证 PHP 动态链路(访问 WordPress 页面)
# 访问 WordPress 首页
curl -I http://192.168.7.21/

# 访问安装页面(应该返回 302 或 200)
curl -I http://192.168.7.21/wp-admin/install.php

# 或者使用您之前的 index.php
curl -I http://192.168.7.21/index.php

# 创建测试图片(如果还没有)
cd /app/blog

# 方法1:复制已有图片
cp wp-includes/images/w-logo-blue-white-bg.png test.jpg
chown nginx:nginx test.jpg
chmod 644 test.jpg

# 方法2:如果上面没有执行过,用这个方法
cp /app/blog/wp-includes/images/w-logo-blue-white-bg.png /app/blog/test.jpg
chown nginx:nginx /app/blog/test.jpg
chmod 644 /app/blog/test.jpg

# 请求图片(返回 200 表示成功)
curl -s -o /dev/null -w "HTTP Status: %{http_code}\n" http://192.168.7.21/test.jpg

# 查看图片响应头
curl -I http://192.168.7.21/test.jpg

📋 Nginx 动静分离诊断报告

架构确认(5 台机器)

 用户请求 → t4 网络Nginx(192.168.7.21) ── PHP动态 ──→ t5 PHP-FPM(192.168.7.22) ──→ t1 MySQL(192.168.7.24)
                           │
                           ├── 图片静态 ──→ t3 图像Nginx(192.168.7.23)
                           │
                           └── CSS/JS 本机处理
 共享代码:NFS t2(192.168.7.20:/app/blog,三台均已挂载 ✅)

📋 部署排错要点(踩坑记录)

现象

原因

解决

nginx -t 报 getpwnam("nginx") failed

系统没有 nginx 用户

useradd -r -s /sbin/nologin nginx

改了配置不生效(还是旧页面)

只改了文件没 reload

nginx -s reload 或 kill -HUP $(cat /usr/local/nginx/logs/nginx.pid)

nginx -s reload 报 invalid PID number

新旧配置 pid 路径不一致

kill -HUP $(cat /usr/local/nginx/logs/nginx.pid)

php-fpm 起不来,报 unknown entry '#listen.allowed_clients'

注释用了 # 而不是 ;

改成 ; listen.allowed_clients = 127.0.0.1

WordPress 装好后文章页 404

没有伪静态规则

server 块加 location / { try_files $uri $uri/ /index.php?$args; }

WordPress 无法上传图片/装插件

php-fpm(apache)写不了 NFS 上的 wp-content

NFS 上建 apache 用户(uid一致)后 chown -R apache:apache /app/blog/wp-content

实测现状(你的 5 台机器)

检查项

当前状态

结论

NFS 写入 /etc/fstab

❌ 没写

重启后 t3/t4/t5 挂载全丢

Nginx 开机自启服务

❌ 没有 systemd 服务

重启后 nginx 不会启动

MySQL 开机自启

✅ enabled

mysql_install.sh 已处理好

firewalld

✅ inactive

侥幸,新机器默认可能开启

SELinux

✅ Disabled

侥幸,新机器默认可能是 Enforcing

执行顺序(避免白忙)

 ① NFS服务器: 装NFS → 配exports → 起服务 → 放wordpress文件 → 建apache用户(48) → chown wp-content
 ② MySQL: 装好 → 记住初始密码改root密码 → 建库建用户
 ③ t3/t4/t5: 装NFS → 挂载(写fstab) → 装nginx/php → 改配置 → 建nginx用户 → 建日志目录 → reload
 ④ 全部完成后: 浏览器访问 http://192.168.7.21 安装WordPress