ThinkPHP 集群部署完整指南
目录
- [1. 概述](#1. 概述)
- [2. 架构设计](#2. 架构设计)
- [3. 环境准备](#3. 环境准备)
- [4. 负载均衡配置](#4. 负载均衡配置)
- [5. Session 共享方案](#5. Session 共享方案)
- [6. 文件存储方案](#6. 文件存储方案)
- [7. 缓存方案](#7. 缓存方案)
- [8. 数据库优化](#8. 数据库优化)
- [9. 代码部署策略](#9. 代码部署策略)
- [10. 常见问题与解决方案](#10. 常见问题与解决方案)
1. 概述
1.1 什么是集群部署
集群部署是指将应用部署在多台服务器上,通过负载均衡将请求分发到不同的服务器节点,以实现:
- 高可用性:单点故障不影响整体服务
- 高性能:多节点并行处理提升并发能力
- 可扩展性:根据负载动态增减节点
1.2 ThinkPHP 集群部署核心挑战
| 挑战 | 说明 |
|---|---|
| Session 共享 | 多节点间 Session 需统一存储 |
| 文件同步 | 上传文件需集中存储 |
| 缓存同步 | 多节点缓存数据一致性 |
| 代码同步 | 多节点代码版本一致 |
| 日志收集 | 集中管理各节点日志 |
2. 架构设计
2.1 推荐架构图
┌─────────────────┐
│ CDN / WAF │
└────────┬────────┘
│
┌────────▼────────┐
│ Nginx 负载均衡 │
│ (主/备 HA) │
└────────┬────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
┌────────▼────────┐ ┌────────▼────────┐ ┌────────▼────────┐
│ Web Node 1 │ │ Web Node 2 │ │ Web Node N │
│ (PHP-FPM) │ │ (PHP-FPM) │ │ (PHP-FPM) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└────────────────────────┼────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
┌────────▼────────┐ ┌────────▼────────┐ ┌────────▼────────┐
│ Redis │ │ MySQL │ │ NFS/OSS │
│ (Session/缓存) │ │ (主从复制) │ │ (文件存储) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
2.2 服务器角色规划
| 角色 | 数量 | 配置建议 | 说明 |
|---|---|---|---|
| 负载均衡 (Nginx) | 2台 | 2C4G | 主备模式,Keepalived 实现高可用 |
| Web 节点 (PHP) | 2+ 台 | 4C8G | 运行 ThinkPHP 应用 |
| Redis | 3台 | 4C8G | 哨兵模式或集群模式 |
| MySQL | 2+ 台 | 8C16G | 主从复制,读写分离 |
| NFS/OSS | 按需 | - | 文件集中存储 |
3. 环境准备
3.1 基础软件版本
bash
# 操作系统
CentOS 7+ / Ubuntu 18.04+
# 软件版本
Nginx >= 1.18
PHP >= 7.4 (推荐 8.0+)
MySQL >= 5.7 (推荐 8.0)
Redis >= 5.0
Composer >= 2.0
3.2 PHP 必要扩展
bash
# 安装 PHP 扩展
yum install -y php-fpm php-mysqlnd php-gd php-xml php-mbstring \
php-curl php-zip php-bcmath php-redis php-opcache
# 验证安装
php -m | grep -E "redis|pdo_mysql|opcache"
3.3 ThinkPHP 配置调整
3.3.1 环境变量配置 .env
env
# 应用配置
APP_DEBUG = false
APP_TRACE = false
# 数据库配置(主从)
DB_TYPE = mysql
DB_HOST = 192.168.1.100 # 主库地址
DB_HOST_READ = 192.168.1.101 # 从库地址
DB_NAME = thinkphp
DB_USER = root
DB_PASS = your_password
DB_PORT = 3306
# Redis 配置
REDIS_HOST = 192.168.1.102
REDIS_PORT = 6379
REDIS_PASSWORD = your_redis_password
REDIS_SELECT = 0
# Session 配置
SESSION_DRIVER = redis
SESSION_EXPIRE = 3600
# 缓存配置
CACHE_DRIVER = redis
3.3.2 数据库配置 config/database.php
php
<?php
return [
'default' => env('database.driver', 'mysql'),
'connections' => [
'mysql' => [
'type' => env('database.type', 'mysql'),
'hostname' => env('database.hostname', '192.168.1.100'),
'database' => env('database.database', 'thinkphp'),
'username' => env('database.username', 'root'),
'password' => env('database.password', ''),
'hostport' => env('database.hostport', '3306'),
'charset' => env('database.charset', 'utf8mb4'),
'prefix' => env('database.prefix', ''),
// 读写分离配置
'deploy' => [
'read' => [
'host' => [
'192.168.1.101', // 从库1
'192.168.1.102', // 从库2
],
],
'write' => [
'host' => [
'192.168.1.100', // 主库
],
],
],
'fields_cache' => false, // 集群环境关闭字段缓存
'trigger_sql' => true, // 开启SQL监听
],
],
];
4. 负载均衡配置
4.1 Nginx 负载均衡器配置
nginx
# /etc/nginx/conf.d/load-balancer.conf
upstream thinkphp_cluster {
# 负载均衡策略
least_conn; # 最少连接数策略
# 后端服务器列表
server 192.168.1.10:9000 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.1.11:9000 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.1.12:9000 weight=1 max_fails=3 fail_timeout=30s;
# 健康检查(需要 nginx_plus 或 tengine)
# check interval=3000 rise=2 fall=3 timeout=1000;
# 保持会话(可选,建议使用 Redis Session)
# ip_hash;
}
server {
listen 80;
server_name your-domain.com;
# 强制 HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL 配置
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 静态资源缓存
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_pass http://thinkphp_cluster;
proxy_cache static_cache;
proxy_cache_valid 200 30d;
proxy_cache_key $uri;
expires 30d;
add_header Cache-Control "public, immutable";
}
# PHP 请求转发
location / {
proxy_pass http://thinkphp_cluster;
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 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 文件上传大小限制
client_max_body_size 50m;
}
# 健康检查端点
location /health {
access_log off;
return 200 "OK";
add_header Content-Type text/plain;
}
}
4.2 Keepalived 高可用配置
主节点配置 /etc/keepalived/keepalived.conf
conf
global_defs {
router_id LVS_DEVEL_01
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -20
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.200/24 # VIP 虚拟IP
}
track_script {
check_nginx
}
}
健康检查脚本 /etc/keepalived/check_nginx.sh
bash
#!/bin/bash
if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then
systemctl start nginx
sleep 2
if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then
exit 1
fi
fi
exit 0
5. Session 共享方案
5.1 Redis Session 配置
方式一:ThinkPHP 原生配置
php
// config/session.php
<?php
return [
'type' => 'redis',
'host' => env('redis.host', '127.0.0.1'),
'port' => env('redis.port', 6379),
'password' => env('redis.password', ''),
'select' => env('redis.select', 0),
'expire' => 3600,
'prefix' => 'sess_',
'timeout' => 3,
'persistent' => true,
];
方式二:PHP phpredis 扩展配置
ini
; /etc/php.d/redis.ini 或 php.ini
session.save_handler = redis
session.save_path = "tcp://192.168.1.102:6379?auth=your_password&database=0"
session.gc_maxlifetime = 3600
方式三:Redis 集群配置
php
// config/session.php
<?php
return [
'type' => 'redis',
'host' => [
'tcp://192.168.1.102:6379',
'tcp://192.168.1.103:6379',
'tcp://192.168.1.104:6379',
],
'password' => env('redis.password', ''),
'select' => 0,
'timeout' => 3,
'persistent' => true,
];
5.2 Session 注意事项
php
// 避免在 Session 中存储大量数据
// 错误示例
session('user_info', $largeUserData);
// 正确示例:只存储必要信息
session('user_id', $user->id);
session('user_token', $user->token);
// 使用 Redis 缓存存储详细数据
Cache::set('user_detail_' . $userId, $userData, 3600);
6. 文件存储方案
6.1 NFS 共享存储方案
服务端配置
bash
# 安装 NFS 服务
yum install -y nfs-utils rpcbind
# 创建共享目录
mkdir -p /data/thinkphp/uploads
chmod 755 /data/thinkphp/uploads
# 配置共享
# /etc/exports
/data/thinkphp/uploads 192.168.1.0/24(rw,sync,no_root_squash,no_subtree_check)
# 启动服务
systemctl start rpcbind
systemctl start nfs-server
systemctl enable nfs-server
# 重新加载配置
exportfs -rav
客户端挂载
bash
# 安装 NFS 客户端
yum install -y nfs-utils
# 创建挂载点
mkdir -p /var/www/thinkphp/public/uploads
# 挂载
mount -t nfs 192.168.1.200:/data/thinkphp/uploads /var/www/thinkphp/public/uploads
# 开机自动挂载 (编辑 /etc/fstab)
192.168.1.200:/data/thinkphp/uploads /var/www/thinkphp/public/uploads nfs defaults 0 0
6.2 对象存储方案(推荐)
阿里云 OSS 配置
php
// 安装 SDK
// composer require aliyuncs/oss-sdk-php
// config/filesystem.php
<?php
return [
'default' => 'oss',
'disks' => [
'oss' => [
'type' => 'oss',
'access_id' => env('oss.access_id', ''),
'access_key' => env('oss.access_key', ''),
'bucket' => env('oss.bucket', ''),
'endpoint' => env('oss.endpoint', 'oss-cn-hangzhou.aliyuncs.com'),
'prefix' => env('oss.prefix', ''),
],
'local' => [
'type' => 'local',
'root' => app()->getRootPath() . 'public/uploads',
],
],
];
文件上传示例
php
<?php
namespace app\controller;
use think\facade\Filesystem;
class Upload
{
public function upload()
{
$file = request()->file('image');
// 上传到 OSS
$path = Filesystem::disk('oss')->putFile('uploads', $file);
// 返回完整 URL
$url = 'https://' . env('oss.bucket') . '.' . env('oss.endpoint') . '/' . $path;
return json(['url' => $url]);
}
}
6.3 本地文件同步方案(不推荐)
bash
# 使用 rsync + inotify 实时同步
# 仅作为临时方案,不建议生产环境使用
# 主节点安装 inotify-tools
yum install -y inotify-tools
# 同步脚本
#!/bin/bash
inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' \
-e modify,delete,create,attrib /var/www/thinkphp/public/uploads/ \
| while read file; do
rsync -avz --delete /var/www/thinkphp/public/uploads/ \
node2:/var/www/thinkphp/public/uploads/
done
7. 缓存方案
7.1 Redis 缓存配置
php
// config/cache.php
<?php
return [
'default' => 'redis',
'stores' => [
'redis' => [
'type' => 'redis',
'host' => env('redis.host', '127.0.0.1'),
'port' => env('redis.port', 6379),
'password' => env('redis.password', ''),
'select' => env('redis.select', 0),
'timeout' => 3,
'persistent' => true,
'prefix' => 'cache_',
'serialize' => true,
],
// 多缓存实例
'session' => [
'type' => 'redis',
'host' => env('redis.host'),
'select' => 1, // 使用不同数据库
],
'data' => [
'type' => 'redis',
'host' => env('redis.host'),
'select' => 2,
],
],
];
7.2 缓存使用最佳实践
php
<?php
namespace app\service;
use think\facade\Cache;
class UserService
{
// 使用缓存标签,便于批量清除
public function getUserInfo($id)
{
$cacheKey = 'user_info_' . $id;
return Cache::tag('user')->remember($cacheKey, 3600, function() use ($id) {
return \app\model\User::find($id)->toArray();
});
}
// 更新时清除相关缓存
public function updateUser($id, $data)
{
$result = \app\model\User::update($data, ['id' => $id]);
// 清除该用户的所有缓存
Cache::tag('user')->clear();
return $result;
}
// 使用分布式锁防止缓存击穿
public function getHotData($key)
{
$data = Cache::get($key);
if ($data === null) {
// 获取分布式锁
$lockKey = 'lock_' . $key;
if (Cache::store('redis')->handler()->setnx($lockKey, 1)) {
Cache::store('redis')->handler()->expire($lockKey, 5);
// 从数据库获取数据
$data = $this->getDataFromDb();
Cache::set($key, $data, 3600);
// 释放锁
Cache::delete($lockKey);
} else {
// 等待其他节点完成缓存
usleep(100000);
return $this->getHotData($key);
}
}
return $data;
}
}
8. 数据库优化
8.1 读写分离配置
php
// config/database.php 已在上文配置
// ThinkPHP 会自动将 SELECT 语句路由到从库
// INSERT/UPDATE/DELETE 路由到主库
// 强制使用主库
Db::name('user')->master()->find();
// 强制使用从库(适用于实时性要求不高的场景)
Db::name('user')->readMaster(false)->select();
8.2 数据库连接池配置
php
// config/database.php
<?php
return [
'connections' => [
'mysql' => [
// ... 其他配置
// 连接池配置
'pool' => [
'max_active' => 20, // 最大活跃连接数
'max_idle' => 10, // 最大空闲连接数
'idle_time' => 60, // 空闲连接存活时间(秒)
'wait_time' => 5, // 获取连接等待时间(秒)
],
],
],
];
8.3 MySQL 主从复制配置
主库配置 /etc/my.cnf
ini
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
binlog-do-db = thinkphp
expire_logs_days = 7
max_binlog_size = 100M
从库配置
ini
[mysqld]
server-id = 2
relay-log = relay-bin
read_only = 1
配置复制
sql
-- 在主库创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
-- 在从库配置复制
CHANGE MASTER TO
MASTER_HOST = '192.168.1.100',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'repl_password',
MASTER_LOG_FILE = 'mysql-bin.000001',
MASTER_LOG_POS = 0;
START SLAVE;
SHOW SLAVE STATUS\G
9. 代码部署策略
9.1 部署架构
┌─────────────────────────────────────────────────────────┐
│ 部署服务器 │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Git Repository → Build → Sync Script │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Node 1 │ │ Node 2 │ │ Node N │
└─────────┘ └─────────┘ └─────────┘
9.2 自动化部署脚本
bash
#!/bin/bash
# deploy.sh - 一键部署脚本
# 配置变量
APP_NAME="thinkphp"
DEPLOY_USER="www"
DEPLOY_DIR="/var/www/${APP_NAME}"
GIT_REPO="git@github.com:your-repo/thinkphp.git"
NODES=("192.168.1.10" "192.168.1.11" "192.168.1.12")
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 主节点构建
build() {
log_info "开始构建应用..."
cd ${DEPLOY_DIR}
# 拉取最新代码
git pull origin master
# 安装依赖
composer install --no-dev --optimize-autoloader
# 清除缓存
php think clear
# 生成路由缓存
php think route:list
# 数据库迁移(如有)
# php think migrate:run
log_info "构建完成!"
}
# 同步到各节点
sync_nodes() {
log_info "开始同步到各节点..."
for node in "${NODES[@]}"; do
log_info "同步到节点: ${node}"
# 同步代码
rsync -avz --delete \
--exclude='.git' \
--exclude='.env' \
--exclude='runtime/*' \
--exclude='public/uploads/*' \
${DEPLOY_DIR}/ ${DEPLOY_USER}@${node}:${DEPLOY_DIR}/
# 清除节点缓存
ssh ${DEPLOY_USER}@${node} "cd ${DEPLOY_DIR} && php think clear"
# 重启 PHP-FPM(平滑重启)
ssh ${DEPLOY_USER}@${node} "sudo systemctl reload php-fpm"
log_info "节点 ${node} 同步完成!"
done
}
# 健康检查
health_check() {
log_info "执行健康检查..."
for node in "${NODES[@]}"; do
response=$(curl -s -o /dev/null -w "%{http_code}" http://${node}/health)
if [ "$response" == "200" ]; then
log_info "节点 ${node} 健康检查通过!"
else
log_error "节点 ${node} 健康检查失败! HTTP ${response}"
fi
done
}
# 回滚
rollback() {
log_info "执行回滚..."
cd ${DEPLOY_DIR}
git reset --hard HEAD~1
sync_nodes
}
# 主流程
main() {
case "$1" in
build)
build
;;
sync)
sync_nodes
;;
deploy)
build
sync_nodes
health_check
;;
rollback)
rollback
;;
*)
echo "Usage: $0 {build|sync|deploy|rollback}"
exit 1
;;
esac
}
main "$@"
9.3 使用说明
bash
# 完整部署
./deploy.sh deploy
# 仅构建
./deploy.sh build
# 仅同步
./deploy.sh sync
# 回滚
./deploy.sh rollback
9.4 零停机部署(蓝绿部署)
bash
#!/bin/bash
# blue-green-deploy.sh
NODES=("192.168.1.10" "192.168.1.11" "192.168.1.12")
LB_NODE="192.168.1.200"
# 按节点依次更新
for node in "${NODES[@]}"; do
echo "更新节点: ${node}"
# 1. 从负载均衡中移除
ssh ${LB_NODE} "echo 'server ${node}:9000 down;' > /etc/nginx/conf.d/node-${node}.conf"
ssh ${LB_NODE} "nginx -s reload"
# 2. 等待现有请求完成
sleep 5
# 3. 更新代码
rsync -avz --delete ${DEPLOY_DIR}/ www@${node}:${DEPLOY_DIR}/
ssh www@${node} "cd ${DEPLOY_DIR} && composer install --no-dev"
ssh www@${node} "sudo systemctl reload php-fpm"
# 4. 健康检查
sleep 3
if curl -f http://${node}/health; then
# 5. 恢复到负载均衡
ssh ${LB_NODE} "rm /etc/nginx/conf.d/node-${node}.conf"
ssh ${LB_NODE} "nginx -s reload"
echo "节点 ${node} 更新完成!"
else
echo "节点 ${node} 更新失败!"
exit 1
fi
done
10. 常见问题与解决方案
10.1 Session 丢失
问题表现:用户登录后刷新页面退出登录
原因分析:
- Session 未配置 Redis 共享
- Session ID 未正确传递
解决方案:
php
// 检查 Session 配置
php think session:status
// 确保 Cookie 同步配置
// config/cookie.php
return [
'domain' => '.your-domain.com', // 支持子域名
'secure' => true, // HTTPS
'httponly' => true,
'samesite' => 'none', // 跨域支持
];
10.2 文件上传后无法访问
问题表现:节点 A 上传的文件,节点 B 无法访问
解决方案:
php
// 方案1:使用对象存储(推荐)
// 见第6章
// 方案2:使用 NFS 共享存储
// 见第6章
// 方案3:上传后同步到其他节点(不推荐)
public function upload()
{
$file = request()->file('image');
$path = $file->move('uploads');
// 同步到其他节点
$nodes = ['192.168.1.11', '192.168.1.12'];
foreach ($nodes as $node) {
exec("rsync -avz uploads/ www@${node}:/var/www/thinkphp/public/uploads/");
}
return json(['path' => $path]);
}
10.3 缓存不一致
问题表现:数据更新后缓存未清除
解决方案:
php
// 使用缓存标签统一管理
Cache::tag(['user', 'user_list'])->remember($key, $ttl, $callback);
// 更新时清除标签下所有缓存
Cache::tag('user')->clear();
// 或者使用事件监听自动清除缓存
// app/event.php
return [
'listen' => [
'UserUpdated' => ['app\listener\UserCacheClear'],
],
];
// app/listener/UserCacheClear.php
<?php
namespace app\listener;
use think\facade\Cache;
class UserCacheClear
{
public function handle($event)
{
Cache::tag('user')->clear();
}
}
10.4 数据库主从延迟
问题表现:写入后立即读取数据不存在
解决方案:
php
// 方案1:写入后强制读主库
Db::name('user')->insert($data);
$user = Db::name('user')->master()->where('id', $id)->find();
// 方案2:配置主从延迟检测
// config/database.php
'deploy' => [
'read' => ['192.168.1.101', '192.168.1.102'],
'write' => ['192.168.1.100'],
'sticky' => true, // 同一请求内写入后读主库
],
// 方案3:关键业务直接读主库
public function getOrderDetail($id)
{
// 订单详情实时性要求高,直接读主库
return Db::name('order')->master()->find($id);
}
10.5 日志分散难以排查
解决方案:使用 ELK 集中收集日志
yaml
# filebeat.yml - 各节点部署
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/www/thinkphp/runtime/log/*.log
fields:
app: thinkphp
node: node1
output.logstash:
hosts: ["192.168.1.200:5044"]
yaml
# logstash.conf
input {
beats {
port => 5044
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:content}" }
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "thinkphp-%{+YYYY.MM.dd}"
}
}
10.6 端口耗尽
问题表现:高并发下出现大量 TIME_WAIT
解决方案:
bash
# 内核参数优化 /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# 应用后生效
sysctl -p
php
// PHP-FPM 配置优化 /etc/php-fpm.d/www.conf
pm = dynamic
pm.max_children = 100
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 1000
附录
A. 端口规划
| 服务 | 端口 | 说明 |
|---|---|---|
| Nginx | 80, 443 | HTTP/HTTPS |
| PHP-FPM | 9000 | FastCGI |
| MySQL | 3306 | 数据库 |
| Redis | 6379 | 缓存/Session |
| NFS | 2049 | 文件共享 |
| Keepalived | 112 | VRRP |
B. 监控指标
| 指标 | 阈值 | 告警方式 |
|---|---|---|
| CPU 使用率 | > 80% | 邮件/短信 |
| 内存使用率 | > 85% | 邮件/短信 |
| 磁盘使用率 | > 90% | 邮件/短信 |
| PHP-FPM 队列 | > 50 | 邮件 |
| MySQL 慢查询 | > 1s | 邮件 |
| Redis 连接数 | > 1000 | 邮件 |
C. 故障排查清单
bash
# 1. 检查服务状态
systemctl status nginx
systemctl status php-fpm
systemctl status mysql
systemctl status redis
# 2. 检查端口监听
netstat -tlnp | grep -E '80|9000|3306|6379'
# 3. 检查日志
tail -f /var/log/nginx/error.log
tail -f /var/www/thinkphp/runtime/log/error.log
tail -f /var/log/php-fpm/error.log
# 4. 检查 PHP-FPM 状态
curl http://localhost/status
# 5. 检查 Redis 连接
redis-cli -h 192.168.1.102 ping
# 6. 检查 MySQL 主从状态
mysql -e "SHOW SLAVE STATUS\G"
总结
ThinkPHP 集群部署的核心要点:
- Session 集中存储 - 使用 Redis 实现多节点共享
- 文件集中存储 - 使用 OSS 或 NFS 避免文件不一致
- 缓存统一管理 - Redis 集群确保缓存一致性
- 数据库读写分离 - 提升数据库性能和可用性
- 负载均衡高可用 - Keepalived 实现故障自动切换
- 自动化部署 - 脚本化部署降低运维成本
- 监控告警 - 及时发现和处理问题
通过以上配置,可以实现一个高可用、高性能、易扩展的 ThinkPHP 集群环境。