linux中级_LNMP架构+负载均衡_部署wordpress

TJCcc 发布于 2025-12-17 29 次阅读


一、架构概览

10.0.0.4 - LB服务器(Haproxy实现四层负载,四层负载分配的是用户连接)

172.16.1.5 - LB01服务器(nginx实现七层负载,七层负载分配的是用户的多个请求)

172.16.1.6 - LB02服务器(nginx实现七层负载)

172.16.1.7 - web01(Nginx + php-fpm)

172.16.1.9 - web02(Nginx + php-fpm)

172.16.1.51 - MySQL服务器

172.16.1.31 - NFS服务器

环境:CentOS7虚拟机

二、NFS服务器配置

在.31服务器上:

1.安装NFS服务器

yum install -y nfs-utils rpcbind

2.创建wordpress共享目录

mkdir -p /data/wordpress/wp-content/

mkdir -p /data/wordpress/uploads/

3.设置权限

chown -R nfsnobody.nfsnobody /data/wordpress/wp-content

chown -R nfsnobody.nfsnobody /data/wordpress/uploads

4.配置NFS共享文件

位置:/etc/exports

添加:

/data/wordpress/wp-content 172.16.1.0/24(rw,sync,all_squash)

5.启动服务并配置开机自启动

systemctl start nfs-server

systemctl enable nfs-server

systemctl start rpcbind

systemctl enable rpcbind

6.验证共享目录

showmount -e localhost

三、MySQL服务器配置

在172.16.1.51中

1.安装mariadb

yum install -y mariadb-server mariadb

2.启动mariadb

systemctl start mariadb

systemctl enable mariadb

3.运行安全配置脚本

mysql_secure_installation

4.创建wordpress数据库和用户

mysql -u root -p

输入root密码进入数据库

创建数据库:

create database if not exists wordpress default character set utf8mb4 collate utf8mb4_unicode_ci;

创建wordpress用户并授权

createuser 'wpuser'@'172.16.1.%' identified by 'TJCKD1ZNb';

grant all privileges on wordpress.* to 'wpuser'@'172.16.1.%';

flush privileges;#刷新权限

验证用户创建及其权限

select user, host from mysql.user where user = 'wpuser';

四、web01服务器配置

在172.16.1.7中:

1.安装基础软件

安装epel仓库

yum install -y epel-release

安装nginx

yum install -y nginx

安装Remi仓库获取php 7.4

yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum-config-manager --enable remi-php74

2.安装php及其相关拓展

yum install -y php php-fpm php-mysqlnd php-gd php-mbstring php-xml \
php-curl php-zip php-json php-opcache

3.安装nfs客户端

yum install -y nfs-utils

4.配置php-fpm

配置文件:

/etc/php-fpm.d/www.conf

备份配置文件:

cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.bak

编辑配置文件:

vim /etc/php-fpm.d/www.conf

改成:

user = nginx

group = nginx

5.创建php会话目录并设置权限

mkdir -p /var/lib/php/session

chown -R nginx.nginx /var/lib/php/session

6.启动php-fpm

systemctl start php-fpm

systemctl enable php-fpm

systemctl status php-fpm

7.配置NFS挂载

创建挂载点:

mkdir -p /var/www/html/wordpress/wp-content

挂载:

mount -t nfs 172.16.1.31:/data/wordpress/wp-content /var/www/html/wordpress/wp-content

验证挂载:

df -h

配置开机自动挂载:

vim /etc/fstab

键入:

172.16.1.31:/data/wordpress/wp-content /var/www/html/wordpress/wp-content nfs defaults_netdev 0 0

设置wordpress的目录权限:

chown -R nginx.nginx /var/www/html/wordpress

8.配置nginx

配置文件:/etc/nginx/nginx.conf

nginx.conf文件里面包含了conf.d/文件夹,所以你可以在conf.d里面新建***.conf文件即可编写配置

备份原始配置文件:

cp /etc/nginx/nginx.conf /etc/nginx.conf.bak

创建wordpress配置文件:

touch /etc/nginx/conf.d/wordpress.conf

vim !$

键入:

server{

listen 80;

server_name www.wp.com;

root /var/www/html/wordpress/

index index.html index.htm index.php;

# WordPress重写规则
location / {
try_files $uri $uri/ /index.php?$args;
}

# 禁止访问敏感文件
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
}

# 缓存静态文件
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
    log_not_found off;
}

# PHP处理
location ~ \.php$ {
    try_files $uri =404;
    fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;

    # 增加PHP超时时间
    fastcgi_read_timeout 300;
}

# 禁止访问特定文件
location ~* \.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|\/(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock))$|\/code-style\.pl$|\.(log|svn|git)|maintenance\.html|README\.html {
    deny all;
    access_log off;
    log_not_found off;
}

# 访问日志
access_log /var/log/nginx/wordpress_access.log;
error_log  /var/log/nginx/wordpress_error.log;

}

测试配置文件语法:

nginx -t

启动nginx服务:

systemctl start nginx

systemctl enable nginx

五、部署wordpress

1.下载wordpress并解压

去家目录:

cd

wget https://wordpress.org/latest.tar.gz

解压:

tar -zxvf latest.tar.gz

然后会生成一个wordpress文件夹,里面有wp-admin/ wp-content wp-????/

2.复制wordpress文件夹

复制wordpress文件夹下的内容到/var/www/html/wordpress/下

cp -r wordpress/* /var/www/html/wordpress/

然后原来的wp-content(空)会被新生成的wp-content(里面有index.php plugins themes)给覆盖

3.配置wordpress配置文件

配置文件:/var/www/html/wordpress/wp-config.php

vim !$

编辑:

//MySQL设置

define('DB_NAME','');

define('DB_USER','');

define('DB_PASSWORD','');

define('DB_HOST','');

define('DB_CHARSET','');

//从NFS服务器加载wp-content

define('WP_CONTENT_DIR','/var/www/html/wordpress/wp-content');

define('WP_CONTENT_URL','http://' . $_SERVER['HTTP_HOST'] . '/wp-content');

4.设置文件权限

chown -R nginx.nginx /var/www/html/wordpress

并保证文件夹的权限是755,文件的权限是644

5.重启服务

systemctl restart nginx

systemctl restart php-fpm

六、部署web02服务器

在完成了前面四步的时候,你就可以构造出web01,NFS,mysql这个小型服务器架构了,接下来就是部署web02,把web02给加入进去,实现一个小型的web服务器集群。

1、在web02(10.0.0.9)上的配置

1.1 安装基础软件(同web01)

yum install -y epel-release
yum install -y nginx

# 安装Remi仓库和PHP 7.4
yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum-config-manager --enable remi-php74

# 安装PHP及其扩展
yum install -y php php-fpm php-mysqlnd php-gd php-mbstring php-xml \
php-curl php-zip php-json php-opcache

# 安装NFS客户端
yum install -y nfs-utils

1.2 配置PHP-FPM(同web01)

# 备份并编辑配置文件
cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.bak
vim /etc/php-fpm.d/www.conf

修改:

user = nginx
group = nginx


*********这里我见建议是直接拷贝web01的/etc/php-fpm.d/www.conf文件下来***************
*********因为默认的配置文件的话没有 listen = /var/run/php/php-fpm.socket 这一行*****
*********否则到最后访问网站会出现502错误********************************************
# 创建会话目录
mkdir -p /var/lib/php/session
chown -R nginx.nginx /var/lib/php/session

# 启动php-fpm
systemctl start php-fpm
systemctl enable php-fpm

3. 配置NFS挂载

# 创建网站目录
mkdir -p /var/www/html/wordpress

# 测试NFS连接
showmount -e 172.16.1.31

# 挂载NFS共享(注意:只挂载wp-content目录)
mkdir -p /var/www/html/wordpress/wp-content
mount -t nfs 172.16.1.31:/data/wordpress/wp-content /var/www/html/wordpress/wp-content

# 验证挂载
df -h | grep nfs

# 配置开机自动挂载
echo "172.16.1.31:/data/wordpress/wp-content /var/www/html/wordpress/wp-content nfs defaults,_netdev 0 0" >> /etc/fstab

4. 关键步骤:从web01同步WordPress核心文件

# 方法1:使用rsync从web01同步(推荐)
# 确保web01和web02之间可以ssh连接
rsync -avz root@172.16.1.7:/var/www/html/wordpress/ /var/www/html/wordpress/ --exclude=wp-content

# 或者方法2:手动复制(如果不能用rsync)
# 在web01上打包WordPress核心文件(排除wp-content)
# ssh到web01执行:
# cd /var/www/html
# tar --exclude=wordpress/wp-content -czf wordpress-core.tar.gz wordpress/
# scp wordpress-core.tar.gz root@10.0.0.9:/root/

# 然后在web02上:
# tar -xzf /root/wordpress-core.tar.gz -C /var/www/html/

5. 配置wp-config.php(从web01复制)

# 从web01复制配置文件
scp root@172.16.1.7:/var/www/html/wordpress/wp-config.php /var/www/html/wordpress/

# 或者手动创建(内容与web01相同)
vim /var/www/html/wordpress/wp-config.php

确保内容包含:

define('DB_NAME', 'wordpress');
define('DB_USER', 'wpuser');
define('DB_PASSWORD', 'TJCKD1ZNb');
define('DB_HOST', '172.16.1.51');  # MySQL服务器IP
define('DB_CHARSET', 'utf8mb4');

define('WP_CONTENT_DIR', '/var/www/html/wordpress/wp-content');
define('WP_CONTENT_URL', 'http://' . $_SERVER['HTTP_HOST'] . '/wp-content');

6. 设置权限

chown -R nginx.nginx /var/www/html/wordpress
find /var/www/html/wordpress -type d -exec chmod 755 {} \;
find /var/www/html/wordpress -type f -exec chmod 644 {} \;

7. 配置Nginx

# 创建配置文件
vim /etc/nginx/conf.d/wordpress.conf

使用与web01完全相同的配置:

server {
    listen 80;
    server_name www.wp.com;  # 与web01相同的域名
    root /var/www/html/wordpress/
    index index.html index.htm index.php


    # 其他配置与web01完全相同...
    # 复制web01的nginx配置到这里
}

测试并启动:

nginx -t
systemctl start nginx
systemctl enable nginx

四、验证配置

1. 测试数据库连接

# 在web02上测试
php -r "
\$conn = new mysqli('172.16.1.51', 'wpuser', 'TJCKD1ZNb', 'wordpress');
if (\$conn->connect_error) {
    die('连接失败: ' . \$conn->connect_error);
} else {
    echo '数据库连接成功!';
    \$conn->close();
}
"

2. 测试文件同步

# 在web02上创建测试文件
echo "Web02 test at $(date)" > /var/www/html/wordpress/wp-content/web02_test.txt

# 在web01上检查(ssh到web01)
# cat /var/www/html/wordpress/wp-content/web02_test.txt

3. 测试WordPress访问

# 创建测试PHP文件
echo "<?php
require_once('/var/www/html/wordpress/wp-load.php');
echo 'WordPress加载成功!用户名:' . wp_get_current_user()->user_login;
?>" > /var/www/html/wordpress/test_wp.php

# 通过浏览器访问 http://10.0.0.9/test_wp.php
# 完成后删除测试文件
rm -f /var/www/html/wordpress/test_wp.php

七、部署LB01服务器

在10.0.0.5中:

1. 下载nginx

yum install -y epel-release

yum install -y nginx

2. 配置文件

vim /etc/nginx/conf.d/load-balance.conf

写入配置文件:

upstream webs{
server 172.16.1.7:80;
server 172.16.1.9:80;

# nginx健康状态检测需要用到nginx_upstream_check_module

}

server{
listen 80;
server_name www.wp.cc;
access_log /var/log/nginx/lb-access.log main;

location / {
# 反向代理设置
proxy_pass http://webs;

    # 重要的代理头部
    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 X-Forwarded-Proto $scheme;

    # 超时设置
    proxy_connect_timeout 5s;
    proxy_send_timeout 10s;
    proxy_read_timeout 10s;

    # 缓冲设置
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;

    # 其他优化
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}

}

3. 启动nginx并设置开机自启动

nginx -t

systemctl start nginx

systemctl enable nginx

八、部署LB02服务器

1. 下载nginx

yum install -y epel-release

yum install -y nginx

2. 拷贝LB01的配置文件

scp 172.16.1.5:/etc/nginx/conf.d/load-balance.conf /etc/nginx/conf.d/

3. 启动nginx并设置开机自启动

nginx -t

systemctl start nginx

systemctl enable nginx

九、部署LB服务器

1. 下载Haproxy

yum install -y haproxy

2. 配置文件

位置:/etc/haproxy/haproxy.cfg

vim /etc/haproxy/haproxy.cfg

写入配置文件:

global
log /dev/log local0
maxconn 100000
user haproxy
group haproxy
daemon

defaults
mode tcp
timeout connect 5s
timeout client 30s
timeout server 30s
log global

frontend tcp_front
bind *:80
default_backend tcp_back

backend tcp_back
balance roundrobin
server lb01 172.16.1.5:80 check maxconn 10000
server lb02 172.16.1.6:80 check maxconn 10000

listen stats
bind *:1936
mode http
stats enable
stats uri /
stats hide-version
stats auth admin:password

3. 启动HAProxy

systemctl start haproxy
systemctl enable haproxy

十、会话一致问题

由于web01和web02是独立的,用户登录状态不会自动同步。

解决方案:

方案A:使用数据库存储session(推荐)

# 在web01和web02上都修改
vim /etc/php-fpm.d/www.conf

# 添加
php_value[session.save_handler] = redis
php_value[session.save_path] = "tcp://172.16.1.51:6379"

# 安装Redis服务器(可以在MySQL服务器或单独服务器上)

方案B:使用NFS存储session

# 在NFS服务器上创建共享目录
mkdir -p /data/php-session
chown nfsnobody.nfsnobody /data/php-session

# 在/etc/exports中添加
/data/php-session 172.16.1.0/24(rw,sync,all_squash)

# 在web01和web02上挂载并修改php.ini
mkdir -p /var/lib/php/session
mount -t nfs 172.16.1.31:/data/php-session /var/lib/php/session

vim /etc/php.ini
# 修改
session.save_path = "/var/lib/php/session"

十一、nginx健康状态检测

1. 安装健康检查模块

在172.16.1.5(LB01)和172.16.1.6(LB02)上执行:

1.1 查看nginx版本:

nginx -v

1.2 下载nginx源码和模块:

# 1. 安装编译工具
yum install -y gcc make pcre-devel zlib-devel openssl-devel git

# 2. 进入源码目录
cd /usr/local/src

# 3. 下载Nginx源码(版本要匹配)
wget http://nginx.org/download/nginx-1.20.1.tar.gz
tar -zxvf nginx-1.20.1.tar.gz

# 4. 下载健康检查模块
# 使用Gitee镜像
git clone https://gitee.com/mirrors/nginx_upstream_check_module.git

1.3 打补丁并编译:

# 1. 进入Nginx源码目录
cd /usr/local/src/nginx-1.20.1

# 2. 打补丁(重要!)
patch -p1 < /usr/local/src/nginx_upstream_check_module/check_1.20.1+.patch
# 如果报错,试试其他补丁文件,如:check_1.16.0+.patch

# 3. 查看当前编译参数
nginx -V 2>&1 | grep 'configure arguments'

# 4. 重新配置(添加健康检查模块)
./configure \
    --prefix=/usr/share/nginx \
    --sbin-path=/usr/sbin/nginx \
    --modules-path=/usr/lib64/nginx/modules \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --pid-path=/run/nginx.pid \
    --lock-path=/run/lock/subsys/nginx \
    --user=nginx \
    --group=nginx \
    --with-compat \
    --with-file-aio \
    --with-http_ssl_module \
    --with-http_stub_status_module \
    --with-http_realip_module \
    --with-http_gzip_static_module \
    --with-http_v2_module \
    --with-pcre \
    --with-pcre-jit \
    --with-threads \
    --add-module=/usr/local/src/nginx_upstream_check_module

# 5. 编译
make

# 6. 备份旧Nginx
cp /usr/sbin/nginx /usr/sbin/nginx.backup

# 7. 停止Nginx
systemctl stop nginx

# 8. 安装新编译的Nginx
cp objs/nginx /usr/sbin/nginx

# 9. 验证模块
nginx -V 2>&1 | grep check_module
# 应该看到:--add-module=/usr/local/src/nginx_upstream_check_module

2. 配置健康检查

2.1 修改nginx配置

# 编辑Nginx配置文件
vim /etc/nginx/conf.d/load-balance.conf

# 在upstream模块中添加健康检查配置:
upstream wordpress_backend {
    # 后端服务器
    server 172.16.1.7:80;
    server 172.16.1.9:80;
    
    # 健康检查配置(核心!)
    check interval=3000 rise=2 fall=3 timeout=2000 type=http;
    check_http_send "HEAD / HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

# 在server模块中添加健康检查状态页面:
server {
    listen 80;
    server_name www.wp.com;
    root /var/www/html/wordpress/;
    index index.php index.html;
    
    # WordPress重写规则
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    
    # PHP处理
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    
    # 代理到后端服务器
    location @proxy {
        proxy_pass http://wordpress_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;
    }
    
    # 健康检查状态页面(重要!)
    location /status {
        check_status;
        access_log off;
        # 只允许内网访问
        allow 172.16.1.0/24;
        deny all;
    }
}

3. 测试并重启nginx

# 1. 测试配置文件
nginx -t
# 应该输出:nginx: configuration file /etc/nginx/nginx.conf test is successful

# 2. 启动Nginx
systemctl start nginx

# 3. 查看状态
systemctl status nginx

4. 测试健康检查功能

# 1. 查看状态页面
curl http://172.16.1.5/status
# 应该看到表格,显示服务器状态

# 2. 查看JSON格式状态
curl http://172.16.1.5/status?format=json
# 看到JSON数据

# 3. 测试后端服务器
curl -I http://172.16.1.7
curl -I http://172.16.1.9

十二、架构的数据流向

让我们从客户端点击"刷新"按钮开始,一步一步追踪整个数据流向。这就像一部网络世界的"漫游记"。

一、完整的数据旅程

第一阶段:客户端浏览器

用户 → 浏览器 → 操作系统网络栈
  1. 用户动作:用户在浏览器中按F5或点击刷新按钮
  2. 浏览器行为
  • 浏览器检查本地DNS缓存中是否有 www.wp.com 的解析记录
  • 如果有缓存且未过期,直接使用缓存的IP;否则进行DNS查询
  1. DNS解析
   # 假设你的DNS将 www.wp.com 解析到 172.16.1.4
   浏览器 → 本地DNS缓存 → ISP DNS → 递归查询 → 权威DNS
                                 ↓
                          返回: www.wp.com = 172.16.1.4

第二阶段:到达四层负载均衡器 (HAProxy, 172.16.1.4)

浏览器 → HAProxy (TCP层处理)
  1. TCP握手开始
   # 三次握手
   浏览器: SYN → HAProxy(172.16.1.4:80)
   HAProxy: SYN-ACK → 浏览器
   浏览器: ACK → HAProxy
   # 此时TCP连接建立完成
  1. HAProxy内部处理
   # HAProxy收到SYN包时的处理流程
   收到SYN包 → 检查frontend配置 → 选择backend → 选择后端服务器
       ↓
   1. 查看 /etc/haproxy/haproxy.cfg
   2. 匹配到 frontend http_frontend (监听 *:80)
   3. 找到对应的 backend http_backend
   4. 根据负载均衡算法选择后端:
      - 如果是 roundrobin: 轮流选择 172.16.1.5 或 172.16.1.6
      - 如果是 leastconn: 选择当前连接数最少的那台
   5. 假设选择了 172.16.1.6
  1. HAProxy建立到后端的连接
   # HAProxy与后端建立独立TCP连接
   HAProxy: SYN → 172.16.1.6:80
   172.16.1.6: SYN-ACK → HAProxy
   HAProxy: ACK → 172.16.1.6
   # 现在有两个TCP连接:
   # 连接A: 浏览器 ↔ HAProxy
   # 连接B: HAProxy ↔ 172.16.1.6

第三阶段:七层负载均衡器 (Nginx, 172.16.1.6)

HAProxy → Nginx (HTTP层开始)
  1. Nginx接收请求
   # Nginx的worker进程接收连接
   # 假设使用epoll事件驱动模型
   事件循环: epoll_wait() 检测到新连接
   → 调用 accept() 接受连接
   → 创建连接结构体 ngx_connection_t
   → 开始接收HTTP请求数据
  1. 解析HTTP请求
   # Nginx解析浏览器发送的HTTP请求
   接收到的原始数据:
   GET / HTTP/1.1
   Host: www.wp.com
   User-Agent: Mozilla/5.0...
   Accept: text/html,application/xhtml+xml...
   Cookie: wordpress_logged_in_xxx=...
   Connection: keep-alive
  1. Nginx处理逻辑
   # Nginx根据配置文件处理
   1. 匹配 server_name: www.wp.com
   2. 找到对应的 location /
   3. 查看 upstream 配置:
      upstream wordpress_backend {
          server 172.16.1.7:80;
          server 172.16.1.9:80;
      }
   4. 选择后端Web服务器(假设选择 172.16.1.7)
   5. 添加代理头部:
      X-Real-IP: <原始客户端IP>
      X-Forwarded-For: <原始客户端IP>
      X-Forwarded-Proto: http
  1. 建立到Web服务器的连接
    bash # Nginx与Web服务器建立第三个TCP连接 Nginx: SYN → 172.16.1.7:80 172.16.1.7: SYN-ACK → Nginx Nginx: ACK → 172.16.1.7 # 现在有三个TCP连接: # 连接A: 浏览器 ↔ HAProxy # 连接B: HAProxy ↔ Nginx # 连接C: Nginx ↔ Web服务器

第四阶段:Web服务器 (172.16.1.7)

Nginx → Web服务器 → PHP-FPM
  1. Web服务器接收请求# Nginx on 172.16.1.7 接收请求 1. 接收完整的HTTP请求 2. 解析头部,看到 Host: www.wp.com 3. 匹配到 wordpress 配置 4. 根据 location ~ \.php$ 转发给PHP-FPM
  2. PHP-FPM处理# Nginx通过FastCGI协议与PHP-FPM通信 1. Nginx将HTTP请求转换为FastCGI请求: SCRIPT_FILENAME: /var/www/html/wordpress/index.php REQUEST_METHOD: GET QUERY_STRING: (空) DOCUMENT_ROOT: /var/www/html/wordpress REMOTE_ADDR: <原始客户端IP> 2. 通过Unix socket发送到PHP-FPM: /var/run/php-fpm/php-fpm.sock 3. PHP-FPM worker进程处理: - 从空闲worker池中分配一个worker - worker执行 /var/www/html/wordpress/index.php
  3. WordPress执行# WordPress的index.php执行流程 1. 加载 wp-config.php 2. 读取数据库配置: DB_HOST=172.16.1.51 3. 连接MySQL数据库 4. 执行SQL查询获取页面内容 5. 读取NFS共享的主题文件 6. 生成HTML页面
  4. 数据库访问# WordPress连接MySQL的过程 PHP-FPM worker → TCP连接 → 172.16.1.51:3306 ↓ 认证: wpuser/TJCKD1ZNb 查询: SELECT * FROM wp_posts... ↓ MySQL返回查询结果
  5. NFS文件访问
    bash # 读取主题文件的过程 PHP-FPM: stat("/var/www/html/wordpress/wp-content/themes/xxx/style.css") ↓ 内核NFS客户端: RPC调用 ↓ 网络: 172.16.1.7 → 172.16.1.31:2049 ↓ NFS服务器: 读取磁盘文件 ↓ 返回文件内容

第五阶段:响应返回路径

WordPress → PHP-FPM → Nginx → HAProxy → 浏览器
  1. 生成响应# PHP执行完成,返回HTML PHP-FPM: 生成完整的HTML页面 → 通过FastCGI返回给Nginx → Nginx接收响应数据
  2. Nginx处理响应# Nginx可能进行的优化 1. Gzip压缩(如果配置了) 2. 添加响应头: Content-Type: text/html; charset=UTF-8 Server: nginx X-Powered-By: PHP/7.4 3. 可能写入缓存(如果配置了) 4. 发送响应给HAProxy
  3. HAProxy转发响应# HAProxy只是转发TCP数据包 接收Nginx的TCP数据包 → 转发给浏览器 不解析HTTP内容,只处理TCP层
  4. 浏览器接收响应# 浏览器渲染页面 1. 接收HTTP响应头 2. 接收HTML内容 3. 解析HTML,发现需要CSS/JS/图片 4. 对每个资源重复上述过程(可能并行)
  5. TCP连接关闭
    bash # 根据HTTP keep-alive设置 # 如果是HTTP/1.1 keep-alive: 连接保持,等待下一个请求 # 如果是短连接: 浏览器: FIN → HAProxy → Nginx → Web服务器 四向挥手,关闭所有连接

二、关键路径总结

物理路径:

客户端
   ↓ (HTTP/TCP)
四层LB: HAProxy (172.16.1.4:80)
   ↓ (纯TCP转发)
七层LB: Nginx (172.16.1.6:80)
   ↓ (HTTP代理)
Web服务器: Nginx + PHP-FPM (172.16.1.7:80)
   ↓ (FastCGI)
PHP-FPM进程
   ↓ (MySQL TCP连接)
数据库: MariaDB (172.16.1.51:3306)
   ↓ (NFS/RPC)
文件存储: NFS (172.16.1.31:2049)

协议栈变化:

浏览器端: HTTP over TCP
     ↓
HAProxy: 只看到TCP层
     ↓
Nginx(LB): 解析HTTP,重新封装
     ↓
Web服务器: HTTP → FastCGI
     ↓
PHP-FPM: 执行PHP
     ↓
MySQL: MySQL协议 over TCP
     ↓
NFS: RPC over TCP

三、为什么四层+七层架构能解决高并发问题?

1. 连接管理对比

传统单层架构(假设10万并发)

浏览器(10万连接) → Nginx七层LB(10万连接) → Web服务器
问题:
- Nginx需要维护10万个文件描述符
- 需要10万个本地端口(但临时端口只有~28000个)
- 每个连接都需要HTTP解析,CPU压力大

四层+七层架构

浏览器(10万连接) → HAProxy四层(10万连接) → Nginx集群(每个2.5万连接) → Web服务器
优势:
- HAProxy: 只处理TCP,10万连接轻松应对
- 每个Nginx: 只处理部分连接(如2.5万),在合理范围内
- 端口复用: HAProxy可以用少量端口与Nginx通信

2. 端口限制的数学解释

# Linux临时端口范围
cat /proc/sys/net/ipv4/ip_local_port_range
# 输出: 32768   60999
# 可用端口数: 60999 - 32768 + 1 = 28232

# 单Nginx场景:
# 每个客户端连接需要一个本地端口
# 最大并发连接数 ≈ 28232
# 超过这个数就会出现"端口耗尽"

# 四层+七层场景:
# HAProxy到Nginx的连接可以复用
# HAProxy端口使用: 100个连接可能只用几个端口
# Nginx集群: 每个实例连接数控制在2.8万以内

3. 性能优化点

HAProxy层优化

# 内核bypass技术
# HAProxy可以直接从网卡DMA读取数据,减少拷贝
# 使用SO_REUSEPORT允许多进程监听同一端口
# 零拷贝技术转发TCP数据包

Nginx层优化

# 可以专注于HTTP优化
# 启用缓存:proxy_cache
# 启用压缩:gzip
# 连接池:keepalive到后端

四、一次完整请求的时间线(假设所有缓存都未命中)

时间     事件
-----   --------------------------------------------------
0ms     用户点击刷新
1ms     DNS解析完成(本地无缓存)
2ms     TCP握手开始
3ms     TCP握手完成
4ms     HTTP请求发送
5ms     请求到达HAProxy
6ms     HAProxy建立到Nginx的连接
7ms     请求到达Nginx七层LB
8ms     Nginx解析HTTP头部
9ms     Nginx建立到Web服务器的连接
10ms    请求到达Web服务器
11ms    Web服务器转发给PHP-FPM
12ms    PHP-FPM开始执行index.php
15ms    WordPress连接数据库
20ms    数据库返回查询结果
25ms    WordPress读取NFS文件
30ms    PHP执行完成
31ms    Web服务器发送响应
32ms    Nginx接收响应
33ms    Nginx发送响应给HAProxy
34ms    HAProxy转发给浏览器
35ms    浏览器开始接收HTML
40ms    浏览器解析HTML,发起CSS/JS请求
...     并行加载所有资源
500ms   页面完全加载完成

五、故障排查视角

如果页面加载缓慢,可以从后往前排查:

  1. 查看浏览器开发者工具:哪个阶段耗时?
  2. 检查HAProxy日志tail -f /var/log/haproxy.log
  3. 查看Nginx访问日志tail -f /var/log/nginx/access.log
  4. 检查PHP-FPM慢日志:查看是否有慢查询
  5. 监控MySQL慢查询mysqldumpslow /var/log/mysql-slow.log
  6. 检查NFS性能nfsstat -c

六、这种架构的核心思想

你可以把这个架构想象成一个高效的物流系统

  • HAProxy(四层):像高速公路收费站
  • 只关心有多少辆车(连接),不关心车里装什么(HTTP内容)
  • 快速分流到不同车道(Nginx实例)
  • 处理能力:每分钟可通过10万辆车
  • Nginx集群(七层):像物流分拣中心
  • 拆开包裹查看内容(解析HTTP)
  • 根据地址分拣到不同配送区域(Web服务器)
  • 还能打包优化(Gzip压缩)
  • Web服务器:像配送站
  • 处理具体的配送任务(执行PHP)
  • 数据库/NFS:像仓库
  • 提供货物(数据/文件)

这种分层设计让每个组件专注于自己最擅长的工作,通过分工合作实现整体高性能。

唯有极致沉淀,才能造就辉煌。
最后更新于 2025-12-20