2
This commit is contained in:
parent
7226255877
commit
a73736cd26
@ -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 () => {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 });
|
||||
|
||||
@ -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<void> {
|
||||
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
|
||||
};
|
||||
// 检查服务器是否已经存在
|
||||
const existingServer = await JimengServer.findOne({ server_id: this.serverId });
|
||||
|
||||
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}`);
|
||||
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<IJimengServer[]> {
|
||||
try {
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user