更新PM2配置并添加相关脚本

This commit is contained in:
2025-09-11 17:07:53 +08:00
parent 15b9cd406e
commit 7b237968b9
14 changed files with 228 additions and 1121 deletions

View File

@@ -21,11 +21,7 @@ const config = {
expiresIn: process.env.JWT_EXPIRES_IN || '7d',
refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN || '30d'
},
redis: {
host: process.env.REDIS_HOST || 'redis.jiebanke.com',
port: process.env.REDIS_PORT || 6379,
password: process.env.REDIS_PASSWORD || ''
},
upload: {
maxFileSize: 5 * 1024 * 1024, // 5MB
allowedTypes: ['image/jpeg', 'image/png', 'image/gif']
@@ -78,11 +74,7 @@ const config = {
expiresIn: process.env.JWT_EXPIRES_IN || '1d',
refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN || '7d'
},
redis: {
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT || 6379,
password: process.env.REDIS_PASSWORD
},
upload: {
maxFileSize: 10 * 1024 * 1024, // 10MB
allowedTypes: ['image/jpeg', 'image/png', 'image/webp']

View File

@@ -7,17 +7,17 @@ module.exports = {
// 环境变量
env: {
NODE_ENV: 'development',
PORT: 3200,
PORT: 3310,
WATCH: false
},
env_production: {
NODE_ENV: 'production',
PORT: 3200,
PORT: 3310,
WATCH: false
},
env_test: {
NODE_ENV: 'test',
PORT: 3001,
PORT: 3311,
WATCH: false
},
// 日志配置

View File

@@ -1,10 +1,10 @@
# 结伴客后端Nginx配置文件
# SSL配置和webapi.jiebanke.com域名设置
# SSL配置和wapi.jiebanke.com域名设置
# HTTP服务器配置 - 重定向到HTTPS
server {
listen 80;
server_name webapi.jiebanke.com;
server_name wapi.jiebanke.com;
# 强制HTTPS重定向
return 301 https://$server_name$request_uri;
@@ -14,11 +14,11 @@ server {
server {
# 监听443端口并启用SSL
listen 443 ssl http2;
server_name webapi.jiebanke.com;
server_name wapi.jiebanke.com;
# SSL证书配置
ssl_certificate /etc/nginx/ssl/webapi.jiebanke.com.crt;
ssl_certificate_key /etc/nginx/ssl/webapi.jiebanke.com.key;
ssl_certificate /etc/nginx/ssl/wapi.jiebanke.com.crt;
ssl_certificate_key /etc/nginx/ssl/wapi.jiebanke.com.key;
# SSL优化配置
ssl_protocols TLSv1.2 TLSv1.3;
@@ -43,7 +43,7 @@ server {
# 代理配置
location / {
# 代理到Node.js后端服务
proxy_pass http://localhost:3200;
proxy_pass http://localhost:3310;
# 代理头信息配置
proxy_set_header Host $host;
@@ -71,21 +71,21 @@ server {
# 健康检查端点
location /health {
access_log off;
proxy_pass http://localhost:3200/health;
proxy_pass http://localhost:3310/health;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# API文档端点
location /api-docs {
proxy_pass http://localhost:3200/api-docs;
proxy_pass http://localhost:3310/api-docs;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 静态资源缓存控制(如果后端有静态资源)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
proxy_pass http://localhost:3200;
proxy_pass http://localhost:3310;
expires 1y;
add_header Cache-Control "public, immutable";
}

View File

@@ -0,0 +1,91 @@
#!/bin/bash
# 结伴客后端服务器启动脚本
# 适用于CentOS生产环境
# 服务器目录: /data/nodejsjiebanke/
set -e
# 配置参数
APP_NAME="jiebanke-backend"
APP_DIR="/data/nodejsjiebanke"
PORT="3310"
LOG_DIR="$APP_DIR/logs"
cd "$APP_DIR"
echo "🚀 开始启动 $APP_NAME 服务..."
echo "📋 工作目录: $APP_DIR"
echo "🔌 服务端口: $PORT"
echo "📊 日志目录: $LOG_DIR"
echo ""
# 创建日志目录
if [ ! -d "$LOG_DIR" ]; then
mkdir -p "$LOG_DIR"
echo "✅ 创建日志目录: $LOG_DIR"
fi
# 检查Node.js环境
echo "🔍 检查Node.js环境..."
if ! command -v node &> /dev/null; then
echo "❌ Node.js未安装请先安装Node.js"
exit 1
fi
if ! command -v npm &> /dev/null; then
echo "❌ npm未安装请先安装npm"
exit 1
fi
if ! command -v pm2 &> /dev/null; then
echo "❌ pm2未安装正在安装pm2..."
npm install -g pm2
echo "✅ pm2安装完成"
fi
echo "✅ Node.js版本: $(node -v)"
echo "✅ npm版本: $(npm -v)"
echo "✅ pm2版本: $(pm2 -v)"
# 安装依赖
echo ""
echo "📦 安装项目依赖..."
npm install --production
# 停止现有服务(如果存在)
echo ""
echo "🛑 停止现有服务..."
pm2 delete "$APP_NAME" 2>/dev/null || true
pm2 flush "$APP_NAME" 2>/dev/null || true
# 启动服务
echo ""
echo "🚀 启动服务..."
NODE_ENV=production PORT=$PORT pm2 start ecosystem.config.js --name "$APP_NAME"
# 保存pm2配置
echo ""
echo "💾 保存pm2配置..."
pm2 save
# 设置开机自启
echo ""
echo "🔧 设置开机自启..."
pm2 startup 2>/dev/null || echo "⚠️ 开机自启设置可能需要手动执行: pm2 startup"
# 显示服务状态
echo ""
echo "📊 服务状态:"
pm2 status "$APP_NAME"
echo ""
echo "$APP_NAME 服务启动成功!"
echo "🌐 服务地址: http://localhost:$PORT"
echo "📋 启动时间: $(date)"
echo ""
echo "💡 常用命令:"
echo " 查看日志: pm2 logs $APP_NAME"
echo " 重启服务: pm2 restart $APP_NAME"
echo " 停止服务: pm2 stop $APP_NAME"
echo " 服务状态: pm2 status"

View File

@@ -0,0 +1,65 @@
# 结伴客后端同步脚本 - Windows PowerShell版本
# 同步文件到CentOS生产服务器
# 服务器地址: www.jiebanke.com
# 服务器目录: /data/nodejsjiebanke/
Write-Host "🚀 开始同步文件到生产服务器..." -ForegroundColor Green
Write-Host "📋 服务器: www.jiebanke.com"
Write-Host "📁 目标目录: /data/nodejsjiebanke/"
Write-Host "📁 本地目录: e:\vue\jiebanke\backend\"
Write-Host ""
# 检查rsync是否可用
$rsyncAvailable = Get-Command rsync -ErrorAction SilentlyContinue
if (-not $rsyncAvailable) {
Write-Host "❌ rsync未安装请先安装Git for Windows或Cygwin" -ForegroundColor Red
Write-Host "💡 或者使用WSL中的rsync"
exit 1
}
# 同步文件到服务器
try {
Write-Host "📤 正在同步文件..." -ForegroundColor Yellow
$rsyncArgs = @(
"-avz",
"--delete",
"--exclude=node_modules/",
"--exclude=logs/",
"--exclude=uploads/",
"--exclude=.git/",
"--exclude=.env",
"--exclude=*.log",
"--exclude=*.tmp",
"--exclude=.DS_Store",
"--exclude=*.swp",
"--exclude=*.swo",
"-e", "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
"e:/vue/jiebanke/backend/",
"root@www.jiebanke.com:/data/nodejsjiebanke/"
)
& rsync @rsyncArgs
if ($LASTEXITCODE -eq 0) {
Write-Host "✅ 文件同步完成!" -ForegroundColor Green
} else {
Write-Host "❌ 文件同步失败,退出码: $LASTEXITCODE" -ForegroundColor Red
exit $LASTEXITCODE
}
# 设置文件权限
Write-Host "🔧 设置文件权限..." -ForegroundColor Yellow
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@www.jiebanke.com "chmod 755 /data/nodejsjiebanke/*.sh && chmod 644 /data/nodejsjiebanke/package.json"
Write-Host ""
Write-Host "✅ 同步完成!" -ForegroundColor Green
Write-Host "📋 同步时间: $(Get-Date)"
Write-Host "💡 接下来请在服务器上运行启动脚本:"
Write-Host " ssh root@www.jiebanke.com"
Write-Host " cd /data/nodejsjiebanke/ && ./start-server.sh"
} catch {
Write-Host "❌ 同步过程中发生错误: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}

View File

@@ -0,0 +1,58 @@
#!/bin/bash
# 结伴客后端同步脚本 - 同步文件到CentOS生产服务器
# 服务器地址: www.jiebanke.com
# 服务器目录: /data/nodejsjiebanke/
set -e
# 配置参数
SERVER="www.jiebanke.com"
SERVER_USER="root"
SERVER_DIR="/data/nodejsjiebanke/"
LOCAL_DIR="e:/vue/jiebanke/backend/"
# 需要排除的文件和目录
EXCLUDE_LIST=(
"--exclude=node_modules/"
"--exclude=logs/"
"--exclude=uploads/"
"--exclude=.git/"
"--exclude=.env"
"--exclude=*.log"
"--exclude=*.tmp"
"--exclude=.DS_Store"
"--exclude=*.swp"
"--exclude=*.swo"
)
echo "🚀 开始同步文件到生产服务器..."
echo "📋 服务器: $SERVER"
echo "📁 目标目录: $SERVER_DIR"
echo "📁 本地目录: $LOCAL_DIR"
echo ""
# 检查本地目录是否存在
if [ ! -d "$LOCAL_DIR" ]; then
echo "❌ 错误: 本地目录 $LOCAL_DIR 不存在"
exit 1
fi
# 同步文件到服务器
echo "📤 正在同步文件..."
rsync -avz --delete \
"${EXCLUDE_LIST[@]}" \
-e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
"$LOCAL_DIR" \
"$SERVER_USER@$SERVER:$SERVER_DIR"
# 设置文件权限
echo "🔧 设置文件权限..."
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
"$SERVER_USER@$SERVER" \
"chmod 755 $SERVER_DIR/*.sh && chmod 644 $SERVER_DIR/package.json"
echo ""
echo "✅ 同步完成!"
echo "📋 同步时间: $(date)"
echo "💡 接下来请在服务器上运行启动脚本: cd $SERVER_DIR && ./start-server.sh"

View File

@@ -1,203 +0,0 @@
const amqp = require('amqplib');
class RabbitMQConfig {
constructor() {
this.connection = null;
this.channel = null;
this.isConnected = false;
this.exchanges = new Map();
this.queues = new Map();
}
// 获取连接URL
getConnectionUrl() {
const host = process.env.RABBITMQ_HOST || 'rabbitmq.jiebanke.com';
const port = process.env.RABBITMQ_PORT || 5672;
const username = process.env.RABBITMQ_USERNAME || 'guest';
const password = process.env.RABBITMQ_PASSWORD || 'guest';
const vhost = process.env.RABBITMQ_VHOST || '/';
return `amqp://${username}:${password}@${host}:${port}/${vhost}`;
}
// 连接RabbitMQ
async connect() {
if (this.isConnected) {
return { connection: this.connection, channel: this.channel };
}
try {
const url = this.getConnectionUrl();
this.connection = await amqp.connect(url);
this.connection.on('error', (err) => {
console.error('RabbitMQ连接错误:', err);
this.isConnected = false;
});
this.connection.on('close', () => {
console.log('❌ RabbitMQ连接关闭');
this.isConnected = false;
});
this.channel = await this.connection.createChannel();
this.channel.on('error', (err) => {
console.error('RabbitMQ通道错误:', err);
});
this.channel.on('close', () => {
console.log('❌ RabbitMQ通道关闭');
});
this.isConnected = true;
console.log('✅ RabbitMQ连接成功');
// 声明默认交换器
await this.setupDefaultExchanges();
return { connection: this.connection, channel: this.channel };
} catch (error) {
console.error('RabbitMQ连接失败:', error);
throw error;
}
}
// 设置默认交换器
async setupDefaultExchanges() {
const exchanges = [
{ name: 'jiebanke.direct', type: 'direct', durable: true },
{ name: 'jiebanke.topic', type: 'topic', durable: true },
{ name: 'jiebanke.fanout', type: 'fanout', durable: true },
{ name: 'jiebanke.delay', type: 'x-delayed-message', durable: true, arguments: { 'x-delayed-type': 'direct' } }
];
for (const exchange of exchanges) {
await this.channel.assertExchange(exchange.name, exchange.type, {
durable: exchange.durable,
arguments: exchange.arguments
});
this.exchanges.set(exchange.name, exchange);
}
}
// 声明队列
async assertQueue(queueName, options = {}) {
if (!this.isConnected) {
await this.connect();
}
const queueOptions = {
durable: true,
arguments: {
'x-message-ttl': 86400000, // 24小时消息过期时间
...options.arguments
},
...options
};
const queue = await this.channel.assertQueue(queueName, queueOptions);
this.queues.set(queueName, queue);
return queue;
}
// 绑定队列到交换器
async bindQueue(queueName, exchangeName, routingKey = '') {
if (!this.isConnected) {
await this.connect();
}
await this.channel.bindQueue(queueName, exchangeName, routingKey);
console.log(`✅ 队列 ${queueName} 绑定到交换器 ${exchangeName},路由键: ${routingKey}`);
}
// 发布消息
async publish(exchangeName, routingKey, message, options = {}) {
if (!this.isConnected) {
await this.connect();
}
const messageBuffer = Buffer.from(JSON.stringify({
timestamp: new Date().toISOString(),
data: message
}));
const publishOptions = {
persistent: true,
contentType: 'application/json',
...options
};
return this.channel.publish(exchangeName, routingKey, messageBuffer, publishOptions);
}
// 消费消息
async consume(queueName, callback, options = {}) {
if (!this.isConnected) {
await this.connect();
}
const consumeOptions = {
noAck: false,
...options
};
return this.channel.consume(queueName, async (msg) => {
try {
if (msg !== null) {
const content = JSON.parse(msg.content.toString());
await callback(content, msg);
this.channel.ack(msg);
}
} catch (error) {
console.error('消息处理错误:', error);
this.channel.nack(msg, false, false); // 不重新入队
}
}, consumeOptions);
}
// 健康检查
async healthCheck() {
try {
if (!this.isConnected) {
throw new Error('RabbitMQ未连接');
}
return {
status: 'healthy',
host: process.env.RABBITMQ_HOST || 'rabbitmq.jiebanke.com',
port: process.env.RABBITMQ_PORT || 5672,
connected: this.isConnected
};
} catch (error) {
return {
status: 'unhealthy',
error: error.message,
host: process.env.RABBITMQ_HOST || 'rabbitmq.jiebanke.com',
port: process.env.RABBITMQ_PORT || 5672,
connected: false
};
}
}
// 优雅关闭
async close() {
try {
if (this.channel) {
await this.channel.close();
}
if (this.connection) {
await this.connection.close();
}
this.isConnected = false;
console.log('✅ RabbitMQ连接已关闭');
} catch (error) {
console.error('关闭RabbitMQ连接时出错:', error);
}
}
}
// 创建全局RabbitMQ实例
const rabbitMQConfig = new RabbitMQConfig();
module.exports = rabbitMQConfig;

View File

@@ -1,119 +0,0 @@
const redis = require('redis');
class RedisConfig {
constructor() {
this.client = null;
this.isConnected = false;
}
// 创建Redis客户端
createClient() {
const redisConfig = {
socket: {
host: process.env.REDIS_HOST || 'redis.jiebanke.com',
port: process.env.REDIS_PORT || 6379,
reconnectStrategy: (retries) => {
const delay = Math.min(retries * 100, 3000);
console.log(`Redis连接重试第${retries + 1}次,延迟${delay}ms`);
return delay;
}
},
password: process.env.REDIS_PASSWORD || null,
database: process.env.REDIS_DB || 0
};
// 移除空配置项
if (!redisConfig.password) delete redisConfig.password;
this.client = redis.createClient(redisConfig);
// 错误处理
this.client.on('error', (err) => {
console.error('Redis错误:', err);
this.isConnected = false;
});
// 连接成功
this.client.on('connect', () => {
console.log('✅ Redis连接中...');
});
// 准备就绪
this.client.on('ready', () => {
this.isConnected = true;
console.log('✅ Redis连接就绪');
});
// 连接断开
this.client.on('end', () => {
this.isConnected = false;
console.log('❌ Redis连接断开');
});
// 重连
this.client.on('reconnecting', () => {
console.log('🔄 Redis重新连接中...');
});
return this.client;
}
// 连接Redis
async connect() {
if (this.client && this.isConnected) {
return this.client;
}
// 开发环境下如果Redis未配置则不连接
if (process.env.NODE_ENV === 'development' &&
(!process.env.REDIS_HOST || process.env.REDIS_HOST === 'redis.jiebanke.com')) {
console.log('⚠️ 开发环境未配置Redis跳过连接');
return null;
}
try {
this.createClient();
await this.client.connect();
return this.client;
} catch (error) {
console.error('Redis连接失败:', error);
throw error;
}
}
// 断开连接
async disconnect() {
if (this.client) {
await this.client.quit();
this.isConnected = false;
console.log('✅ Redis连接已关闭');
}
}
// 获取客户端状态
getStatus() {
return {
isConnected: this.isConnected,
host: process.env.REDIS_HOST || 'redis.jiebanke.com',
port: process.env.REDIS_PORT || 6379
};
}
// 健康检查
async healthCheck() {
try {
if (!this.isConnected) {
throw new Error('Redis未连接');
}
await this.client.ping();
return { status: 'healthy', ...this.getStatus() };
} catch (error) {
return { status: 'unhealthy', error: error.message, ...this.getStatus() };
}
}
}
// 创建全局Redis实例
const redisConfig = new RedisConfig();
module.exports = redisConfig;

View File

@@ -1 +0,0 @@
start-server.sh

View File

@@ -1 +0,0 @@
start-server.sh

View File

@@ -1 +0,0 @@
start-server.sh

View File

@@ -1,429 +0,0 @@
module.exports = {
apps: [{
name: 'jiebanke-backend',
script: 'server.js',
env: {
PORT: 3200,
NODE_ENV: 'production',
},
autorestart: true,
watch: false,
max_memory_restart: '1G',
output: 'logs/pm2.log',
error: 'logs/pm2-error.log',
log: 'logs/pm2-combined.log',
pid_file: 'pm2.pid',
instances: 1,
exec_mode: 'fork'
}]
};
#!/bin/bash
# 结伴客后端服务启动脚本
# 用于启动Node.js后端服务
# 设置颜色变量
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 显示脚本使用说明
show_usage() {
echo "用法: $0 [选项]"
echo "选项:"
echo " start 启动后端服务"
echo " stop 停止后端服务"
echo " restart 重启后端服务"
echo " status 查看服务状态"
echo " help 显示帮助信息"
}
# 检查是否安装了Node.js
check_node() {
if ! command -v node &> /dev/null; then
echo -e "${RED}错误: 未找到Node.js请先安装Node.js${NC}"
exit 1
fi
NODE_VERSION=$(node -v)
echo -e "${GREEN}✓ Node.js版本: ${NODE_VERSION}${NC}"
}
# 检查是否安装了npm
check_npm() {
if ! command -v npm &> /dev/null; then
echo -e "${RED}错误: 未找到npm请先安装npm${NC}"
exit 1
fi
NPM_VERSION=$(npm -v)
echo -e "${GREEN}✓ npm版本: ${NPM_VERSION}${NC}"
}
# 检查依赖是否已安装
check_dependencies() {
if [ ! -d "node_modules" ]; then
echo -e "${YELLOW}警告: 未找到node_modules目录正在安装依赖...${NC}"
npm install
if [ $? -ne 0 ]; then
echo -e "${RED}错误: 依赖安装失败${NC}"
exit 1
fi
echo -e "${GREEN}✓ 依赖安装完成${NC}"
else
echo -e "${GREEN}✓ 依赖已安装${NC}"
fi
}
# 启动服务
start_service() {
# 检查服务是否已经在运行
if pgrep -f "node.*server.js" > /dev/null; then
echo -e "${YELLOW}警告: 服务已在运行中${NC}"
exit 1
fi
echo -e "${GREEN}正在启动结伴客后端服务...${NC}"
# 设置环境变量
export NODE_ENV=production
export PORT=${PORT:-3200}
# 启动服务并将其放到后台运行
nohup npm start > server.log 2>&1 &
SERVER_PID=$!
# 将PID保存到文件
echo $SERVER_PID > server.pid
# 等待几秒钟让服务启动
sleep 3
# 检查服务是否成功启动
if pgrep -f "node.*server.js" > /dev/null; then
echo -e "${GREEN}✓ 服务启动成功${NC}"
echo -e "${GREEN}✓ PID: ${SERVER_PID}${NC}"
echo -e "${GREEN}✓ 日志文件: server.log${NC}"
echo -e "${GREEN}✓ 访问地址: http://localhost:${PORT}${NC}"
else
echo -e "${RED}✗ 服务启动失败,请检查日志文件 server.log${NC}"
rm -f server.pid
exit 1
fi
}
# 停止服务
stop_service() {
if [ ! -f server.pid ]; then
if pgrep -f "node.*server.js" > /dev/null; then
echo -e "${YELLOW}警告: 找到正在运行的服务但PID文件不存在${NC}"
echo -e "${YELLOW}尝试查找并终止服务...${NC}"
pkill -f "node.*server.js"
sleep 2
if pgrep -f "node.*server.js" > /dev/null; then
echo -e "${RED}✗ 无法终止服务${NC}"
exit 1
else
echo -e "${GREEN}✓ 服务已终止${NC}"
fi
else
echo -e "${YELLOW}服务未在运行${NC}"
fi
else
SERVER_PID=$(cat server.pid)
if ps -p $SERVER_PID > /dev/null; then
echo -e "${GREEN}正在停止服务 (PID: ${SERVER_PID})...${NC}"
kill $SERVER_PID
sleep 3
if ps -p $SERVER_PID > /dev/null; then
echo -e "${YELLOW}服务未响应,强制终止...${NC}"
kill -9 $SERVER_PID
fi
rm -f server.pid
echo -e "${GREEN}✓ 服务已停止${NC}"
else
echo -e "${YELLOW}PID文件存在但服务未在运行${NC}"
rm -f server.pid
fi
fi
}
# 查看服务状态
status_service() {
if [ -f server.pid ]; then
SERVER_PID=$(cat server.pid)
if ps -p $SERVER_PID > /dev/null; then
echo -e "${GREEN}✓ 服务正在运行 (PID: ${SERVER_PID})${NC}"
else
echo -e "${RED}✗ PID文件存在但服务未在运行${NC}"
fi
else
if pgrep -f "node.*server.js" > /dev/null; then
echo -e "${GREEN}✓ 服务正在运行${NC}"
else
echo -e "${YELLOW}服务未在运行${NC}"
fi
fi
}
# 查看日志
tail_logs() {
if [ -f server.log ]; then
tail -f server.log
else
echo -e "${RED}日志文件不存在${NC}"
fi
}
# 主逻辑
main() {
# 获取命令行参数
ACTION=${1:-"start"}
case "$ACTION" in
start)
check_node
check_npm
check_dependencies
start_service
;;
stop)
stop_service
;;
restart)
stop_service
sleep 2
check_node
check_npm
check_dependencies
start_service
;;
status)
status_service
;;
logs)
tail_logs
;;
help)
show_usage
;;
*)
echo -e "${RED}未知选项: $ACTION${NC}"
show_usage
exit 1
;;
esac
}
# 执行主逻辑
main "$@"
```
```
@echo off
title 结伴客后端服务PM2启动脚本
setlocal enabledelayedexpansion
:: 设置颜色
for /f "delims=" %%i in ('echo prompt $E^| cmd') do set "ESC=%%i"
:: 显示使用说明
if "%1"=="" (
call :show_usage
goto :eof
)
:: 根据参数执行相应操作
if "%1"=="start" (
call :start_service
) else if "%1"=="stop" (
call :stop_service
) else if "%1"=="restart" (
call :restart_service
) else if "%1"=="status" (
call :status_service
) else if "%1"=="logs" (
call :logs_service
) else if "%1"=="delete" (
call :delete_service
) else if "%1"=="list" (
call :list_service
) else if "%1"=="help" (
call :show_usage
) else (
echo %ESC%[91m未知选项: %1%ESC%[0m
call :show_usage
)
goto :eof
:: 显示使用说明
:show_usage
echo 用法: %0 [选项]
echo 选项:
echo start 使用PM2启动后端服务
echo stop 停止PM2管理的后端服务
echo restart 重启PM2管理的后端服务
echo status 查看PM2服务状态
echo logs 查看PM2服务日志
echo delete 从PM2中删除应用
echo list 列出所有PM2应用
echo help 显示帮助信息
goto :eof
:: 检查Node.js
:check_node
echo 检查Node.js环境...
node -v >nul 2>&1
if %errorlevel% neq 0 (
echo %ESC%[91m错误: 未找到Node.js请先安装Node.js%ESC%[0m
exit /b 1
) else (
for /f %%i in ('node -v') do set NODE_VERSION=%%i
echo %ESC%[92m✓ Node.js版本: %NODE_VERSION%%ESC%[0m
)
goto :eof
:: 检查npm
:check_npm
echo 检查npm环境...
npm -v >nul 2>&1
if %errorlevel% neq 0 (
echo %ESC%[91m错误: 未找到npm请先安装npm%ESC%[0m
exit /b 1
) else (
for /f %%i in ('npm -v') do set NPM_VERSION=%%i
echo %ESC%[92m✓ npm版本: %NPM_VERSION%%ESC%[0m
)
goto :eof
:: 检查PM2
:check_pm2
echo 检查PM2环境...
pm2 -v >nul 2>&1
if %errorlevel% neq 0 (
echo %ESC%[93m警告: 未找到PM2正在安装...%ESC%[0m
npm install -g pm2
if !errorlevel! neq 0 (
echo %ESC%[91m错误: PM2安装失败%ESC%[0m
exit /b 1
)
echo %ESC%[92m✓ PM2安装完成%ESC%[0m
) else (
for /f %%i in ('pm2 -v') do set PM2_VERSION=%%i
echo %ESC%[92m✓ PM2版本: %PM2_VERSION%%ESC%[0m
)
goto :eof
:: 检查依赖
:check_dependencies
if not exist "node_modules" (
echo %ESC%[93m警告: 未找到node_modules目录正在安装依赖...%ESC%[0m
npm install
if !errorlevel! neq 0 (
echo %ESC%[91m错误: 依赖安装失败%ESC%[0m
exit /b 1
)
echo %ESC%[92m✓ 依赖安装完成%ESC%[0m
) else (
echo %ESC%[92m✓ 依赖已安装%ESC%[0m
)
goto :eof
:: 启动服务
:start_service
call :check_node
call :check_npm
call :check_pm2
call :check_dependencies
echo %ESC%[92m正在使用PM2启动结伴客后端服务...%ESC%[0m
pm2 start ecosystem.config.js --env production
if %errorlevel% equ 0 (
echo %ESC%[92m✓ 服务已通过PM2启动%ESC%[0m
echo %ESC%[92m✓ 执行 'pm2 list' 查看运行中的应用%ESC%[0m
echo %ESC%[92m✓ 执行 'pm2 logs' 查看应用日志%ESC%[0m
) else (
echo %ESC%[91m✗ 服务启动失败%ESC%[0m
exit /b 1
)
goto :eof
:: 停止服务
:stop_service
call :check_pm2
echo %ESC%[92m正在停止PM2管理的服务...%ESC%[0m
pm2 stop ecosystem.config.js
if %errorlevel% equ 0 (
echo %ESC%[92m✓ 服务已停止%ESC%[0m
) else (
echo %ESC%[93m可能没有正在运行的服务%ESC%[0m
)
goto :eof
:: 重启服务
:restart_service
call :check_pm2
echo %ESC%[92m正在重启PM2管理的服务...%ESC%[0m
:: 检查应用是否在运行,如果未运行则直接启动
call :is_app_running
if %errorlevel% neq 0 (
echo %ESC%[93m应用未在运行正在启动...%ESC%[0m
pm2 start ecosystem.config.js --env production
) else (
pm2 restart ecosystem.config.js --env production
)
if %errorlevel% equ 0 (
echo %ESC%[92m✓ 服务已重启%ESC%[0m
) else (
echo %ESC%[91m✗ 服务重启失败%ESC%[0m
exit /b 1
)
goto :eof
:: 删除应用
:delete_service
call :check_pm2
echo %ESC%[92m正在从PM2中删除应用...%ESC%[0m
:: 检查应用是否存在
call :is_app_running
if %errorlevel% neq 0 (
echo %ESC%[93m应用不存在或未在运行%ESC%[0m
goto :eof
)
pm2 delete ecosystem.config.js
if %errorlevel% equ 0 (
echo %ESC%[92m✓ 应用已从PM2中删除%ESC%[0m
) else (
echo %ESC%[93m删除应用时遇到问题%ESC%[0m
)
goto :eof
:: 查看服务状态
:status_service
call :check_pm2
echo %ESC%[92mPM2应用状态:%ESC%[0m
pm2 list
goto :eof
:: 列出所有应用
:list_service
call :check_pm2
echo %ESC%[92mPM2应用列表:%ESC%[0m
pm2 list
goto :eof
:: 查看日志
:logs_service
call :check_pm2
echo %ESC%[92m正在查看应用日志...%ESC%[0m
pm2 logs ecosystem.config.js
goto :eof

View File

@@ -1,236 +0,0 @@
#!/bin/bash
# 结伴客后端服务PM2启动脚本
# 使用PM2管理Node.js应用程序
# 设置颜色变量
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 显示脚本使用说明
show_usage() {
echo "用法: $0 [选项]"
echo "选项:"
echo " start 使用PM2启动后端服务"
echo " stop 停止PM2管理的后端服务"
echo " restart 重启PM2管理的后端服务"
echo " status 查看PM2服务状态"
echo " logs 查看PM2服务日志"
echo " delete 从PM2中删除应用"
echo " list 列出所有PM2应用"
echo " help 显示帮助信息"
}
# 检查是否安装了Node.js
check_node() {
if ! command -v node &> /dev/null; then
echo -e "${RED}错误: 未找到Node.js请先安装Node.js${NC}"
exit 1
fi
NODE_VERSION=$(node -v)
echo -e "${GREEN}✓ Node.js版本: ${NODE_VERSION}${NC}"
}
# 检查是否安装了npm
check_npm() {
if ! command -v npm &> /dev/null; then
echo -e "${RED}错误: 未找到npm请先安装npm${NC}"
exit 1
fi
NPM_VERSION=$(npm -v)
echo -e "${GREEN}✓ npm版本: ${NPM_VERSION}${NC}"
}
# 检查是否安装了PM2
check_pm2() {
if ! command -v pm2 &> /dev/null; then
echo -e "${YELLOW}警告: 未找到PM2正在安装...${NC}"
npm install -g pm2
if [ $? -ne 0 ]; then
echo -e "${RED}错误: PM2安装失败${NC}"
exit 1
fi
echo -e "${GREEN}✓ PM2安装完成${NC}"
else
PM2_VERSION=$(pm2 -v)
echo -e "${GREEN}✓ PM2版本: ${PM2_VERSION}${NC}"
fi
}
# 检查依赖是否已安装
check_dependencies() {
if [ ! -d "node_modules" ]; then
echo -e "${YELLOW}警告: 未找到node_modules目录正在安装依赖...${NC}"
npm install
if [ $? -ne 0 ]; then
echo -e "${RED}错误: 依赖安装失败${NC}"
exit 1
fi
echo -e "${GREEN}✓ 依赖安装完成${NC}"
else
echo -e "${GREEN}✓ 依赖已安装${NC}"
fi
}
# 检查应用是否已在PM2中运行
is_app_running() {
pm2 list | grep -q "jiebanke-backend"
return $?
}
# 启动服务
start_service() {
echo -e "${GREEN}正在使用PM2启动结伴客后端服务...${NC}"
# 检查应用是否已经在运行
if is_app_running; then
echo -e "${YELLOW}警告: 应用已在PM2中运行${NC}"
echo -e "${BLUE}提示: 使用 'pm2 restart jiebanke-backend' 重启应用${NC}"
echo -e "${BLUE}提示: 使用 'pm2 stop jiebanke-backend' 停止应用${NC}"
return 0
fi
# 使用PM2启动服务
pm2 start ecosystem.config.js --env production
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ 服务已通过PM2启动${NC}"
echo -e "${GREEN}✓ 执行 'pm2 list' 查看运行中的应用${NC}"
echo -e "${GREEN}✓ 执行 'pm2 logs' 查看应用日志${NC}"
else
echo -e "${RED}✗ 服务启动失败${NC}"
exit 1
fi
}
# 停止服务
stop_service() {
echo -e "${GREEN}正在停止PM2管理的服务...${NC}"
# 检查应用是否在运行
if ! is_app_running; then
echo -e "${YELLOW}应用未在运行${NC}"
return 0
fi
pm2 stop ecosystem.config.js
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ 服务已停止${NC}"
else
echo -e "${YELLOW}停止服务时遇到问题${NC}"
fi
}
# 重启服务
restart_service() {
echo -e "${GREEN}正在重启PM2管理的服务...${NC}"
# 检查应用是否在运行,如果未运行则直接启动
if ! is_app_running; then
echo -e "${YELLOW}应用未在运行,正在启动...${NC}"
pm2 start ecosystem.config.js --env production
else
pm2 restart ecosystem.config.js --env production
fi
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ 服务已重启${NC}"
else
echo -e "${RED}✗ 服务重启失败${NC}"
exit 1
fi
}
# 删除应用
delete_service() {
echo -e "${GREEN}正在从PM2中删除应用...${NC}"
# 检查应用是否存在
if ! is_app_running; then
echo -e "${YELLOW}应用不存在或未在运行${NC}"
return 0
fi
pm2 delete ecosystem.config.js
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ 应用已从PM2中删除${NC}"
else
echo -e "${YELLOW}删除应用时遇到问题${NC}"
fi
}
# 查看服务状态
status_service() {
echo -e "${GREEN}PM2应用状态:${NC}"
pm2 list
}
# 列出所有应用
list_service() {
echo -e "${GREEN}PM2应用列表:${NC}"
pm2 list
}
# 查看日志
logs_service() {
echo -e "${GREEN}正在查看应用日志...${NC}"
pm2 logs ecosystem.config.js
}
# 主逻辑
main() {
# 获取命令行参数
ACTION=${1:-"start"}
case "$ACTION" in
start)
check_node
check_npm
check_pm2
check_dependencies
start_service
;;
stop)
check_pm2
stop_service
;;
restart)
check_pm2
restart_service
;;
delete)
check_pm2
delete_service
;;
status)
check_pm2
status_service
;;
list)
check_pm2
list_service
;;
logs)
check_pm2
logs_service
;;
help)
show_usage
;;
*)
echo -e "${RED}未知选项: $ACTION${NC}"
show_usage
exit 1
;;
esac
}
# 执行主逻辑
main "$@"

View File

@@ -1,109 +0,0 @@
#!/bin/bash
# 结伴客后端文件同步脚本 - 同步到CentOS服务器
# 目标服务器: 使用命令行参数或环境变量指定
# 目标目录: /data/nodejs/jiebanke
# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 配置参数 - 可通过环境变量或命令行参数覆盖
LOCAL_DIR="$(pwd)"
REMOTE_USER=${REMOTE_USER:-"root"}
REMOTE_HOST=${REMOTE_HOST:-"www.jiebanke.com"}
REMOTE_DIR=${REMOTE_DIR:-"/data/nodejs/jiebanke"}
# 检查命令行参数
if [ $# -ge 1 ]; then
REMOTE_HOST=$1
fi
# 检查必需参数
if [ -z "$REMOTE_HOST" ]; then
echo -e "${RED}错误:未指定远程服务器地址!${NC}"
echo -e "${YELLOW}用法:$0 <remote_host> [remote_user]${NC}"
exit 1
fi
if [ $# -ge 2 ]; then
REMOTE_USER=$2
fi
# 检查本地目录是否存在
if [ ! -d "$LOCAL_DIR" ]; then
echo -e "${RED}错误:本地目录 $LOCAL_DIR 不存在!${NC}"
exit 1
fi
# 检查rsync是否安装
if ! command -v rsync &> /dev/null; then
echo -e "${RED}错误rsync未安装请先安装rsync。${NC}"
exit 1
fi
# 检查Node.js环境
if ! command -v node &> /dev/null; then
echo -e "${YELLOW}警告本地Node.js环境未安装但仍会继续同步文件...${NC}"
else
# 安装生产依赖
echo -e "${BLUE}安装生产依赖...${NC}"
npm install --production
if [ $? -ne 0 ]; then
echo -e "${RED}依赖安装失败!${NC}"
exit 1
fi
fi
# 确保.env文件存在
if [ ! -f ".env" ]; then
if [ -f ".env.example" ]; then
echo -e "${YELLOW}未找到.env文件正在从.env.example创建...${NC}"
cp .env.example .env
else
echo -e "${RED}错误:未找到.env和.env.example文件${NC}"
exit 1
fi
fi
# 使用rsync上传文件到服务器
echo -e "${BLUE}开始同步文件到远程服务器 ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}...${NC}"
# 创建排除列表
EXCLUDE_LIST=(
--exclude 'node_modules'
--exclude '.git'
--exclude '.gitignore'
--exclude '.env.example' # 不同步示例环境文件,保留服务器上的实际配置
--exclude 'logs'
--exclude 'uploads'
--exclude 'docker-compose.yml'
--exclude 'test-*.js'
--exclude 'README*.md'
)
# 执行同步
rsync -avz --progress --delete \
"${EXCLUDE_LIST[@]}" \
"$LOCAL_DIR/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/"
if [ $? -ne 0 ]; then
echo -e "${RED}文件同步失败!${NC}"
exit 1
fi
# 在服务器上创建必要的目录
echo -e "${BLUE}在远程服务器上创建必要的目录...${NC}"
ssh "$REMOTE_USER@$REMOTE_HOST" "mkdir -p $REMOTE_DIR/logs $REMOTE_DIR/uploads"
# 完成提示
echo -e "${GREEN}文件同步完成!${NC}"
# 提示如何在服务器上启动服务
echo -e "${YELLOW}请在服务器上执行以下命令以启动服务:${NC}"
echo -e " ssh $REMOTE_USER@$REMOTE_HOST"
echo -e " cd $REMOTE_DIR"
echo -e " ./start_server.sh"