172 lines
6.5 KiB
JavaScript
172 lines
6.5 KiB
JavaScript
require('dotenv').config()
|
||
const app = require('./app')
|
||
const { testConnection } = require('./config/database')
|
||
const redisConfig = require('./config/redis')
|
||
const rabbitMQConfig = require('./config/rabbitmq')
|
||
|
||
const PORT = process.env.PORT || 3100
|
||
const HOST = process.env.HOST || '0.0.0.0'
|
||
|
||
// 显示启动横幅
|
||
console.log('========================================')
|
||
console.log('🚀 服务器启动中...')
|
||
console.log(`📅 时间: ${new Date().toISOString()}`)
|
||
console.log(`📌 版本: 1.0.0`)
|
||
console.log('========================================\n')
|
||
|
||
// 显示环境信息
|
||
console.log('🔍 环境配置:')
|
||
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`)
|
||
|
||
// 优雅关闭处理
|
||
process.on('uncaughtException', (err) => {
|
||
console.error('========================================')
|
||
console.error('❌ 未捕获的异常:')
|
||
console.error(`🔹 消息: ${err.message}`)
|
||
console.error(`🔹 堆栈: ${err.stack}`)
|
||
console.error('========================================')
|
||
process.exit(1)
|
||
})
|
||
|
||
process.on('unhandledRejection', (err) => {
|
||
console.error('========================================')
|
||
console.error('❌ 未处理的Promise拒绝:')
|
||
console.error(`🔹 消息: ${err.message}`)
|
||
console.error(`🔹 堆栈: ${err.stack}`)
|
||
console.error('========================================')
|
||
process.exit(1)
|
||
})
|
||
|
||
// 启动服务器
|
||
const startServer = async () => {
|
||
try {
|
||
console.log('\n========================================')
|
||
console.log('🔍 正在初始化服务...')
|
||
console.log('========================================\n')
|
||
|
||
console.log('🔍 测试数据库连接...')
|
||
// 测试数据库连接
|
||
await testConnection()
|
||
console.log('✅ 数据库连接测试成功')
|
||
console.log('📌 数据库连接池配置:', {
|
||
host: process.env.DB_HOST,
|
||
port: process.env.DB_PORT,
|
||
database: process.env.DB_NAME,
|
||
user: process.env.DB_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}`)
|
||
}
|
||
|
||
// 启动HTTP服务器
|
||
console.log('\n🔍 启动HTTP服务器...')
|
||
const server = app.listen(PORT, HOST, () => {
|
||
console.log('========================================')
|
||
console.log('✅ 服务器启动成功!')
|
||
console.log(`🚀 访问地址: http://${HOST}:${PORT}`)
|
||
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('========================================\n')
|
||
})
|
||
|
||
// 优雅关闭
|
||
const gracefulShutdown = async (signal) => {
|
||
console.log('\n========================================')
|
||
console.log(`🛑 收到 ${signal} 信号,开始优雅关闭流程...`)
|
||
console.log(`⏰ 时间: ${new Date().toLocaleString()}`)
|
||
console.log('========================================\n')
|
||
|
||
// 设置超时计时器
|
||
const shutdownTimer = setTimeout(() => {
|
||
console.error('========================================')
|
||
console.error('❌ 关闭操作超时,强制退出')
|
||
console.error('========================================')
|
||
process.exit(1)
|
||
}, 10000)
|
||
|
||
try {
|
||
// 关闭HTTP服务器
|
||
console.log('🔐 关闭HTTP服务器...')
|
||
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('========================================')
|
||
|
||
clearTimeout(shutdownTimer)
|
||
process.exit(0)
|
||
} catch (error) {
|
||
console.error('========================================')
|
||
console.error('❌ 关闭过程中发生错误:', error.message)
|
||
console.error('========================================')
|
||
clearTimeout(shutdownTimer)
|
||
process.exit(1)
|
||
}
|
||
}
|
||
|
||
// 注册关闭信号
|
||
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'))
|
||
process.on('SIGINT', () => gracefulShutdown('SIGINT'))
|
||
|
||
} catch (error) {
|
||
console.error('❌ 服务器启动失败:', error)
|
||
process.exit(1)
|
||
}
|
||
}
|
||
|
||
// 如果是直接运行此文件,则启动服务器
|
||
if (require.main === module) {
|
||
console.log('\n🔧 启动模式: 直接运行')
|
||
console.log(`📌 调用堆栈: ${new Error().stack.split('\n')[1].trim()}`)
|
||
console.log('🔄 开始启动服务器...\n')
|
||
startServer()
|
||
}
|
||
|
||
module.exports = app |