#!/usr/bin/env tsx /** * 生产环境完整交易系统启动器 * Production Complete Trading System Launcher * * 基于 main-complete.ts 的生产级部署版本 */ import { CompleteTradingSystem } from './src/main-complete.js' import { ProductionLogger } from './src/utils/ProductionLogger.js' import * as fs from 'fs' import * as http from 'http' class ProductionSystemRunner { private system?: CompleteTradingSystem private logger: ProductionLogger private isShuttingDown = false private healthCheckServer?: http.Server private systemStartTime = Date.now() constructor() { this.logger = ProductionLogger.getInstance({ level: (process.env.LOG_LEVEL as any) || 'info', enableFile: true, logDir: process.env.LOG_DIR || './logs', enableConsole: true, enableAudit: true, }) } async start() { this.displayBanner() this.setupSignalHandlers() this.startHealthCheck() this.logger.info('🚀 启动生产级交易系统', { nodeEnv: process.env.NODE_ENV, pid: process.pid, memory: process.memoryUsage(), version: '1.0.0', }) try { // 环境检查 this.performEnvironmentCheck() // 创建并启动完整交易系统 this.system = new CompleteTradingSystem() // 绑定生产环境监听器 this.setupProductionEventHandlers() // 启动系统 await this.system.start() this.logger.info('✅ 生产系统启动成功', { healthCheckUrl: 'http://localhost:3001/health', uptime: Date.now() - this.systemStartTime, }) console.log(` ✅ 🚀 生产级交易系统已启动! 📊 监控地址: - 健康检查: http://localhost:3001/health - 系统状态: http://localhost:3001/status - 性能指标: http://localhost:3001/metrics 🔧 管理命令: - curl http://localhost:3001/health # 检查系统健康 - kill -TERM ${process.pid} # 优雅关闭 - kill -USR1 ${process.pid} # 重载配置 📁 日志位置: ${process.env.LOG_DIR || './logs'} `) // PM2 兼容性 if (process.send) { process.send('ready') } // 保持运行并启动监控 this.startSystemMonitoring() } catch (error: any) { this.logger.critical('❌ 生产系统启动失败', error) console.error('❌ 生产系统启动失败:', error.message) process.exit(1) } } private displayBanner() { console.log(` ██████ ██████ ██████ ██████ ██ ██ ██████ ████████ ██ ██████ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██████ ██████ ██████ ██████ ██ ██ ██████ ██ ████ 🌟 生产级完整交易系统 v1.0.0 🔥 多平台对冲 | 实时监控 | 自动化交易 | 风险控制 启动时间: ${new Date().toLocaleString('zh-CN')} 进程 ID: ${process.pid} Node.js: ${process.version} 内存: ${Math.round(process.memoryUsage().rss / 1024 / 1024)}MB `) } private performEnvironmentCheck() { const required = ['NODE_ENV'] const missing = required.filter(env => !process.env[env]) if (missing.length > 0) { this.logger.warn('⚠️ 缺少环境变量', { missingVars: missing }) } // 检查日志目录 const logDir = process.env.LOG_DIR || './logs' if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }) this.logger.info('📁 创建日志目录', { logDir }) } this.logger.info('✅ 环境检查完成', { nodeEnv: process.env.NODE_ENV, logDir, }) } private startHealthCheck() { this.healthCheckServer = http.createServer((req, res) => { const url = req.url || '' // CORS 支持 res.setHeader('Access-Control-Allow-Origin', '*') res.setHeader('Content-Type', 'application/json') if (url === '/health') { const health = { status: 'healthy', timestamp: new Date().toISOString(), uptime: process.uptime(), memory: process.memoryUsage(), pid: process.pid, system: this.system ? 'running' : 'starting', version: '1.0.0', } res.writeHead(200) res.end(JSON.stringify(health, null, 2)) } else if (url === '/status' && this.system) { try { const stats = this.system.getSystemStats() res.writeHead(200) res.end(JSON.stringify(stats, null, 2)) } catch (error: any) { res.writeHead(500) res.end(JSON.stringify({ error: error.message })) } } else if (url === '/metrics') { const metrics = { timestamp: new Date().toISOString(), uptime: process.uptime(), memory: process.memoryUsage(), cpu: process.cpuUsage(), startTime: this.systemStartTime, systemActive: !!this.system, } res.writeHead(200) res.end(JSON.stringify(metrics, null, 2)) } else { res.writeHead(404) res.end(JSON.stringify({ error: 'Not Found' })) } }) this.healthCheckServer.listen(3001, () => { console.log('🏥 健康检查服务器已启动: http://localhost:3001/health') }) this.healthCheckServer.on('error', (error: any) => { this.logger.error('健康检查服务器错误', error) }) } private setupProductionEventHandlers() { if (!this.system) return // 系统级事件 this.system.on('error', (error: Error) => { this.logger.error('🚨 系统错误', error) if (error.message.includes('FATAL')) { this.logger.critical('💀 致命错误,准备重启', error) this.attemptSystemRestart() } }) this.system.on('warning', (warning: string) => { this.logger.warn(`⚠️ 系统警告: ${warning}`) }) // 交易事件 this.system.on('trade_executed', (data: any) => { this.logger.trade('订单执行', { exchange: data.exchange, symbol: data.symbol, side: data.side, quantity: data.quantity, price: data.price, orderId: data.orderId, }) }) // 对冲事件 this.system.on('hedge_executed', (data: any) => { this.logger.hedge('对冲执行', { sourceExchange: data.sourceExchange, targetExchange: data.targetExchange, symbol: data.symbol, quantity: data.quantity, reason: data.reason, }) }) } private startSystemMonitoring() { // 心跳检查 (每分钟) const heartbeatInterval = setInterval(async () => { if (this.isShuttingDown) { clearInterval(heartbeatInterval) return } try { if (this.system) { const stats = await this.system.getSystemStats() this.logger.info('💓 系统心跳', { accounts: stats.accounts.total, connections: stats.connections.active, dailyTrades: stats.trading.dailyTrades, uptime: Math.round(process.uptime()), }) } } catch (error: any) { this.logger.warn(`心跳检查失败: ${error.message}`) } }, 60000) // 内存监控 (每30秒) const memoryInterval = setInterval(() => { if (this.isShuttingDown) { clearInterval(memoryInterval) return } const usage = process.memoryUsage() const memoryMB = Math.round(usage.rss / 1024 / 1024) this.logger.performance('内存使用', memoryMB, { heap: Math.round(usage.heapUsed / 1024 / 1024), external: Math.round(usage.external / 1024 / 1024), }) // 内存警告 if (memoryMB > 500) { this.logger.warn(`⚠️ 内存使用过高: ${memoryMB}MB`) } // 内存泄漏检测 if (memoryMB > 1000) { this.logger.critical(`🚨 内存可能泄漏: ${memoryMB}MB`) } }, 30000) } private setupSignalHandlers() { // 优雅关闭信号 ;['SIGTERM', 'SIGINT'].forEach(signal => { process.on(signal, () => { console.log(`\n🛑 收到 ${signal} 信号,开始优雅关闭...`) this.gracefulShutdown() }) }) // 重载配置信号 (生产环境热更新) process.on('SIGUSR1', () => { this.logger.info('🔄 收到重载配置信号') this.reloadConfiguration() }) // 错误处理 process.on('uncaughtException', error => { this.logger.critical('💥 未捕获异常', error) console.error('💥 未捕获异常:', error) this.gracefulShutdown() }) process.on('unhandledRejection', reason => { this.logger.critical('💥 未处理的Promise拒绝', undefined, { reason }) console.error('💥 未处理的Promise拒绝:', reason) }) } private async attemptSystemRestart() { this.logger.info('🔄 尝试系统自动恢复...') try { if (this.system) { await this.system.shutdown() this.system = undefined } // 等待5秒 await new Promise(resolve => setTimeout(resolve, 5000)) // 重新创建系统 this.system = new CompleteTradingSystem() this.setupProductionEventHandlers() await this.system.start() this.logger.info('✅ 系统自动恢复成功') } catch (error: any) { this.logger.critical('❌ 系统自动恢复失败', error) process.exit(1) } } private async reloadConfiguration() { try { this.logger.info('🔧 开始重载配置...') // 这里可以实现配置热更新逻辑 // 例如重新读取环境变量、配置文件等 this.logger.info('✅ 配置重载完成') } catch (error: any) { this.logger.error('❌ 配置重载失败', error) } } private async gracefulShutdown() { if (this.isShuttingDown) return this.isShuttingDown = true const shutdownStart = Date.now() try { this.logger.info('🛑 开始优雅关闭系统...') // 1. 停止接受新请求 if (this.healthCheckServer) { this.healthCheckServer.close() this.logger.info('✅ 健康检查服务器已关闭') } // 2. 关闭交易系统 if (this.system) { await this.system.shutdown() this.logger.info('✅ 交易系统已关闭') } // 3. 等待现有操作完成 (最多30秒) const maxWait = 30000 const remaining = maxWait - (Date.now() - shutdownStart) if (remaining > 0) { this.logger.info(`⏱️ 等待现有操作完成... (最多${remaining}ms)`) await new Promise(resolve => setTimeout(resolve, Math.min(remaining, 5000))) } const shutdownTime = Date.now() - shutdownStart this.logger.info(`✅ 系统优雅关闭完成 (用时${shutdownTime}ms)`) // 关闭日志系统 this.logger.close() process.exit(0) } catch (error: any) { this.logger.critical('❌ 优雅关闭失败', error) console.error('❌ 优雅关闭失败:', error) process.exit(1) } } } // 启动生产系统 if (import.meta.url === `file://${process.argv[1]}`) { // 设置默认环境变量 process.env.NODE_ENV = process.env.NODE_ENV || 'production' const runner = new ProductionSystemRunner() runner.start().catch(error => { console.error('❌ 系统启动失败:', error) process.exit(1) }) } export { ProductionSystemRunner }