ThinkPHP 集群部署完整指南

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 集群部署的核心要点:

  1. Session 集中存储 - 使用 Redis 实现多节点共享
  2. 文件集中存储 - 使用 OSS 或 NFS 避免文件不一致
  3. 缓存统一管理 - Redis 集群确保缓存一致性
  4. 数据库读写分离 - 提升数据库性能和可用性
  5. 负载均衡高可用 - Keepalived 实现故障自动切换
  6. 自动化部署 - 脚本化部署降低运维成本
  7. 监控告警 - 及时发现和处理问题

通过以上配置,可以实现一个高可用、高性能、易扩展的 ThinkPHP 集群环境。

相关推荐
流觞 无依2 小时前
DedeCMS plus/recommend.php SQL注入漏洞修复教程
sql·php
刘~浪地球2 小时前
数据库与缓存--MySQL 高可用架构设计
数据库·mysql·缓存
知识分享小能手2 小时前
MongoDB入门学习教程,从入门到精通,MongoDB的了解应用程序的动态(18)
数据库·学习·mongodb
oradh2 小时前
Oracle数据类型概述(一)
数据库·oracle·oracle基础·oracle入门基础·oracle数据类型
小兜全糖(xdqt)3 小时前
Ubuntu22.04安装最新版本redis
数据库·redis·缓存
风曦Kisaki3 小时前
Linux服务Day03:自定义YUM仓库、网络YUM仓库(HTTP/FTP)、MariaDB数据库基础操作
linux·网络·数据库
流觞 无依3 小时前
DedeCMS plus/list.php 参数注入(SQL注入)修复教程
sql·安全·php
weixin_704266053 小时前
redis 的集群
java·数据库·redis
软件开发技术3 小时前
最新网络游戏账户交易平台系统源码 全开源版本 全新UI 自适应移动端
php