gongxiangp2/docs/frp-stability-analysis.md
chenpei 0ce59be34e 备份:组织架构设计方案讨论前的代码快照
- 包含所有当前修改和新功能
- 准备开始组织架构优化实施方案
2025-12-30 13:20:26 +08:00

10 KiB
Raw Blame History

FRP 稳定性问题分析报告

检查时间: 2025-12-29
问题: FRP穿透服务在短短几天内崩溃3次
FRP版本: 0.52.3


🔴 发现的问题

1. Systemd 重启策略不够积极 ⚠️

当前配置:

Restart=on-failure
RestartSec=5s

问题:

  • on-failure 只在进程异常退出时重启
  • 如果FRP工作连接失败但进程未退出,systemd不会重启
  • 工作连接超时不会触发进程退出,导致服务"假死"

影响: 服务看起来在运行,但实际无法建立工作连接


2. 连接池配置可能不足 ⚠️

当前配置:

transport.poolCount = 5
transport.heartbeatInterval = 30
transport.heartbeatTimeout = 90

问题:

  • poolCount = 5 可能在高并发时不够
  • 工作连接池耗尽后,新请求会超时
  • 没有自动清理失效连接的机制

影响: 高负载时工作连接池耗尽,导致502错误


3. 文件描述符限制过低 🔴

当前限制: ulimit -n = 1024

问题:

  • 网络服务需要大量文件描述符(每个连接一个)
  • 1024的限制可能导致连接数达到上限后无法建立新连接
  • FRP需要维护多个连接(控制连接 + 工作连接池)

影响: 连接数达到上限后,新连接无法建立


4. CPU消耗异常高 ⚠️

观察数据:

  • 运行约5小时43分钟,消耗CPU时间17分30秒
  • 运行更长时间后,消耗CPU时间40分27秒
  • CPU使用率14.4%(仅运行2分43秒)

问题:

  • CPU消耗过高,可能是连接重试循环或资源泄漏
  • 高CPU使用可能导致响应变慢,触发超时

影响: 性能下降,可能导致连接超时


5. 缺少监控和自动恢复机制 ⚠️

当前状态:

  • 没有健康检查机制
  • 没有自动检测工作连接失败的机制
  • 依赖手动重启

影响: 问题发现不及时,需要人工干预


📊 崩溃时间线

根据日志分析:

  1. 第一次崩溃: 约在 12月29日 10:01:33 之前

    • 运行时间: 未知(可能是几天)
    • CPU消耗: 40分27秒
    • 手动重启
  2. 第二次崩溃: 12月29日 15:45:33

    • 运行时间: 约5小时43分钟
    • CPU消耗: 17分30秒
    • 手动重启
  3. 第三次崩溃: 今天(用户报告)

    • 运行时间: 约2小时
    • CPU消耗: 23.649秒(仅2分43秒运行时间)

模式: 崩溃间隔越来越短,说明问题在恶化


🛠️ 解决方案

方案 1: 优化 Systemd 服务配置(立即执行)

修改 /etc/systemd/system/frpc.service:

[Unit]
Description=Frp Client Service
After=network.target

[Service]
Type=simple
# 改为 always,即使正常退出也重启(防止假死)
Restart=always
RestartSec=10s
# 增加启动超时
TimeoutStartSec=30s
# 增加文件描述符限制
LimitNOFILE=4096
# 内存限制(防止内存泄漏)
MemoryLimit=512M
# CPU限制(防止CPU占用过高)
CPUQuota=50%

ExecStart=/root/gongxiangp2/frp_0.52.3_linux_amd64/frpc -c /etc/frp/frpc.toml
StandardOutput=append:/root/frp/frpc.log
StandardError=append:/root/frp/frpc.log

[Install]
WantedBy=multi-user.target

关键改进:

  • Restart=always: 即使正常退出也重启,防止假死
  • LimitNOFILE=4096: 增加文件描述符限制
  • MemoryLimit=512M: 防止内存泄漏
  • CPUQuota=50%: 限制CPU使用,防止占用过高

方案 2: 优化 FRP 客户端配置

修改 /etc/frp/frpc.toml:

serverAddr = "180.97.221.140"
serverPort = 7000

auth.method = "token"
auth.token = "LiuYunKu_NAS_2024_SecureToken"

log.to = "/root/frp/frpc.log"
log.level = "info"
log.maxDays = 7

# 优化传输配置
transport.heartbeatInterval = 30
transport.heartbeatTimeout = 90
transport.tcpMux = true
# 增加连接池大小(从5增加到10)
transport.poolCount = 10
# 启用连接复用
transport.tcpKeepAlive = true

[[proxies]]
name = "nas_smb"
type = "tcp"
localIP = "192.168.58.20"
localPort = 445
remotePort = 445
transport.useCompression = true

[[proxies]]
name = "nas_netbios"
type = "tcp"
localIP = "192.168.58.20"
localPort = 139
remotePort = 139
transport.useCompression = true

[[proxies]]
name = "youyidian-3d"
type = "tcp"
localIP = "127.0.0.1"
localPort = 4320
remotePort = 2320
transport.useCompression = true
# 增加健康检查
healthCheck.type = "tcp"
healthCheck.intervalSeconds = 10
healthCheck.maxFailed = 3
healthCheck.timeoutSeconds = 3

关键改进:

  • poolCount = 10: 增加连接池大小
  • tcpKeepAlive = true: 启用TCP保活
  • 添加健康检查配置(如果FRP版本支持)

方案 3: 添加健康检查和自动恢复脚本

创建健康检查脚本 /root/frp/check-frpc-health.sh:

#!/bin/bash

# FRP健康检查脚本
# 检查工作连接是否正常

FRPC_LOG="/root/frp/frpc.log"
FRPC_SERVICE="frpc.service"
CHECK_INTERVAL=60  # 每60秒检查一次
MAX_FAILURES=3     # 连续失败3次后重启

failure_count=0

while true; do
    # 检查frpc进程是否运行
    if ! systemctl is-active --quiet $FRPC_SERVICE; then
        echo "$(date): FRPC服务未运行,重启中..."
        systemctl restart $FRPC_SERVICE
        failure_count=0
        sleep 10
        continue
    fi
    
    # 检查是否有工作连接超时错误(最近5分钟)
    recent_errors=$(tail -100 "$FRPC_LOG" | grep -c "timeout trying to get work connection" || true)
    
    if [ "$recent_errors" -gt 5 ]; then
        failure_count=$((failure_count + 1))
        echo "$(date): 检测到工作连接超时错误 ($recent_errors次),失败计数: $failure_count"
        
        if [ "$failure_count" -ge "$MAX_FAILURES" ]; then
            echo "$(date): 连续失败达到上限,重启FRPC服务..."
            systemctl restart $FRPC_SERVICE
            failure_count=0
        fi
    else
        failure_count=0
    fi
    
    sleep $CHECK_INTERVAL
done

创建systemd定时器 /etc/systemd/system/frpc-health-check.service:

[Unit]
Description=FRPC Health Check Service
After=network.target

[Service]
Type=simple
ExecStart=/root/frp/check-frpc-health.sh
Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target

方案 4: 检查并优化系统资源

增加系统文件描述符限制:

# 编辑 /etc/security/limits.conf
echo "* soft nofile 4096" >> /etc/security/limits.conf
echo "* hard nofile 8192" >> /etc/security/limits.conf

# 编辑 /etc/systemd/system.conf
# 取消注释并修改:
# DefaultLimitNOFILE=4096:8192

🎯 立即执行的操作

步骤 1: 优化 Systemd 配置

ssh root@192.168.58.20

# 备份当前配置
cp /etc/systemd/system/frpc.service /etc/systemd/system/frpc.service.bak

# 创建新配置(使用上面的优化配置)
# ... (编辑文件)

# 重新加载systemd配置
systemctl daemon-reload

# 重启服务
systemctl restart frpc

# 检查状态
systemctl status frpc

步骤 2: 优化 FRP 配置

# 备份当前配置
cp /etc/frp/frpc.toml /etc/frp/frpc.toml.bak

# 修改配置(增加poolCount等)
# ... (编辑文件)

# 重启服务
systemctl restart frpc

步骤 3: 增加文件描述符限制

# 临时增加(立即生效)
ulimit -n 4096

# 永久增加(需要编辑配置文件)
# ... (编辑 /etc/security/limits.conf)

📈 预期效果

  1. 稳定性提升: Restart=always 确保服务始终运行
  2. 性能提升: 增加连接池和文件描述符限制,支持更多并发
  3. 自动恢复: 健康检查脚本自动检测并恢复问题
  4. 资源控制: CPU和内存限制防止资源耗尽

🔍 后续监控

建议监控以下指标:

  1. 服务运行时间: systemctl status frpc | grep Active
  2. CPU使用率: top -p $(pgrep frpc)
  3. 内存使用: ps aux | grep frpc
  4. 连接数: netstat -an | grep 180.97.221.140:7000 | wc -l
  5. 错误日志: tail -f /root/frp/frpc.log | grep -E 'error|fail|timeout'

📝 总结

根本原因:

  1. Systemd重启策略不够积极(on-failure vs always)
  2. 连接池配置不足(poolCount=5)
  3. 文件描述符限制过低(1024)
  4. 缺少自动恢复机制

解决方案优先级:

  1. 🔴 高优先级: 优化Systemd配置(Restart=always + 资源限制)
  2. 🟡 中优先级: 优化FRP配置(增加连接池)
  3. 🟢 低优先级: 添加健康检查脚本(可选,但推荐)

预计修复后稳定性: 从几天崩溃一次 → 稳定运行数周/数月


✅ 优化已应用(2025-12-29 15:50)

已执行的优化

  1. ✅ Systemd 服务配置优化

    • Restart=always: 已应用(防止假死)
    • LimitNOFILE=4096: 已应用(增加文件描述符限制)
    • MemoryMax=512M: 已应用(防止内存泄漏)
    • CPUQuota=50%: 已应用(限制CPU使用)
  2. ✅ FRP 客户端配置优化

    • transport.poolCount = 10: 已应用(从5增加到10)
  3. ✅ 服务状态验证

    • FRP服务: ✅ 正常运行
    • FRP连接: ✅ 已建立(192.168.58.20:40602 → 180.97.221.140:7000)
    • 本地应用: ✅ HTTP 200 正常
    • 公网访问: ✅ 正常

当前配置摘要

Systemd配置 (/etc/systemd/system/frpc.service):

Restart=always          # 总是重启(防止假死)
RestartSec=10s          # 重启间隔10秒
LimitNOFILE=4096        # 文件描述符限制4096
MemoryMax=512M          # 内存限制512MB
CPUQuota=50%            # CPU限制50%

FRP配置 (/etc/frp/frpc.toml):

transport.poolCount = 10  # 连接池大小10(原为5)

监控建议

建议定期检查以下指标:

# 1. 服务运行时间
systemctl status frpc | grep Active

# 2. 资源使用情况
systemctl status frpc | grep -E 'Memory|CPU'

# 3. 连接状态
netstat -an | grep 180.97.221.140:7000 | grep ESTABLISHED

# 4. 错误日志
tail -50 /root/frp/frpc.log | grep -E 'error|fail|timeout'

预期改进

  • 稳定性: 从几天崩溃一次 → 稳定运行数周/数月
  • 性能: 连接池增加2倍,支持更高并发
  • 自动恢复: Restart=always 确保服务始终运行
  • 资源控制: CPU和内存限制防止资源耗尽