更新PM2配置并添加相关脚本
This commit is contained in:
@@ -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']
|
||||
|
||||
@@ -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
|
||||
},
|
||||
// 日志配置
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
91
backend/scripts/start-server.sh
Normal file
91
backend/scripts/start-server.sh
Normal 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"
|
||||
65
backend/scripts/sync-to-server.ps1
Normal file
65
backend/scripts/sync-to-server.ps1
Normal 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
|
||||
}
|
||||
58
backend/scripts/sync-to-server.sh
Normal file
58
backend/scripts/sync-to-server.sh
Normal 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"
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -1 +0,0 @@
|
||||
start-server.sh
|
||||
@@ -1 +0,0 @@
|
||||
start-server.sh
|
||||
@@ -1 +0,0 @@
|
||||
start-server.sh
|
||||
@@ -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
|
||||
@@ -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 "$@"
|
||||
@@ -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"
|
||||
Reference in New Issue
Block a user