diff --git a/backend/config/env.js b/backend/config/env.js index 655b968..783655e 100644 --- a/backend/config/env.js +++ b/backend/config/env.js @@ -5,7 +5,7 @@ require('dotenv').config({ path: path.join(__dirname, '../../.env') }) const config = { // 开发环境 development: { - port: process.env.PORT || 3200, + port: process.env.PORT || 3110, mysql: { host: process.env.DB_HOST || 'nj-cdb-3pwh2kz1.sql.tencentcdb.com', port: process.env.DB_PORT || 20784, @@ -38,7 +38,7 @@ const config = { // 测试环境 test: { - port: process.env.PORT || 3200, + port: process.env.PORT || 3110, mysql: { host: process.env.DB_HOST || 'nj-cdb-3pwh2kz1.sql.tencentcdb.com', port: process.env.DB_PORT || 20784, @@ -62,7 +62,7 @@ const config = { // 生产环境 production: { - port: process.env.PORT || 3200, + port: process.env.PORT || 3110, mysql: { host: process.env.DB_HOST || 'nj-cdb-3pwh2kz1.sql.tencentcdb.com', port: process.env.DB_PORT || 20784, @@ -88,7 +88,7 @@ const config = { allowedTypes: ['image/jpeg', 'image/png', 'image/webp'] }, cors: { - origin: process.env.CORS_ORIGIN || 'https://your-domain.com', + origin: process.env.CORS_ORIGIN || 'https://www.jiebanke.com', credentials: true } } diff --git a/backend/scripts/init-test-data.js b/backend/scripts/init-test-data.js index b04479c..d6c1dce 100644 --- a/backend/scripts/init-test-data.js +++ b/backend/scripts/init-test-data.js @@ -9,16 +9,10 @@ const mysql = require('mysql2/promise'); const bcrypt = require('bcryptjs'); const config = require('../config/env'); -// 数据库配置 -const dbConfig = { - host: process.env.DB_HOST || 'mysql.jiebanke.com', - port: process.env.DB_PORT || 3306, - user: process.env.DB_USER || 'root', - password: process.env.DB_PASSWORD || '', - database: process.env.DB_NAME || 'jiebanke_dev', - charset: process.env.DB_CHARSET || 'utf8mb4', - timezone: process.env.DB_TIMEZONE || '+08:00' -}; +// 引入database.js配置 +const dbConfig = require('../src/config/database').pool.config; + +// 数据库配置已从database.js导入 // 测试数据 const testData = { diff --git a/backend/scripts/simple-server.js b/backend/scripts/simple-server.js new file mode 100644 index 0000000..0196cef --- /dev/null +++ b/backend/scripts/simple-server.js @@ -0,0 +1,37 @@ +// 简化版服务器入口文件 +require('dotenv').config(); +const express = require('express'); + +const app = express(); +const PORT = process.env.PORT || 3202; +const HOST = process.env.HOST || '0.0.0.0'; + +// 健康检查路由 +app.get('/health', (req, res) => { + res.json({ + status: 'ok', + timestamp: new Date().toISOString(), + version: '1.0.0', + noDbMode: process.env.NO_DB_MODE === 'true' + }); +}); + +// 根路由 +app.get('/', (req, res) => { + res.send('简化版服务器运行中...'); +}); + +// 启动服务器 +console.log(`🔍 准备启动服务器在 http://${HOST}:${PORT}`); +const server = app.listen(PORT, HOST, () => { + console.log(`✅ 服务器启动成功!`); + console.log(`🚀 访问地址: http://${HOST}:${PORT}`); + console.log(`🔍 NODE_ENV: ${process.env.NODE_ENV}`); + console.log(`🔍 NO_DB_MODE: ${process.env.NO_DB_MODE}`); +}); + +// 错误处理 +server.on('error', (error) => { + console.error('❌ 服务器启动错误:', error); + process.exit(1); +}); \ No newline at end of file diff --git a/backend/scripts/test-database-connection.js b/backend/scripts/test-database-connection.js index 7ddc924..ff62e69 100644 --- a/backend/scripts/test-database-connection.js +++ b/backend/scripts/test-database-connection.js @@ -8,17 +8,10 @@ const mysql = require('mysql2/promise'); const config = require('../config/env'); -// 数据库配置 - 使用环境变量,优先使用开发环境配置 -const dbConfig = { - host: process.env.DB_HOST || 'localhost', - port: process.env.DB_PORT || 3306, - user: process.env.DB_USER || 'root', - password: process.env.DB_PASSWORD || '', - database: process.env.DB_NAME || 'jiebanke_dev', - charset: process.env.DB_CHARSET || 'utf8mb4', - timezone: process.env.DB_TIMEZONE || '+08:00', - connectTimeout: 10000 -}; +// 引入database.js配置 +const dbConfig = require('../src/config/database').pool.config; + +// 数据库配置已从database.js导入 async function testDatabaseConnection() { let connection; @@ -80,9 +73,9 @@ async function testDatabaseConnection() { // 检查连接池配置 console.log('🔍 检查连接池配置...'); - console.log(`📈 连接池限制: ${config.mysql.connectionLimit || 10}`); - console.log(`🔤 字符集: ${config.mysql.charset}`); - console.log(`⏰ 时区: ${config.mysql.timezone}`); + console.log(`📈 连接池限制: ${dbConfig.connectionLimit || 10}`); + console.log(`🔤 字符集: ${dbConfig.charset}`); + console.log(`⏰ 时区: ${dbConfig.timezone}`); console.log('\n🎉 数据库连接测试完成!'); console.log('✅ 所有配置检查通过'); diff --git a/backend/scripts/test-dev-connection.js b/backend/scripts/test-dev-connection.js index 982db6f..a93a207 100644 --- a/backend/scripts/test-dev-connection.js +++ b/backend/scripts/test-dev-connection.js @@ -1,21 +1,17 @@ const mysql = require('mysql2/promise'); +// 引入database.js配置 +const dbConfig = require('../src/config/database').pool.config; + async function testDevConnection() { console.log('🧪 测试开发环境数据库连接...'); - - const dbConfig = { - host: '192.168.0.240', - port: 3306, - user: 'root', - password: 'aiotAiot123!', - database: 'jiebandata', - connectTimeout: 10000 - }; +// 使用从database.js导入的配置 + const config = dbConfig; try { - console.log('🔗 尝试连接到开发服务器:', dbConfig.host + ':' + dbConfig.port); + console.log('🔗 尝试连接到开发服务器:', config.host + ':' + config.port); - const connection = await mysql.createConnection(dbConfig); + const connection = await mysql.createConnection(config); console.log('✅ 开发环境连接成功!'); // 测试基本查询 @@ -24,10 +20,10 @@ async function testDevConnection() { // 检查表结构 const [tables] = await connection.execute(` - SELECT TABLE_NAME - FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_SCHEMA = 'jiebandata' - `); + SELECT TABLE_NAME + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = ? + `, [config.database]); console.log('📊 数据库中的表:', tables.map(t => t.TABLE_NAME).join(', ') || '暂无表'); diff --git a/backend/scripts/test-mysql-connection.js b/backend/scripts/test-mysql-connection.js new file mode 100644 index 0000000..3fccce1 --- /dev/null +++ b/backend/scripts/test-mysql-connection.js @@ -0,0 +1,89 @@ +import mysql from 'mysql2/promise'; +import 'dotenv/config'; + +// 引入database.js配置 +import dbConfig from '../src/config/database'; + +// 尝试多种连接配置 +async function testMySQLConnections() { + console.log('🔍 测试MySQL连接配置...\n'); + + // 使用database.js中的配置 + const config1 = { + host: dbConfig.pool.config.host, + port: dbConfig.pool.config.port, + user: dbConfig.pool.config.user, + password: dbConfig.pool.config.password, + database: dbConfig.pool.config.database, + connectTimeout: 5000 + }; + + // 配置2: 不指定数据库名称 + const config2 = { + ...config1, + database: undefined + }; + + const configurations = [ + { name: 'database.js配置', config: config1 }, + { name: 'database.js配置(无数据库)', config: config2 } + ]; + + for (const { name, config } of configurations) { + console.log(`\n🎯 尝试连接: ${name}`); + console.log(`📌 配置:`, { + host: config.host, + port: config.port, + user: config.user, + database: config.database || '不指定' + }); + + try { + const connection = await mysql.createConnection(config); + console.log('✅ 连接成功!'); + + // 测试简单查询 + const [rows] = await connection.execute('SELECT 1 as test'); + console.log('✅ 查询测试通过:', rows); + + // 如果指定了数据库,检查数据库是否存在 + if (config.database) { + const [dbCheck] = await connection.execute(`SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?`, [config.database]); + if (dbCheck.length > 0) { + console.log('✅ 数据库存在'); + } else { + console.warn('⚠️ 指定的数据库不存在'); + } + } + + await connection.end(); + return { success: true, config }; + + } catch (error) { + console.error('❌ 连接失败:', error.message); + console.error('🔍 错误代码:', error.code); + + if (error.code === 'ECONNREFUSED') { + console.error('💡 可能原因: MySQL服务器未启动或网络不可达'); + } else if (error.code === 'ER_ACCESS_DENIED_ERROR') { + console.error('💡 可能原因: 用户名或密码错误'); + } else if (error.code === 'ER_BAD_DB_ERROR') { + console.error('💡 可能原因: 数据库不存在'); + } + } + } + + console.log('\n❌ 所有连接配置都失败了'); + console.log('💡 建议:'); + console.log('1. 检查MySQL服务器是否已启动'); + console.log('2. 确认用户名和密码正确'); + console.log('3. 确认数据库已创建'); + console.log('4. 检查网络连接'); + + return { success: false }; +} + +// 执行测试 +testMySQLConnections().then(result => { + process.exit(result.success ? 0 : 1); +}); \ No newline at end of file diff --git a/backend/scripts/test-network.js b/backend/scripts/test-network.js index 2bdc31e..3610e09 100644 --- a/backend/scripts/test-network.js +++ b/backend/scripts/test-network.js @@ -1,21 +1,18 @@ const mysql = require('mysql2/promise'); +// 引入database.js配置 +const dbConfig = require('../src/config/database').pool.config; + async function testNetworkConnection() { console.log('🌐 测试网络连接性...'); - const dbConfig = { - host: '129.211.213.226', - port: 9527, - user: 'root', - password: 'Aiot123', - connectTimeout: 5000, - acquireTimeout: 5000 - }; + // 使用从database.js导入的配置 + const config = dbConfig; try { - console.log('🔗 尝试连接到:', dbConfig.host + ':' + dbConfig.port); + console.log('🔗 尝试连接到:', config.host + ':' + config.port); - const connection = await mysql.createConnection(dbConfig); + const connection = await mysql.createConnection(config); console.log('✅ 网络连接成功!'); await connection.end(); diff --git a/backend/scripts/test-server.js b/backend/scripts/test-server.js new file mode 100644 index 0000000..d35c711 --- /dev/null +++ b/backend/scripts/test-server.js @@ -0,0 +1,34 @@ +// 简单的服务器测试脚本 +import express from 'express'; + +const app = express(); +const PORT = 3201; +const HOST = '0.0.0.0'; + +// 基本路由 +app.get('/', (req, res) => { + res.send('服务器测试成功!'); +}); + +app.get('/health', (req, res) => { + res.json({ + status: 'ok', + timestamp: new Date().toISOString(), + version: '1.0.0' + }); +}); + +// 启动服务器 +const server = app.listen(PORT, HOST, () => { + console.log(`✅ 测试服务器启动成功!`); + console.log(`🚀 访问地址: http://${HOST}:${PORT}`); +}); + +// 处理退出信号 +process.on('SIGINT', () => { + console.log('🛑 收到退出信号,关闭测试服务器...'); + server.close(() => { + console.log('✅ 测试服务器已关闭'); + process.exit(0); + }); +}); \ No newline at end of file diff --git a/backend/src/app.js b/backend/src/app.js index a416797..444db6e 100644 --- a/backend/src/app.js +++ b/backend/src/app.js @@ -12,13 +12,23 @@ console.log('🔧 初始化Express应用...'); const { globalErrorHandler, notFound } = require('./utils/errors'); -// 路由导入 -const authRoutes = require('./routes/auth'); -const userRoutes = require('./routes/user'); -const travelRoutes = require('./routes/travel'); -const animalRoutes = require('./routes/animal'); -const orderRoutes = require('./routes/order'); -const adminRoutes = require('./routes/admin'); // 新增管理员路由 +// 检查是否为无数据库模式 +const NO_DB_MODE = process.env.NO_DB_MODE === 'true'; + +let authRoutes, userRoutes, travelRoutes, animalRoutes, orderRoutes, adminRoutes; + +// 路由导入 - 根据是否为无数据库模式决定是否导入实际路由 +if (NO_DB_MODE) { + console.log('⚠️ 无数据库模式:将使用模拟路由'); +} else { + // 路由导入 + authRoutes = require('./routes/auth'); + userRoutes = require('./routes/user'); + travelRoutes = require('./routes/travel'); + animalRoutes = require('./routes/animal'); + orderRoutes = require('./routes/order'); + adminRoutes = require('./routes/admin'); // 新增管理员路由 +} const app = express(); @@ -88,7 +98,8 @@ app.get('/health', (req, res) => { status: 'OK', timestamp: new Date().toISOString(), uptime: process.uptime(), - environment: process.env.NODE_ENV || 'development' + environment: process.env.NODE_ENV || 'development', + noDbMode: NO_DB_MODE }); }); @@ -103,20 +114,85 @@ app.get('/system-stats', (req, res) => { uptime: process.uptime(), cpuCount: require('os').cpus().length, platform: process.platform, - architecture: process.arch + architecture: process.arch, + noDbMode: NO_DB_MODE }; res.status(200).json(stats); }); -// API路由 -app.use('/api/v1/auth', authRoutes); -app.use('/api/v1/users', userRoutes); -app.use('/api/v1/travel', travelRoutes); -app.use('/api/v1/animals', animalRoutes); -app.use('/api/v1/orders', orderRoutes); -// 管理员路由 -app.use('/api/v1/admin', adminRoutes); +// 无数据库模式下的模拟路由 +if (NO_DB_MODE) { + // 认证路由 + app.use('/api/v1/auth', (req, res) => { + if (req.method === 'POST' && req.path === '/login') { + // 模拟登录响应 + res.status(200).json({ + success: true, + message: '模拟登录成功', + data: { + token: 'mock-jwt-token', + user: { + id: 1, + username: 'mockuser', + email: 'mock@example.com', + role: 'user' + } + } + }); + } else { + res.status(503).json({ + success: false, + message: '当前为无数据库模式,该功能不可用' + }); + } + }); + + // 其他路由的通用响应 + app.use('/api/v1/users', (req, res) => { + res.status(503).json({ + success: false, + message: '当前为无数据库模式,用户管理功能不可用' + }); + }); + + app.use('/api/v1/travel', (req, res) => { + res.status(503).json({ + success: false, + message: '当前为无数据库模式,旅行相关功能不可用' + }); + }); + + app.use('/api/v1/animals', (req, res) => { + res.status(503).json({ + success: false, + message: '当前为无数据库模式,动物相关功能不可用' + }); + }); + + app.use('/api/v1/orders', (req, res) => { + res.status(503).json({ + success: false, + message: '当前为无数据库模式,订单相关功能不可用' + }); + }); + + app.use('/api/v1/admin', (req, res) => { + res.status(503).json({ + success: false, + message: '当前为无数据库模式,管理员功能不可用' + }); + }); +} else { + // API路由 + app.use('/api/v1/auth', authRoutes); + app.use('/api/v1/users', userRoutes); + app.use('/api/v1/travel', travelRoutes); + app.use('/api/v1/animals', animalRoutes); + app.use('/api/v1/orders', orderRoutes); + // 管理员路由 + app.use('/api/v1/admin', adminRoutes); +} // 404处理 app.use('*', notFound); diff --git a/backend/src/config/database.js b/backend/src/config/database.js index 9e57a02..2b9f11c 100644 --- a/backend/src/config/database.js +++ b/backend/src/config/database.js @@ -1,16 +1,9 @@ const mysql = require('mysql2/promise'); const config = require('../../config/env'); -// 数据库配置 +// 数据库配置 - 使用env.js中的mysql配置 const dbConfig = { - host: process.env.DB_HOST || 'nj-cdb-3pwh2kz1.sql.tencentcdb.com', - port: process.env.DB_PORT || 20784, - user: process.env.DB_USER || 'jiebanke', - password: process.env.DB_PASSWORD || 'aiot741$12346', - database: process.env.DB_NAME || 'jbkdata', - connectionLimit: process.env.DB_CONNECTION_LIMIT || 10, - charset: process.env.DB_CHARSET || 'utf8mb4', - timezone: process.env.DB_TIMEZONE || '+08:00', + ...config.mysql, // 连接池配置 waitForConnections: true, queueLimit: 0, @@ -30,6 +23,22 @@ async function testConnection() { return true; } catch (error) { console.error('❌ MySQL数据库连接失败:', error.message); + console.error('🔍 错误代码:', error.code); + console.error('📌 数据库配置:', { + host: dbConfig.host, + port: dbConfig.port, + database: dbConfig.database, + user: dbConfig.user + }); + + if (error.code === 'ECONNREFUSED') { + console.error('💡 可能原因: MySQL服务器未启动或网络不可达'); + } else if (error.code === 'ER_ACCESS_DENIED_ERROR') { + console.error('💡 可能原因: 用户名或密码错误'); + } else if (error.code === 'ER_BAD_DB_ERROR') { + console.error('💡 可能原因: 数据库不存在'); + } + return false; } } diff --git a/backend/src/server.js b/backend/src/server.js index 45e217a..0524a0b 100644 --- a/backend/src/server.js +++ b/backend/src/server.js @@ -1,8 +1,6 @@ require('dotenv').config() const app = require('./app') -const { testConnection } = require('./config/database') -const redisConfig = require('./config/redis') -const rabbitMQConfig = require('./config/rabbitmq') +const { testConnection, pool } = require('./config/database') const PORT = process.env.PORT || 3200 const HOST = process.env.HOST || '0.0.0.0' @@ -20,8 +18,9 @@ console.log(`🔹 NODE_ENV: ${process.env.NODE_ENV || 'development'}`) console.log(`🔹 PORT: ${PORT}`) console.log(`🔹 HOST: ${HOST}`) console.log(`🔹 DATABASE_URL: ${process.env.DATABASE_URL ? '已配置' : '未配置'}`) -console.log(`🔹 REDIS_URL: ${process.env.REDIS_URL ? '已配置' : '未配置'}`) -console.log(`🔹 RABBITMQ_URL: ${process.env.RABBITMQ_URL ? '已配置' : '未配置'}\n`) +console.log(`🔹 使用生产环境MySQL数据库: 是`) +console.log(`🔹 使用Redis缓存: 否`) +console.log(`🔹 使用RabbitMQ消息队列: 否\n`) // 优雅关闭处理 process.on('uncaughtException', (err) => { @@ -51,41 +50,20 @@ const startServer = async () => { console.log('🔍 测试数据库连接...') // 测试数据库连接 - await testConnection() + const isConnected = await testConnection() + if (!isConnected) { + console.error('❌ 数据库连接测试失败,无法启动服务器') + process.exit(1) + } + console.log('✅ 数据库连接测试成功') console.log('📌 数据库连接池配置:', { - host: process.env.DB_HOST, - port: process.env.DB_PORT, - database: process.env.DB_NAME, - user: process.env.DB_USER + host: pool.config.host, + port: pool.config.port, + database: pool.config.database, + user: pool.config.user }) - - // 连接Redis(可选) - try { - console.log('\n🔍 初始化Redis连接...') - console.log(`📌 Redis配置: ${process.env.REDIS_URL || '使用默认配置'}`) - await redisConfig.connect() - console.log('✅ Redis连接成功') - const info = await redisConfig.getInfo() - console.log('📌 Redis服务器信息:', info.server) - console.log('📌 Redis内存信息:', info.memory) - } catch (error) { - console.warn('⚠️ Redis连接失败,继续以无缓存模式运行') - console.warn(`🔹 错误详情: ${error.message}`) - } - - // 连接RabbitMQ(可选) - try { - console.log('\n🔍 初始化RabbitMQ连接...') - console.log(`📌 RabbitMQ配置: ${process.env.RABBITMQ_URL || '使用默认配置'}`) - await rabbitMQConfig.connect() - console.log('✅ RabbitMQ连接成功') - const connInfo = rabbitMQConfig.getConnectionInfo() - console.log('📌 RabbitMQ连接信息:', connInfo) - } catch (error) { - console.warn('⚠️ RabbitMQ连接失败,继续以无消息队列模式运行') - console.warn(`🔹 错误详情: ${error.message}`) - } + console.log('🔄 所有数据库连接已统一使用database.js配置') // 启动HTTP服务器 console.log('\n🔍 启动HTTP服务器...') @@ -96,8 +74,8 @@ const startServer = async () => { console.log(`📊 环境: ${process.env.NODE_ENV || 'development'}`) console.log(`⏰ 启动时间: ${new Date().toLocaleString()}`) console.log('💾 数据库: MySQL') - console.log(`🔴 Redis: ${redisConfig.isConnected ? '已连接' : '未连接'}`) - console.log(`🐰 RabbitMQ: ${rabbitMQConfig.isConnected ? '已连接' : '未连接'}`) + console.log('🔴 Redis: 未使用') + console.log('🐰 RabbitMQ: 未使用') console.log('========================================\n') }) @@ -122,20 +100,6 @@ const startServer = async () => { await new Promise((resolve) => server.close(resolve)) console.log('✅ HTTP服务器已关闭') - // 关闭Redis连接 - if (redisConfig.isConnected()) { - console.log('🔐 关闭Redis连接...') - await redisConfig.disconnect() - console.log('✅ Redis连接已关闭') - } - - // 关闭RabbitMQ连接 - if (rabbitMQConfig.isConnected) { - console.log('🔐 关闭RabbitMQ连接...') - await rabbitMQConfig.close() - console.log('✅ RabbitMQ连接已关闭') - } - console.log('\n========================================') console.log('👋 服务器已完全关闭') console.log('========================================') diff --git a/backend/start-production.sh b/backend/start-production.sh new file mode 100755 index 0000000..a777964 --- /dev/null +++ b/backend/start-production.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# 结伴客后端生产环境启动脚本 +# 此脚本用于直接使用生产环境MySQL数据库,不使用Redis和RabbitMQ + +# 设置脚本执行时的选项:出错时退出,未定义变量时出错 +set -euo pipefail + +# 生产环境环境变量配置 +export NODE_ENV="production" +export PORT="3200" +export HOST="0.0.0.0" + +# MySQL数据库配置 - 生产环境 +# 请根据实际情况修改以下配置 +export DB_HOST="nj-cdb-3pwh2kz1.sql.tencentcdb.com" +export DB_PORT="20784" +export DB_NAME="jbkdata" +export DB_USER="jiebanke" +export DB_PASSWORD='aiot741$12346' + +export DATABASE_URL="mysql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}" + +# 禁用Redis缓存 +export USE_REDIS="false" +export REDIS_URL="" + +# 禁用RabbitMQ消息队列 +export USE_RABBITMQ="false" +export RABBITMQ_URL="" + +# 应用特定配置 +export JWT_SECRET="your-production-jwt-secret" +export JWT_EXPIRES_IN="30d" +export CRYPTO_SECRET="your-production-crypto-secret" + +# 上传文件配置 +export UPLOAD_DIR="./uploads" +export MAX_FILE_SIZE="10485760" # 10MB + +export ENABLE_SWAGGER="true" # 生产环境启用Swagger文档 +export NO_DB_MODE="false" # 必须使用数据库 + +# 显示启动信息 +echo "========================================" +echo "🚀 结伴客后端生产环境启动脚本" +echo "📅 时间: $(date)" +echo "========================================" +echo "" +echo "🔍 环境变量配置:" +echo "🔹 NODE_ENV: $NODE_ENV" +echo "🔹 PORT: $PORT" +echo "🔹 HOST: $HOST" +echo "🔹 DATABASE_URL: $(echo $DATABASE_URL | sed 's/:.*/:******@/')" +echo "🔹 USE_REDIS: $USE_REDIS" +echo "🔹 USE_RABBITMQ: $USE_RABBITMQ" +echo "🔹 NO_DB_MODE: $NO_DB_MODE" +echo "🔹 ENABLE_SWAGGER: $ENABLE_SWAGGER" +echo "" + +# 检查是否已安装依赖 +echo "🔍 检查依赖安装..." +if [ ! -d "node_modules" ]; then + echo "⚠️ 依赖未安装,开始安装..." + npm install --production + echo "✅ 依赖安装完成" +else + echo "✅ 依赖已安装" +fi + +echo "" +# 启动服务器 +echo "========================================" +echo "🚀 启动服务器..." +echo "========================================" + +# 使用node直接启动服务器(不使用PM2等进程管理器) +node src/server.js \ No newline at end of file diff --git a/backend/start-without-db.sh b/backend/start-without-db.sh new file mode 100755 index 0000000..3520a11 --- /dev/null +++ b/backend/start-without-db.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# 无数据库模式启动脚本 + +# 确保脚本可执行 +echo "🔧 正在准备无数据库模式启动..." + +# 设置NODE_ENV为development +export NODE_ENV=development + +# 设置NO_DB_MODE为true +export NO_DB_MODE=true + +# 启动服务器 +echo "🚀 以无数据库模式启动服务器..." +echo "⚠️ 注意:在无数据库模式下,许多功能将不可用" +echo "📝 查看 /health 和 /system-stats 端点获取服务器状态" +echo "📚 Swagger文档可在 /api-docs 访问" + +npm run dev \ No newline at end of file diff --git a/backend/start_backend_simple.sh b/backend/start_backend_simple.sh new file mode 100755 index 0000000..4442f9e --- /dev/null +++ b/backend/start_backend_simple.sh @@ -0,0 +1,155 @@ +#!/bin/bash + +# 结伴客后端服务简化启动脚本 +# 不依赖PM2,直接使用Node.js运行 + +# 设置颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 配置参数 +APP_DIR="$(pwd)" +NODE_ENV=${NODE_ENV:-"development"} +PORT=${PORT:-"3110"} # 使用3110端口 + +# 数据库配置 - 使用生产环境MySQL数据库 +DB_HOST="nj-cdb-3pwh2kz1.sql.tencentcdb.com" +DB_PORT="20784" +DB_USER="jiebanke" +DB_PASSWORD='aiot741$12346' +DB_NAME="jbkdata" +DATABASE_URL="mysql://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME" + +# 其他配置 +USE_REDIS="false" +USE_RABBITMQ="false" +ENABLE_SWAGGER="true" + +# 检查Node.js环境 +check_node() { + if ! command -v node &> /dev/null; then + echo -e "${RED}错误:Node.js环境未安装!${NC}" + exit 1 + fi + echo -e "${GREEN}Node.js版本: $(node -v)${NC}" +} + +# 检查npm环境 +check_npm() { + if ! command -v npm &> /dev/null; then + echo -e "${RED}错误:npm环境未安装!${NC}" + exit 1 + fi + echo -e "${GREEN}npm版本: $(npm -v)${NC}" +} + +# 安装依赖 +install_dependencies() { + echo -e "${BLUE}正在安装依赖...${NC}" + cd "$APP_DIR" + npm install + if [ $? -ne 0 ]; then + echo -e "${RED}依赖安装失败!${NC}" + exit 1 + fi + echo -e "${GREEN}依赖安装完成!${NC}" +} + +# 启动服务 +start_service() { + echo -e "${BLUE}正在启动结伴客后端服务...${NC}" + cd "$APP_DIR" + + # 设置环境变量 + export NODE_ENV=$NODE_ENV + export PORT=$PORT + export DB_HOST=$DB_HOST + export DB_PORT=$DB_PORT + export DB_USER=$DB_USER + export DB_PASSWORD=$DB_PASSWORD + export DB_NAME=$DB_NAME + export DATABASE_URL=$DATABASE_URL + export USE_REDIS=$USE_REDIS + export USE_RABBITMQ=$USE_RABBITMQ + export ENABLE_SWAGGER=$ENABLE_SWAGGER + + # 打印启动信息 + echo -e "${BLUE}启动配置:${NC}" + echo -e "${BLUE} NODE_ENV: $NODE_ENV${NC}" + echo -e "${BLUE} PORT: $PORT${NC}" + echo -e "${BLUE} DB_HOST: $DB_HOST${NC}" + echo -e "${BLUE} DB_PORT: $DB_PORT${NC}" + echo -e "${BLUE} DB_NAME: $DB_NAME${NC}" + echo -e "${BLUE} USE_REDIS: $USE_REDIS${NC}" + echo -e "${BLUE} USE_RABBITMQ: $USE_RABBITMQ${NC}" + echo -e "${BLUE} ENABLE_SWAGGER: $ENABLE_SWAGGER${NC}" + + # 使用node直接启动服务 + node src/server.js + + if [ $? -ne 0 ]; then + echo -e "${RED}服务启动失败!${NC}" + exit 1 + fi +} + +# 显示帮助信息 +show_help() { + echo "" + echo "结伴客后端服务简化启动脚本" + echo "" + echo "用法: $0 [命令] [环境]" + echo "" + echo "命令选项:" + echo " start - 启动服务(默认)" + echo " install - 仅安装依赖" + echo " help - 显示此帮助信息" + echo "" + echo "环境选项:" + echo " development - 开发环境(默认)" + echo " production - 生产环境" + echo " test - 测试环境" + echo "" +} + +# 主函数 +handle_command() { + # 解析命令和环境参数 + COMMAND="start" + if [ $# -ge 1 ]; then + case $1 in + start|install|help) COMMAND=$1 ;; + *) echo -e "${RED}未知命令:$1${NC}"; show_help; exit 1 ;; + esac + fi + + if [ $# -ge 2 ]; then + case $2 in + development|production|test) NODE_ENV=$2 ;; + *) echo -e "${RED}未知环境:$2${NC}"; show_help; exit 1 ;; + esac + fi + + # 执行相应的命令 + case $COMMAND in + start) + check_node + check_npm + start_service + ;; + install) + check_node + check_npm + install_dependencies + ;; + help) + show_help + ;; + esac +} + +# 执行主函数 +handle_command "$@" \ No newline at end of file diff --git a/backend/start_server.sh b/backend/start_server.sh deleted file mode 100755 index 2e22b68..0000000 --- a/backend/start_server.sh +++ /dev/null @@ -1,278 +0,0 @@ -#!/bin/bash - -# 结伴客后端服务启动脚本 - 在CentOS服务器上运行 -# 使用PM2管理Node.js应用 - -# 设置颜色输出 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# 配置参数 -APP_DIR="$(pwd)" -NODE_ENV=${NODE_ENV:-"production"} -PORT=${PORT:-"3200"} - -# 检查Node.js环境 -check_node() { - if ! command -v node &> /dev/null; then - echo -e "${RED}错误:Node.js环境未安装!${NC}" - echo -e "${YELLOW}请先安装Node.js: curl -sL https://rpm.nodesource.com/setup_16.x | sudo bash - && sudo yum install -y nodejs${NC}" - exit 1 - fi - echo -e "${GREEN}Node.js版本: $(node -v)${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 - fi - echo -e "${GREEN}PM2版本: $(pm2 -v)${NC}" -} - -# 检查环境变量文件 -check_env() { - if [ ! -f "$APP_DIR/.env" ]; then - echo -e "${RED}错误:未找到.env文件!${NC}" - echo -e "${YELLOW}请确保.env文件已正确配置,包含必要的数据库连接信息和其他配置。${NC}" - exit 1 - fi - echo -e "${GREEN}已找到.env文件${NC}" -} - -# 检查ecosystem.config.js文件 -check_ecosystem() { - if [ ! -f "$APP_DIR/ecosystem.config.js" ]; then - echo -e "${YELLOW}未找到ecosystem.config.js文件,正在创建默认配置...${NC}" - cat > "$APP_DIR/ecosystem.config.js" << EOF -module.exports = { - apps: [{ - name: 'jiebanke-backend', - script: './src/server.js', - instances: 'max', - exec_mode: 'cluster', - env: { - NODE_ENV: 'development', - PORT: $PORT, - WATCH: true - }, - env_production: { - NODE_ENV: 'production', - PORT: $PORT, - WATCH: false - }, - log_file: '$APP_DIR/logs/combined.log', - out_file: '$APP_DIR/logs/out.log', - error_file: '$APP_DIR/logs/error.log', - max_memory_restart: '1G', - kill_timeout: 3000, - wait_ready: true, - listen_timeout: 3000, - autorestart: true, - max_restarts: 10, - restart_delay: 4000, - ignore_watch: [ - 'node_modules', - 'logs', - '.git', - 'uploads' - ] - }] -}; -EOF - echo -e "${GREEN}ecosystem.config.js文件已创建${NC}" - fi -} - -# 安装依赖 -install_dependencies() { - echo -e "${BLUE}正在安装生产依赖...${NC}" - cd "$APP_DIR" - npm install --production - if [ $? -ne 0 ]; then - echo -e "${RED}依赖安装失败!${NC}" - exit 1 - fi - echo -e "${GREEN}依赖安装完成!${NC}" -} - -# 创建日志和上传目录 -create_directories() { - echo -e "${BLUE}正在创建必要的目录...${NC}" - mkdir -p "$APP_DIR/logs" "$APP_DIR/uploads" - chmod 755 "$APP_DIR/logs" "$APP_DIR/uploads" - echo -e "${GREEN}目录创建完成!${NC}" -} - -# 启动服务 -start_service() { - echo -e "${BLUE}正在使用PM2启动结伴客后端服务...${NC}" - cd "$APP_DIR" - - # 设置NODE_ENV环境变量 - export NODE_ENV=$NODE_ENV - - # 使用PM2启动应用 - pm2 start ecosystem.config.js --env $NODE_ENV - - if [ $? -ne 0 ]; then - echo -e "${RED}服务启动失败!${NC}" - exit 1 - fi - - echo -e "${GREEN}服务启动成功!${NC}" - echo -e "${BLUE}应用名称: jiebanke-backend${NC}" - echo -e "${BLUE}环境: $NODE_ENV${NC}" - echo -e "${BLUE}端口: $PORT${NC}" - echo -e "${YELLOW}提示:使用 pm2 logs jiebanke-backend 查看日志${NC}" - echo -e "${YELLOW}提示:使用 pm2 monit 监控应用状态${NC}" -} - -# 设置PM2开机自启 -setup_autostart() { - echo -e "${BLUE}正在配置PM2开机自启...${NC}" - pm2 startup - if [ $? -ne 0 ]; then - echo -e "${RED}PM2开机自启配置失败!${NC}" - else - pm2 save - echo -e "${GREEN}PM2开机自启配置完成!${NC}" - fi -} - -# 显示帮助信息 -show_help() { - echo "" - echo "结伴客后端服务管理脚本" - echo "" - echo "用法: $0 [命令] [环境]" - echo "" - echo "命令选项:" - echo " start - 启动服务(默认)" - echo " stop - 停止服务" - echo " restart - 重启服务" - echo " status - 查看服务状态" - echo " logs - 查看服务日志" - echo " install - 仅安装依赖" - echo " setup - 配置PM2开机自启" - echo " help - 显示此帮助信息" - echo "" - echo "环境选项:" - echo " production - 生产环境(默认)" - echo " development - 开发环境" - echo " test - 测试环境" - echo "" - echo "示例:" - echo " $0 start production # 在生产环境启动服务" - echo " $0 restart development # 在开发环境重启服务" - echo " $0 logs # 查看服务日志" - echo "" -} - -# 停止服务 -stop_service() { - echo -e "${BLUE}正在停止结伴客后端服务...${NC}" - pm2 stop jiebanke-backend - if [ $? -ne 0 ]; then - echo -e "${YELLOW}服务可能未在运行!${NC}" - else - echo -e "${GREEN}服务已停止!${NC}" - fi -} - -# 重启服务 -restart_service() { - echo -e "${BLUE}正在重启结伴客后端服务...${NC}" - export NODE_ENV=$NODE_ENV - pm2 restart ecosystem.config.js --env $NODE_ENV - if [ $? -ne 0 ]; then - echo -e "${RED}服务重启失败!${NC}" - exit 1 - fi - echo -e "${GREEN}服务重启成功!${NC}" -} - -# 查看服务状态 -status_service() { - echo -e "${BLUE}正在查看结伴客后端服务状态...${NC}" - pm2 status jiebanke-backend -} - -# 查看服务日志 -logs_service() { - echo -e "${BLUE}正在查看结伴客后端服务日志...${NC}" - pm2 logs jiebanke-backend -} - -# 主函数 -handle_command() { - # 解析命令和环境参数 - COMMAND="start" - if [ $# -ge 1 ]; then - case $1 in - start|stop|restart|status|logs|install|setup|help) COMMAND=$1 ;; - *) echo -e "${RED}未知命令:$1${NC}"; show_help; exit 1 ;; - esac - fi - - if [ $# -ge 2 ]; then - case $2 in - production|development|test) NODE_ENV=$2 ;; - *) echo -e "${RED}未知环境:$2${NC}"; show_help; exit 1 ;; - esac - fi - - # 执行相应的命令 - case $COMMAND in - start) - check_node - check_pm2 - check_env - check_ecosystem - install_dependencies - create_directories - start_service - ;; - stop) - check_pm2 - stop_service - ;; - restart) - check_node - check_pm2 - check_env - install_dependencies - restart_service - ;; - status) - check_pm2 - status_service - ;; - logs) - check_pm2 - logs_service - ;; - install) - check_node - install_dependencies - ;; - setup) - check_pm2 - setup_autostart - ;; - help) - show_help - ;; - esac -} - -# 执行主函数 -handle_command "$@" \ No newline at end of file diff --git a/backend/start_server.sh b/backend/start_server.sh new file mode 120000 index 0000000..9bdbf6d --- /dev/null +++ b/backend/start_server.sh @@ -0,0 +1 @@ +start_server.sh \ No newline at end of file