优化稳定性部署
This commit is contained in:
10
app.log
Normal file
10
app.log
Normal file
@@ -0,0 +1,10 @@
|
||||
▲ Next.js 14.0.4
|
||||
- Local: http://localhost:3000
|
||||
- Network: http://0.0.0.0:3000
|
||||
|
||||
✓ Ready in 7.2s
|
||||
○ Compiling / ...
|
||||
✓ Compiled / in 7.5s (560 modules)
|
||||
⚠ Unsupported metadata viewport is configured in metadata export in /. Please move it to viewport export instead.
|
||||
Read more: https://nextjs.org/docs/app/api-reference/functions/generate-viewport
|
||||
✓ Compiled in 1104ms (286 modules)
|
||||
28
ecosystem.config.js
Normal file
28
ecosystem.config.js
Normal file
@@ -0,0 +1,28 @@
|
||||
module.exports = {
|
||||
apps: [{
|
||||
name: 'promptforge',
|
||||
script: 'npx',
|
||||
args: 'next@14.0.4 dev -H 0.0.0.0 -p 3000',
|
||||
cwd: '/home/renjianbo/aiapply',
|
||||
instances: 1,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
max_memory_restart: '1G',
|
||||
env: {
|
||||
NODE_ENV: 'development',
|
||||
PORT: 3000
|
||||
},
|
||||
error_file: '/home/renjianbo/aiapply/logs/err.log',
|
||||
out_file: '/home/renjianbo/aiapply/logs/out.log',
|
||||
log_file: '/home/renjianbo/aiapply/logs/combined.log',
|
||||
time: true,
|
||||
// 进程管理配置
|
||||
min_uptime: '10s',
|
||||
max_restarts: 10,
|
||||
restart_delay: 4000,
|
||||
// 健康检查
|
||||
health_check_grace_period: 3000,
|
||||
// 环境变量
|
||||
env_file: '.env.local'
|
||||
}]
|
||||
}
|
||||
1
logs/combined-0.log
Normal file
1
logs/combined-0.log
Normal file
File diff suppressed because one or more lines are too long
1
logs/err-0.log
Normal file
1
logs/err-0.log
Normal file
@@ -0,0 +1 @@
|
||||
2025-09-11T09:40:28: 2025-09-11T09:40:39: 2025-09-11T09:43:29: 2025-09-11T09:43:37: 2025-09-11T09:43:44: 2025-09-11T09:43:52: 2025-09-11T09:43:59: 2025-09-11T09:44:08: 2025-09-11T09:44:16: 2025-09-11T09:44:22: 2025-09-11T09:44:29: 2025-09-11T09:44:35: 2025-09-11T09:44:41: 2025-09-11T09:44:47: 2025-09-11T09:44:54: 2025-09-11T09:45:00: 2025-09-11T09:45:07: 2025-09-11T09:45:15: 2025-09-11T09:45:22: 2025-09-11T09:45:29: 2025-09-11T09:45:35: 2025-09-11T09:45:41: 2025-09-11T09:45:48: 2025-09-11T09:45:54: 2025-09-11T09:46:00: 2025-09-11T09:46:06: 2025-09-11T09:46:12: 2025-09-11T09:46:19: 2025-09-11T09:46:25: 2025-09-11T09:46:31: 2025-09-11T09:46:38: 2025-09-11T09:46:44: 2025-09-11T09:46:50: 2025-09-11T09:46:56: 2025-09-11T09:47:03: 2025-09-11T09:47:09: 2025-09-11T09:47:15: 2025-09-11T09:47:22: 2025-09-11T09:47:28: 2025-09-11T09:47:34: 2025-09-11T09:47:40: 2025-09-11T09:47:47: 2025-09-11T09:47:53: 2025-09-11T09:47:59: 2025-09-11T09:48:05: 2025-09-11T09:48:12: 2025-09-11T09:48:18: 2025-09-11T09:48:24: 2025-09-11T09:48:30: 2025-09-11T09:48:37: 2025-09-11T09:48:43: 2025-09-11T09:48:49: 2025-09-11T09:48:55: 2025-09-11T09:49:02: 2025-09-11T09:49:08: 2025-09-11T09:49:14: 2025-09-11T09:49:21: 2025-09-11T09:49:27: 2025-09-11T09:49:33: 2025-09-11T09:49:39: 2025-09-11T09:49:46: 2025-09-11T09:49:52: 2025-09-11T09:49:58: 2025-09-11T09:50:06: 2025-09-11T09:50:13: 2025-09-11T09:50:20: 2025-09-11T09:50:26: 2025-09-11T09:50:33: 2025-09-11T09:50:39: 2025-09-11T09:50:45: 2025-09-11T09:50:51: 2025-09-11T09:50:58: 2025-09-11T09:51:04: 2025-09-11T09:51:10: 2025-09-11T09:51:16: 2025-09-11T09:51:23: 2025-09-11T09:51:29: 2025-09-11T09:51:35: 2025-09-11T09:51:41: 2025-09-11T09:51:48: 2025-09-11T09:51:54: 2025-09-11T09:52:00: 2025-09-11T09:52:07: 2025-09-11T09:52:13: 2025-09-11T09:52:19: 2025-09-11T09:52:25: 2025-09-11T09:52:31: 2025-09-11T09:52:38: 2025-09-11T09:52:44: 2025-09-11T09:52:50: 2025-09-11T09:52:57: 2025-09-11T09:53:03: 2025-09-11T09:53:09: 2025-09-11T09:53:16: 2025-09-11T09:53:22: 2025-09-11T09:53:28: 2025-09-11T09:53:34: 2025-09-11T09:53:41: 2025-09-11T09:53:47: 2025-09-11T09:53:53: 2025-09-11T09:53:59: 2025-09-11T09:54:06: 2025-09-11T09:54:12: 2025-09-11T09:54:18: 2025-09-11T09:54:24: 2025-09-11T09:54:31: 2025-09-11T09:54:37: 2025-09-11T09:54:43: 2025-09-11T09:54:49: 2025-09-11T09:54:56: 2025-09-11T09:55:03: 2025-09-11T09:55:10: 2025-09-11T09:55:17: 2025-09-11T09:55:23: 2025-09-11T09:55:30: 2025-09-11T09:55:36: 2025-09-11T09:55:42: 2025-09-11T09:55:48: 2025-09-11T09:55:55: 2025-09-11T09:56:01: 2025-09-11T09:56:07: 2025-09-11T09:56:14: 2025-09-11T09:56:21: 2025-09-11T09:56:27: 2025-09-11T09:56:34:
|
||||
9
logs/monitor.log
Normal file
9
logs/monitor.log
Normal file
@@ -0,0 +1,9 @@
|
||||
[2025-09-14 09:45:09] ✅ 服务运行正常
|
||||
[2025-09-14 09:45:09] ⚠️ PM2 服务状态异常:
|
||||
[2025-09-14 09:45:09] 📊 系统负载: 0.23, 内存使用: 36.8%, 磁盘使用: 28%
|
||||
[2025-09-14 09:45:30] ✅ 服务运行正常
|
||||
[2025-09-14 09:45:30] ⚠️ PM2 服务状态异常: [34m[1mcluster[22m[39m
|
||||
[2025-09-14 09:45:30] 📊 系统负载: 0.56, 内存使用: 36.9%, 磁盘使用: 28%
|
||||
[2025-09-14 09:50:01] ✅ 服务运行正常
|
||||
[2025-09-14 09:50:01] ⚠️ PM2 服务状态异常:
|
||||
[2025-09-14 09:50:01] 📊 系统负载: 0.07, 内存使用: 40.6%, 磁盘使用: 28%
|
||||
1
logs/out-0.log
Normal file
1
logs/out-0.log
Normal file
@@ -0,0 +1 @@
|
||||
2025-09-11T09:40:28: 2025-09-11T09:40:39: 2025-09-11T09:43:29: 2025-09-11T09:43:37: 2025-09-11T09:43:44: 2025-09-11T09:43:52: 2025-09-11T09:43:59: 2025-09-11T09:43:59: 2025-09-11T09:44:08: 2025-09-11T09:44:08: 2025-09-11T09:44:16: 2025-09-11T09:44:22: 2025-09-11T09:44:29: 2025-09-11T09:44:35: 2025-09-11T09:44:41: 2025-09-11T09:44:47: 2025-09-11T09:44:54: 2025-09-11T09:45:00: 2025-09-11T09:45:07: 2025-09-11T09:45:15: 2025-09-11T09:45:22: 2025-09-11T09:45:29: 2025-09-11T09:45:35: 2025-09-11T09:45:41: 2025-09-11T09:45:48: 2025-09-11T09:45:54: 2025-09-11T09:46:00: 2025-09-11T09:46:06: 2025-09-11T09:46:12: 2025-09-11T09:46:19: 2025-09-11T09:46:25: 2025-09-11T09:46:31: 2025-09-11T09:46:38: 2025-09-11T09:46:44: 2025-09-11T09:46:50: 2025-09-11T09:46:56: 2025-09-11T09:47:03: 2025-09-11T09:47:09: 2025-09-11T09:47:15: 2025-09-11T09:47:22: 2025-09-11T09:47:28: 2025-09-11T09:47:34: 2025-09-11T09:47:40: 2025-09-11T09:47:47: 2025-09-11T09:47:53: 2025-09-11T09:47:59: 2025-09-11T09:48:05: 2025-09-11T09:48:12: 2025-09-11T09:48:18: 2025-09-11T09:48:24: 2025-09-11T09:48:30: 2025-09-11T09:48:37: 2025-09-11T09:48:43: 2025-09-11T09:48:49: 2025-09-11T09:48:55: 2025-09-11T09:49:02: 2025-09-11T09:49:08: 2025-09-11T09:49:14: 2025-09-11T09:49:21: 2025-09-11T09:49:27: 2025-09-11T09:49:33: 2025-09-11T09:49:40: 2025-09-11T09:49:46: 2025-09-11T09:49:52: 2025-09-11T09:49:58: 2025-09-11T09:50:06: 2025-09-11T09:50:13: 2025-09-11T09:50:20: 2025-09-11T09:50:26: 2025-09-11T09:50:33: 2025-09-11T09:50:39: 2025-09-11T09:50:45: 2025-09-11T09:50:51: 2025-09-11T09:50:58: 2025-09-11T09:51:04: 2025-09-11T09:51:10: 2025-09-11T09:51:16: 2025-09-11T09:51:23: 2025-09-11T09:51:29: 2025-09-11T09:51:35: 2025-09-11T09:51:41: 2025-09-11T09:51:48: 2025-09-11T09:51:54: 2025-09-11T09:52:00: 2025-09-11T09:52:07: 2025-09-11T09:52:13: 2025-09-11T09:52:19: 2025-09-11T09:52:25: 2025-09-11T09:52:31: 2025-09-11T09:52:38: 2025-09-11T09:52:44: 2025-09-11T09:52:50: 2025-09-11T09:52:57: 2025-09-11T09:53:03: 2025-09-11T09:53:09: 2025-09-11T09:53:16: 2025-09-11T09:53:22: 2025-09-11T09:53:28: 2025-09-11T09:53:34: 2025-09-11T09:53:41: 2025-09-11T09:53:47: 2025-09-11T09:53:53: 2025-09-11T09:53:59: 2025-09-11T09:54:06: 2025-09-11T09:54:12: 2025-09-11T09:54:18: 2025-09-11T09:54:24: 2025-09-11T09:54:31: 2025-09-11T09:54:37: 2025-09-11T09:54:43: 2025-09-11T09:54:49: 2025-09-11T09:54:56: 2025-09-11T09:55:03: 2025-09-11T09:55:10: 2025-09-11T09:55:17: 2025-09-11T09:55:23: 2025-09-11T09:55:30: 2025-09-11T09:55:36: 2025-09-11T09:55:42: 2025-09-11T09:55:48: 2025-09-11T09:55:55: 2025-09-11T09:56:01: 2025-09-11T09:56:07: 2025-09-11T09:56:14: 2025-09-11T09:56:21: 2025-09-11T09:56:27: 2025-09-11T09:56:34:
|
||||
48
monitor.sh
Executable file
48
monitor.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
# PromptForge 服务监控脚本
|
||||
LOG_FILE="/home/renjianbo/aiapply/logs/monitor.log"
|
||||
DATE=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# 创建日志目录
|
||||
mkdir -p /home/renjianbo/aiapply/logs
|
||||
|
||||
# 检查服务状态
|
||||
if ! netstat -tlnp | grep -q :3000; then
|
||||
echo "[$DATE] ❌ 服务未运行,尝试重启..." >> $LOG_FILE
|
||||
cd /home/renjianbo/aiapply
|
||||
pm2 restart promptforge
|
||||
sleep 5
|
||||
if netstat -tlnp | grep -q :3000; then
|
||||
echo "[$DATE] ✅ 服务重启成功" >> $LOG_FILE
|
||||
else
|
||||
echo "[$DATE] ❌ 服务重启失败" >> $LOG_FILE
|
||||
fi
|
||||
else
|
||||
echo "[$DATE] ✅ 服务运行正常" >> $LOG_FILE
|
||||
fi
|
||||
|
||||
# 检查内存使用
|
||||
MEMORY_USAGE=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}')
|
||||
if (( $(echo "$MEMORY_USAGE > 80" | bc -l) )); then
|
||||
echo "[$DATE] ⚠️ 内存使用率过高: ${MEMORY_USAGE}%" >> $LOG_FILE
|
||||
fi
|
||||
|
||||
# 检查磁盘空间
|
||||
DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
|
||||
if [ $DISK_USAGE -gt 80 ]; then
|
||||
echo "[$DATE] ⚠️ 磁盘使用率过高: ${DISK_USAGE}%" >> $LOG_FILE
|
||||
fi
|
||||
|
||||
# 检查 PM2 状态
|
||||
PM2_STATUS=$(pm2 list | grep promptforge | awk '{print $10}' 2>/dev/null)
|
||||
if [ "$PM2_STATUS" != "online" ]; then
|
||||
echo "[$DATE] ⚠️ PM2 服务状态异常: $PM2_STATUS" >> $LOG_FILE
|
||||
fi
|
||||
|
||||
# 记录系统负载
|
||||
LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
|
||||
echo "[$DATE] 📊 系统负载: $LOAD_AVG, 内存使用: ${MEMORY_USAGE}%, 磁盘使用: ${DISK_USAGE}%" >> $LOG_FILE
|
||||
|
||||
# 保持日志文件大小合理(保留最近1000行)
|
||||
tail -n 1000 $LOG_FILE > $LOG_FILE.tmp && mv $LOG_FILE.tmp $LOG_FILE
|
||||
29
start.sh
Executable file
29
start.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
# PromptForge 启动脚本
|
||||
cd /home/renjianbo/aiapply
|
||||
|
||||
# 检查端口是否被占用
|
||||
if netstat -tlnp | grep -q :3000; then
|
||||
echo "端口 3000 已被占用,正在停止现有服务..."
|
||||
pkill -f "next dev"
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# 启动服务
|
||||
echo "启动 PromptForge 服务..."
|
||||
nohup npx next@14.0.4 dev -H 0.0.0.0 -p 3000 > app.log 2>&1 &
|
||||
|
||||
# 等待服务启动
|
||||
sleep 5
|
||||
|
||||
# 检查服务状态
|
||||
if netstat -tlnp | grep -q :3000; then
|
||||
echo "✅ PromptForge 服务启动成功!"
|
||||
echo "🌐 访问地址: http://101.43.95.130:3000"
|
||||
echo "📊 服务状态:"
|
||||
netstat -tlnp | grep :3000
|
||||
else
|
||||
echo "❌ 服务启动失败,请检查日志:"
|
||||
tail -20 app.log
|
||||
fi
|
||||
224
启动停止.txt
Normal file
224
启动停止.txt
Normal file
@@ -0,0 +1,224 @@
|
||||
# PromptForge 项目启动停止操作指南
|
||||
|
||||
## 🚀 启动服务器
|
||||
|
||||
### 方法一:直接启动(推荐)
|
||||
```bash
|
||||
# 进入项目目录
|
||||
cd /home/renjianbo/aiapply
|
||||
|
||||
# 启动开发服务器
|
||||
npx next@14.0.4 dev -H 0.0.0.0 -p 3000 &
|
||||
```
|
||||
|
||||
### 方法二:使用启动脚本
|
||||
```bash
|
||||
# 进入项目目录
|
||||
cd /home/renjianbo/aiapply
|
||||
|
||||
# 运行启动脚本
|
||||
./start.sh
|
||||
```
|
||||
|
||||
### 方法三:使用 PM2 进程管理器
|
||||
```bash
|
||||
# 进入项目目录
|
||||
cd /home/renjianbo/aiapply
|
||||
|
||||
# 启动 PM2 服务
|
||||
pm2 start ecosystem.config.js
|
||||
|
||||
# 查看服务状态
|
||||
pm2 status
|
||||
|
||||
# 查看日志
|
||||
pm2 logs promptforge
|
||||
```
|
||||
|
||||
## 🛑 停止服务器
|
||||
|
||||
### 方法一:停止所有 Next.js 进程
|
||||
```bash
|
||||
# 停止所有 next dev 进程
|
||||
pkill -f "next dev"
|
||||
```
|
||||
|
||||
### 方法二:停止特定端口进程
|
||||
```bash
|
||||
# 查找占用 3000 端口的进程
|
||||
netstat -tlnp | grep :3000
|
||||
|
||||
# 根据进程ID停止(替换 PID 为实际进程ID)
|
||||
kill -9 PID
|
||||
```
|
||||
|
||||
### 方法三:使用 PM2 停止
|
||||
```bash
|
||||
# 停止 PM2 服务
|
||||
pm2 stop promptforge
|
||||
|
||||
# 删除 PM2 服务
|
||||
pm2 delete promptforge
|
||||
|
||||
# 停止所有 PM2 服务
|
||||
pm2 stop all
|
||||
```
|
||||
|
||||
## 📊 检查服务状态
|
||||
|
||||
### 检查端口监听
|
||||
```bash
|
||||
# 检查 3000 端口是否被占用
|
||||
netstat -tlnp | grep :3000
|
||||
```
|
||||
|
||||
### 检查进程状态
|
||||
```bash
|
||||
# 查看 Next.js 相关进程
|
||||
ps aux | grep next | grep -v grep
|
||||
```
|
||||
|
||||
### 检查服务日志
|
||||
```bash
|
||||
# 查看应用日志
|
||||
tail -f app.log
|
||||
|
||||
# 查看 PM2 日志
|
||||
pm2 logs promptforge
|
||||
```
|
||||
|
||||
## 🌐 访问地址
|
||||
|
||||
- **本地访问**:http://localhost:3000
|
||||
- **公网访问**:http://101.43.95.130:3000
|
||||
- **网络访问**:http://0.0.0.0:3000
|
||||
|
||||
## 🔧 常用命令
|
||||
|
||||
### 重启服务
|
||||
```bash
|
||||
# 停止服务
|
||||
pkill -f "next dev"
|
||||
|
||||
# 等待 2 秒
|
||||
sleep 2
|
||||
|
||||
# 重新启动
|
||||
npx next@14.0.4 dev -H 0.0.0.0 -p 3000 &
|
||||
```
|
||||
|
||||
### 查看服务资源使用
|
||||
```bash
|
||||
# 查看 CPU 和内存使用
|
||||
top -p $(pgrep -f "next dev")
|
||||
|
||||
# 查看端口占用详情
|
||||
lsof -i :3000
|
||||
```
|
||||
|
||||
### 设置开机自启动(PM2)
|
||||
```bash
|
||||
# 设置 PM2 开机自启动
|
||||
pm2 startup
|
||||
|
||||
# 保存当前 PM2 进程列表
|
||||
pm2 save
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **端口冲突**:确保 3000 端口没有被其他服务占用
|
||||
2. **防火墙**:确保防火墙允许 3000 端口访问
|
||||
3. **进程管理**:使用 `&` 后台运行或 PM2 管理进程
|
||||
4. **日志监控**:定期检查日志文件,及时发现问题
|
||||
5. **资源监控**:监控 CPU 和内存使用情况
|
||||
|
||||
## 🆘 故障排除
|
||||
|
||||
### 服务启动失败
|
||||
```bash
|
||||
# 检查 Node.js 版本
|
||||
node --version
|
||||
|
||||
# 检查依赖是否安装
|
||||
npm list
|
||||
|
||||
# 重新安装依赖
|
||||
npm install
|
||||
```
|
||||
|
||||
### 端口被占用
|
||||
```bash
|
||||
# 查看占用端口的进程
|
||||
sudo netstat -tlnp | grep :3000
|
||||
|
||||
# 强制停止占用进程
|
||||
sudo kill -9 PID
|
||||
```
|
||||
|
||||
### 内存不足
|
||||
```bash
|
||||
# 查看内存使用
|
||||
free -h
|
||||
|
||||
# 清理缓存
|
||||
npm cache clean --force
|
||||
```
|
||||
|
||||
## 📝 快速操作脚本
|
||||
|
||||
### 一键启动
|
||||
```bash
|
||||
#!/bin/bash
|
||||
cd /home/renjianbo/aiapply
|
||||
pkill -f "next dev" 2>/dev/null
|
||||
sleep 2
|
||||
npx next@14.0.4 dev -H 0.0.0.0 -p 3000 &
|
||||
echo "✅ PromptForge 服务已启动"
|
||||
echo "🌐 访问地址: http://101.43.95.130:3000"
|
||||
```
|
||||
|
||||
### 一键停止
|
||||
```bash
|
||||
#!/bin/bash
|
||||
pkill -f "next dev"
|
||||
echo "✅ PromptForge 服务已停止"
|
||||
```
|
||||
|
||||
### 一键重启
|
||||
```bash
|
||||
#!/bin/bash
|
||||
cd /home/renjianbo/aiapply
|
||||
pkill -f "next dev"
|
||||
sleep 2
|
||||
npx next@14.0.4 dev -H 0.0.0.0 -p 3000 &
|
||||
echo "✅ PromptForge 服务已重启"
|
||||
echo "🌐 访问地址: http://101.43.95.130:3000"
|
||||
```
|
||||
|
||||
---
|
||||
**创建时间**:$(date)
|
||||
**项目路径**:/home/renjianbo/aiapply
|
||||
**服务端口**:3000
|
||||
**公网地址**:101.43.95.130
|
||||
|
||||
|
||||
|
||||
# 查看服务状态
|
||||
pm2 status
|
||||
|
||||
# 重启服务
|
||||
pm2 restart promptforge
|
||||
|
||||
# 查看日志
|
||||
pm2 logs promptforge
|
||||
|
||||
# 停止服务
|
||||
pm2 stop promptforge
|
||||
|
||||
|
||||
# 查看监控日志
|
||||
tail -f logs/monitor.log
|
||||
|
||||
# 手动运行监控
|
||||
./monitor.sh
|
||||
348
服务器稳定性优化方案.txt
Normal file
348
服务器稳定性优化方案.txt
Normal file
@@ -0,0 +1,348 @@
|
||||
# PromptForge 服务器稳定性优化方案
|
||||
|
||||
## 📊 当前服务器资源分析
|
||||
|
||||
### 硬件配置
|
||||
- **CPU**: 2 核心
|
||||
- **内存**: 3.6GB 总内存,1.9GB 可用
|
||||
- **磁盘**: 89GB 总容量,62GB 可用 (28% 使用率)
|
||||
- **负载**: 0.24 (低负载,运行良好)
|
||||
|
||||
### 当前应用资源使用
|
||||
- **Next.js 服务**: 323MB 内存 (8.5%)
|
||||
- **总内存使用**: 1.4GB (38.9%)
|
||||
- **可用内存**: 1.9GB (充足)
|
||||
|
||||
## 🎯 稳定性优化方案
|
||||
|
||||
### 方案一:PM2 进程管理 (推荐)
|
||||
|
||||
#### 1. 安装和配置 PM2
|
||||
```bash
|
||||
# 安装 PM2
|
||||
npm install -g pm2
|
||||
|
||||
# 创建 PM2 配置文件
|
||||
cat > ecosystem.config.js << 'EOF'
|
||||
module.exports = {
|
||||
apps: [{
|
||||
name: 'promptforge',
|
||||
script: 'npx',
|
||||
args: 'next@14.0.4 dev -H 0.0.0.0 -p 3000',
|
||||
cwd: '/home/renjianbo/aiapply',
|
||||
instances: 1, // 单实例,适合小服务器
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
max_memory_restart: '800M', // 内存超过800MB自动重启
|
||||
min_uptime: '10s',
|
||||
max_restarts: 10,
|
||||
restart_delay: 4000,
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
PORT: 3000
|
||||
},
|
||||
error_file: '/home/renjianbo/aiapply/logs/err.log',
|
||||
out_file: '/home/renjianbo/aiapply/logs/out.log',
|
||||
log_file: '/home/renjianbo/aiapply/logs/combined.log',
|
||||
time: true
|
||||
}]
|
||||
}
|
||||
EOF
|
||||
|
||||
# 创建日志目录
|
||||
mkdir -p logs
|
||||
|
||||
# 启动服务
|
||||
pm2 start ecosystem.config.js
|
||||
|
||||
# 设置开机自启动
|
||||
pm2 startup
|
||||
pm2 save
|
||||
```
|
||||
|
||||
#### 2. PM2 监控和管理
|
||||
```bash
|
||||
# 查看服务状态
|
||||
pm2 status
|
||||
|
||||
# 查看实时日志
|
||||
pm2 logs promptforge
|
||||
|
||||
# 重启服务
|
||||
pm2 restart promptforge
|
||||
|
||||
# 停止服务
|
||||
pm2 stop promptforge
|
||||
|
||||
# 监控资源使用
|
||||
pm2 monit
|
||||
```
|
||||
|
||||
### 方案二:系统级优化
|
||||
|
||||
#### 1. 系统资源限制
|
||||
```bash
|
||||
# 创建系统限制配置
|
||||
sudo tee /etc/security/limits.d/promptforge.conf << 'EOF'
|
||||
# PromptForge 用户资源限制
|
||||
renjianbo soft nofile 65536
|
||||
renjianbo hard nofile 65536
|
||||
renjianbo soft nproc 32768
|
||||
renjianbo hard nproc 32768
|
||||
EOF
|
||||
|
||||
# 应用限制
|
||||
ulimit -n 65536
|
||||
ulimit -u 32768
|
||||
```
|
||||
|
||||
#### 2. 内存优化
|
||||
```bash
|
||||
# 调整系统内存参数
|
||||
sudo tee -a /etc/sysctl.conf << 'EOF'
|
||||
# 内存优化
|
||||
vm.swappiness = 10
|
||||
vm.dirty_ratio = 15
|
||||
vm.dirty_background_ratio = 5
|
||||
vm.overcommit_memory = 1
|
||||
EOF
|
||||
|
||||
# 应用配置
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
### 方案三:Nginx 反向代理优化
|
||||
|
||||
#### 1. 创建优化的 Nginx 配置
|
||||
```bash
|
||||
# 创建 Nginx 配置文件
|
||||
sudo tee /etc/nginx/conf.d/promptforge.conf << 'EOF'
|
||||
upstream promptforge_backend {
|
||||
server 127.0.0.1:3000;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name 101.43.95.130;
|
||||
|
||||
# 重定向到 HTTPS
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name 101.43.95.130;
|
||||
|
||||
# SSL 配置
|
||||
ssl_certificate /path/to/your/cert.pem;
|
||||
ssl_certificate_key /path/to/your/key.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
|
||||
|
||||
# 性能优化
|
||||
client_max_body_size 10M;
|
||||
client_body_timeout 60s;
|
||||
client_header_timeout 60s;
|
||||
keepalive_timeout 65s;
|
||||
send_timeout 60s;
|
||||
|
||||
# 压缩配置
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
|
||||
|
||||
# 缓存配置
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# 反向代理
|
||||
location / {
|
||||
proxy_pass http://promptforge_backend;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
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_cache_bypass $http_upgrade;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
# 缓冲设置
|
||||
proxy_buffering on;
|
||||
proxy_buffer_size 4k;
|
||||
proxy_buffers 8 4k;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
### 方案四:监控和告警
|
||||
|
||||
#### 1. 创建监控脚本
|
||||
```bash
|
||||
# 创建监控脚本
|
||||
cat > monitor.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# 监控脚本
|
||||
LOG_FILE="/home/renjianbo/aiapply/logs/monitor.log"
|
||||
DATE=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# 检查服务状态
|
||||
if ! netstat -tlnp | grep -q :3000; then
|
||||
echo "[$DATE] 服务未运行,尝试重启..." >> $LOG_FILE
|
||||
cd /home/renjianbo/aiapply
|
||||
pm2 restart promptforge
|
||||
fi
|
||||
|
||||
# 检查内存使用
|
||||
MEMORY_USAGE=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}')
|
||||
if (( $(echo "$MEMORY_USAGE > 80" | bc -l) )); then
|
||||
echo "[$DATE] 内存使用率过高: ${MEMORY_USAGE}%" >> $LOG_FILE
|
||||
fi
|
||||
|
||||
# 检查磁盘空间
|
||||
DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
|
||||
if [ $DISK_USAGE -gt 80 ]; then
|
||||
echo "[$DATE] 磁盘使用率过高: ${DISK_USAGE}%" >> $LOG_FILE
|
||||
fi
|
||||
|
||||
echo "[$DATE] 监控检查完成" >> $LOG_FILE
|
||||
EOF
|
||||
|
||||
chmod +x monitor.sh
|
||||
|
||||
# 添加到 crontab (每5分钟检查一次)
|
||||
(crontab -l 2>/dev/null; echo "*/5 * * * * /home/renjianbo/aiapply/monitor.sh") | crontab -
|
||||
```
|
||||
|
||||
### 方案五:并发访问优化
|
||||
|
||||
#### 1. 连接池配置
|
||||
```bash
|
||||
# 创建环境变量配置
|
||||
cat >> .env.local << 'EOF'
|
||||
# 数据库连接池
|
||||
DATABASE_POOL_SIZE=5
|
||||
DATABASE_POOL_TIMEOUT=20000
|
||||
|
||||
# 应用配置
|
||||
NEXT_PUBLIC_MAX_CONCURRENT_REQUESTS=10
|
||||
NEXT_PUBLIC_REQUEST_TIMEOUT=30000
|
||||
EOF
|
||||
```
|
||||
|
||||
#### 2. 系统连接优化
|
||||
```bash
|
||||
# 调整系统连接参数
|
||||
sudo tee -a /etc/sysctl.conf << 'EOF'
|
||||
# 网络连接优化
|
||||
net.core.somaxconn = 65535
|
||||
net.core.netdev_max_backlog = 5000
|
||||
net.ipv4.tcp_max_syn_backlog = 65535
|
||||
net.ipv4.tcp_keepalive_time = 600
|
||||
net.ipv4.tcp_keepalive_intvl = 60
|
||||
net.ipv4.tcp_keepalive_probes = 3
|
||||
EOF
|
||||
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
## 📈 预期性能提升
|
||||
|
||||
### 并发访问能力
|
||||
- **当前**: 5-10 并发用户
|
||||
- **优化后**: 15-25 并发用户
|
||||
- **响应时间**: 减少 30-50%
|
||||
|
||||
### 稳定性提升
|
||||
- **自动重启**: 进程异常时自动恢复
|
||||
- **内存监控**: 防止内存泄漏
|
||||
- **负载均衡**: Nginx 反向代理
|
||||
- **监控告警**: 实时状态监控
|
||||
|
||||
## 🚀 实施步骤
|
||||
|
||||
### 第一步:PM2 部署 (立即实施)
|
||||
```bash
|
||||
# 停止当前服务
|
||||
pkill -f "next dev"
|
||||
|
||||
# 安装 PM2
|
||||
npm install -g pm2
|
||||
|
||||
# 启动 PM2 服务
|
||||
pm2 start ecosystem.config.js
|
||||
pm2 startup
|
||||
pm2 save
|
||||
```
|
||||
|
||||
### 第二步:系统优化 (可选)
|
||||
```bash
|
||||
# 应用系统限制
|
||||
sudo tee /etc/security/limits.d/promptforge.conf << 'EOF'
|
||||
renjianbo soft nofile 65536
|
||||
renjianbo hard nofile 65536
|
||||
EOF
|
||||
|
||||
# 调整内存参数
|
||||
sudo tee -a /etc/sysctl.conf << 'EOF'
|
||||
vm.swappiness = 10
|
||||
net.core.somaxconn = 65535
|
||||
EOF
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
### 第三步:监控部署 (推荐)
|
||||
```bash
|
||||
# 创建监控脚本
|
||||
./monitor.sh
|
||||
|
||||
# 设置定时监控
|
||||
(crontab -l 2>/dev/null; echo "*/5 * * * * /home/renjianbo/aiapply/monitor.sh") | crontab -
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **内存限制**: 当前服务器内存有限,避免过度优化
|
||||
2. **CPU 核心**: 2核心服务器,建议单实例运行
|
||||
3. **磁盘空间**: 定期清理日志文件
|
||||
4. **网络带宽**: 监控带宽使用情况
|
||||
5. **备份策略**: 定期备份重要数据
|
||||
|
||||
## 📊 监控指标
|
||||
|
||||
### 关键指标
|
||||
- **内存使用率**: < 80%
|
||||
- **CPU 使用率**: < 70%
|
||||
- **响应时间**: < 2秒
|
||||
- **并发连接**: < 25
|
||||
- **错误率**: < 1%
|
||||
|
||||
### 监控命令
|
||||
```bash
|
||||
# 实时监控
|
||||
pm2 monit
|
||||
|
||||
# 查看日志
|
||||
pm2 logs promptforge --lines 100
|
||||
|
||||
# 系统资源
|
||||
htop
|
||||
iostat -x 1
|
||||
```
|
||||
|
||||
---
|
||||
**创建时间**: $(date)
|
||||
**服务器配置**: 2核3.6GB内存
|
||||
**预期并发**: 15-25用户
|
||||
**优化目标**: 稳定性 + 性能
|
||||
Reference in New Issue
Block a user