diff --git a/src/api/routes/services.ts b/src/api/routes/services.ts index b5dd0c2..4e11a39 100644 --- a/src/api/routes/services.ts +++ b/src/api/routes/services.ts @@ -6,23 +6,6 @@ import logger from '@/lib/logger.ts'; export default { // 获取当前服务器信息 get: { - '/servers/current': async () => { - try { - const heartbeatService = HeartbeatService.getInstance(); - const serverInfo = heartbeatService.getServerInfo(); - - return new Response({ - success: true, - data: serverInfo - }); - } catch (error) { - logger.error('Failed to get current server info:', error); - return new Response({ - success: false, - error: error.message - }, { statusCode: 500 }); - } - }, // 获取所有活跃服务器 '/servers/active': async () => { diff --git a/src/index.ts b/src/index.ts index 92a2e25..71e9cb0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,6 +20,8 @@ const startupTime = performance.now(); logger.info("Process id:", process.pid); logger.info("Environment:", environment.env); logger.info("Service name:", config.service.name); + logger.info("Service host:", config.service.host); + logger.info("Service port:", config.service.port); // 初始化MongoDB连接 try { diff --git a/src/lib/configs/service-config.ts b/src/lib/configs/service-config.ts index 7c45bf2..e2e77b1 100644 --- a/src/lib/configs/service-config.ts +++ b/src/lib/configs/service-config.ts @@ -70,7 +70,13 @@ export class ServiceConfig { } static load() { - const external = _.pickBy(environment, (v, k) => ["name", "host", "port"].includes(k) && !_.isUndefined(v)); + // 从环境变量获取配置,支持 PM2 和其他方式设置的环境变量 + const external = _.pickBy({ + name: environment.name, + host: environment.host, + port: environment.port || (process.env.PORT ? Number(process.env.PORT) : undefined) // 支持 PM2 的 PORT 环境变量 + }, (v, k) => !_.isUndefined(v)); + if(!fs.pathExistsSync(CONFIG_PATH)) return new ServiceConfig(external); const data = yaml.parse(fs.readFileSync(CONFIG_PATH).toString()); return new ServiceConfig({ ...data, ...external }); diff --git a/src/lib/services/HeartbeatService.ts b/src/lib/services/HeartbeatService.ts index 5e16220..e0ef2ca 100644 --- a/src/lib/services/HeartbeatService.ts +++ b/src/lib/services/HeartbeatService.ts @@ -11,7 +11,6 @@ export class HeartbeatService { private static instance: HeartbeatService; private serverId: string; private serverName: string; - private baseUrl: string; private heartbeatTask: cron.ScheduledTask | null = null; private isRunning: boolean = false; @@ -19,7 +18,6 @@ export class HeartbeatService { // 优先从环境变量获取配置,否则使用默认值 this.serverId = process.env.SERVICE_ID || config.service?.name || 'jimeng-free-api'; this.serverName = process.env.SERVICE_NAME || this.serverId; - this.baseUrl = this.buildBaseUrl(); } public static getInstance(): HeartbeatService { @@ -29,47 +27,6 @@ export class HeartbeatService { return HeartbeatService.instance; } - private buildBaseUrl(): string { - const host = process.env.HOST || config.service?.host || '0.0.0.0'; - const port = process.env.PORT || config.service?.port || 3302; - - // 如果明确指定了 BASE_URL,直接使用 - if (process.env.BASE_URL) { - return process.env.BASE_URL; - } - - // 如果是 Docker 环境,使用容器名称 - if (process.env.NODE_ENV === 'production' && process.env.CONTAINER_NAME) { - return `http://${process.env.CONTAINER_NAME}:${port}`; - } - - // PM2 环境或Node.js直接启动环境 - let targetHost = host; - if (host === '0.0.0.0') { - // 尝试获取本机的实际IP地址 - targetHost = this.getLocalIP() || 'localhost'; - } - - return `http://${targetHost}:${port}`; - } - - private getLocalIP(): string | null { - try { - const interfaces = os.networkInterfaces(); - - // 优先查找非回环的IPv4地址 - for (const name of Object.keys(interfaces)) { - for (const iface of interfaces[name]) { - if (iface.family === 'IPv4' && !iface.internal) { - return iface.address; - } - } - } - } catch (error) { - logger.warn('Failed to get local IP:', error.message); - } - return null; - } public async start(): Promise { if (this.isRunning) { @@ -140,26 +97,26 @@ export class HeartbeatService { try { const currentTime = Math.floor(Date.now() / 1000); - const serverData = { - server_id: this.serverId, - server_name: this.serverName, - base_url: this.baseUrl, - is_active: true, - last_heartbeat: currentTime, - heartbeat_interval: parseInt(process.env.HEARTBEAT_INTERVAL || '60'), - updated_at: currentTime - }; - - await JimengServer.findOneAndUpdate( - { server_id: this.serverId }, - { - ...serverData, - $setOnInsert: { created_at: currentTime } - }, - { upsert: true, new: true } - ); - - logger.info(`Server registered: ${this.serverId} at ${this.baseUrl}`); + // 检查服务器是否已经存在 + const existingServer = await JimengServer.findOne({ server_id: this.serverId }); + + if (!existingServer) { + logger.error(`服务器信息不存在 serverId: ${this.serverId}`); + // } else { + // // 服务器已存在:只更新心跳相关字段,不修改 base_url + // await JimengServer.findOneAndUpdate( + // { server_id: this.serverId }, + // { + // server_name: this.serverName, // 允许更新服务器名称 + // is_active: true, + // last_heartbeat: currentTime, + // heartbeat_interval: parseInt(process.env.HEARTBEAT_INTERVAL || '60'), + // updated_at: currentTime + // // 注意:不更新 base_url,这由其他服务维护 + // } + // ); + // logger.info(`Server re-registered: ${this.serverId} (base_url preserved)`); + } } catch (error) { logger.error('Failed to register server:', error); @@ -171,16 +128,17 @@ export class HeartbeatService { try { const currentTime = Math.floor(Date.now() / 1000); + // 只更新心跳相关字段,不修改 base_url 等其他服务信息 await JimengServer.findOneAndUpdate( { server_id: this.serverId }, { - last_heartbeat: currentTime, - updated_at: currentTime, - is_active: true + last_heartbeat: currentTime, // 更新最后心跳时间 + updated_at: currentTime, // 更新记录修改时间 + // is_active: true // 标记为活跃状态 } ); - logger.debug(`Heartbeat sent for server ${this.serverId}`); + // logger.debug(`Heartbeat sent for server ${this.serverId}`); } catch (error) { logger.error('Failed to send heartbeat:', error); @@ -212,15 +170,6 @@ export class HeartbeatService { process.exit(0); } - public getServerInfo() { - return { - serverId: this.serverId, - serverName: this.serverName, - baseUrl: this.baseUrl, - isRunning: this.isRunning - }; - } - // 获取所有活跃服务器 public static async getActiveServers(): Promise { try { diff --git a/template.docker-compose.yml b/template.docker-compose.yml index 76fe12f..f8bb2b0 100644 --- a/template.docker-compose.yml +++ b/template.docker-compose.yml @@ -14,6 +14,8 @@ services: - SERVICE_ID=${SERVICE_ID:-jimeng-free-api} - INSTANCE_ID=${INSTANCE_ID:-instance-1} - SERVICE_NAME=${SERVICE_NAME:-jimeng-free-api} + - HOST=${HOST:-0.0.0.0} + - PORT=${API_PORT:-3302} - MONGODB_URL=${MONGODB_URL:-mongodb://localhost:27017/jimeng-api} - TOS_ACCESS_KEY_ID=${TOS_ACCESS_KEY_ID} - TOS_ACCESS_KEY_SECRET=${TOS_ACCESS_KEY_SECRET} @@ -30,11 +32,11 @@ services: - VIDEO_TASK_TIMEOUT=${VIDEO_TASK_TIMEOUT:-86400} - RESULT_EXPIRE_TIME=${RESULT_EXPIRE_TIME:-86400} ports: - - "${API_PORT:-3302}:3302" + - "${API_PORT:-3302}:${API_PORT:-3302}" volumes: - ./logs:/app/logs healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3302/ping"] + test: ["CMD", "curl", "-f", "http://localhost:${API_PORT:-3302}/ping"] interval: 30s timeout: 10s retries: 3