2
This commit is contained in:
parent
7226255877
commit
a73736cd26
@ -6,23 +6,6 @@ import logger from '@/lib/logger.ts';
|
|||||||
export default {
|
export default {
|
||||||
// 获取当前服务器信息
|
// 获取当前服务器信息
|
||||||
get: {
|
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 () => {
|
'/servers/active': async () => {
|
||||||
|
|||||||
@ -20,6 +20,8 @@ const startupTime = performance.now();
|
|||||||
logger.info("Process id:", process.pid);
|
logger.info("Process id:", process.pid);
|
||||||
logger.info("Environment:", environment.env);
|
logger.info("Environment:", environment.env);
|
||||||
logger.info("Service name:", config.service.name);
|
logger.info("Service name:", config.service.name);
|
||||||
|
logger.info("Service host:", config.service.host);
|
||||||
|
logger.info("Service port:", config.service.port);
|
||||||
|
|
||||||
// 初始化MongoDB连接
|
// 初始化MongoDB连接
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -70,7 +70,13 @@ export class ServiceConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static load() {
|
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);
|
if(!fs.pathExistsSync(CONFIG_PATH)) return new ServiceConfig(external);
|
||||||
const data = yaml.parse(fs.readFileSync(CONFIG_PATH).toString());
|
const data = yaml.parse(fs.readFileSync(CONFIG_PATH).toString());
|
||||||
return new ServiceConfig({ ...data, ...external });
|
return new ServiceConfig({ ...data, ...external });
|
||||||
|
|||||||
@ -11,7 +11,6 @@ export class HeartbeatService {
|
|||||||
private static instance: HeartbeatService;
|
private static instance: HeartbeatService;
|
||||||
private serverId: string;
|
private serverId: string;
|
||||||
private serverName: string;
|
private serverName: string;
|
||||||
private baseUrl: string;
|
|
||||||
private heartbeatTask: cron.ScheduledTask | null = null;
|
private heartbeatTask: cron.ScheduledTask | null = null;
|
||||||
private isRunning: boolean = false;
|
private isRunning: boolean = false;
|
||||||
|
|
||||||
@ -19,7 +18,6 @@ export class HeartbeatService {
|
|||||||
// 优先从环境变量获取配置,否则使用默认值
|
// 优先从环境变量获取配置,否则使用默认值
|
||||||
this.serverId = process.env.SERVICE_ID || config.service?.name || 'jimeng-free-api';
|
this.serverId = process.env.SERVICE_ID || config.service?.name || 'jimeng-free-api';
|
||||||
this.serverName = process.env.SERVICE_NAME || this.serverId;
|
this.serverName = process.env.SERVICE_NAME || this.serverId;
|
||||||
this.baseUrl = this.buildBaseUrl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getInstance(): HeartbeatService {
|
public static getInstance(): HeartbeatService {
|
||||||
@ -29,47 +27,6 @@ export class HeartbeatService {
|
|||||||
return HeartbeatService.instance;
|
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> {
|
public async start(): Promise<void> {
|
||||||
if (this.isRunning) {
|
if (this.isRunning) {
|
||||||
@ -140,26 +97,26 @@ export class HeartbeatService {
|
|||||||
try {
|
try {
|
||||||
const currentTime = Math.floor(Date.now() / 1000);
|
const currentTime = Math.floor(Date.now() / 1000);
|
||||||
|
|
||||||
const serverData = {
|
// 检查服务器是否已经存在
|
||||||
server_id: this.serverId,
|
const existingServer = await JimengServer.findOne({ server_id: this.serverId });
|
||||||
server_name: this.serverName,
|
|
||||||
base_url: this.baseUrl,
|
if (!existingServer) {
|
||||||
is_active: true,
|
logger.error(`服务器信息不存在 serverId: ${this.serverId}`);
|
||||||
last_heartbeat: currentTime,
|
// } else {
|
||||||
heartbeat_interval: parseInt(process.env.HEARTBEAT_INTERVAL || '60'),
|
// // 服务器已存在:只更新心跳相关字段,不修改 base_url
|
||||||
updated_at: currentTime
|
// await JimengServer.findOneAndUpdate(
|
||||||
};
|
// { server_id: this.serverId },
|
||||||
|
// {
|
||||||
await JimengServer.findOneAndUpdate(
|
// server_name: this.serverName, // 允许更新服务器名称
|
||||||
{ server_id: this.serverId },
|
// is_active: true,
|
||||||
{
|
// last_heartbeat: currentTime,
|
||||||
...serverData,
|
// heartbeat_interval: parseInt(process.env.HEARTBEAT_INTERVAL || '60'),
|
||||||
$setOnInsert: { created_at: currentTime }
|
// updated_at: currentTime
|
||||||
},
|
// // 注意:不更新 base_url,这由其他服务维护
|
||||||
{ upsert: true, new: true }
|
// }
|
||||||
);
|
// );
|
||||||
|
// logger.info(`Server re-registered: ${this.serverId} (base_url preserved)`);
|
||||||
logger.info(`Server registered: ${this.serverId} at ${this.baseUrl}`);
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Failed to register server:', error);
|
logger.error('Failed to register server:', error);
|
||||||
@ -171,16 +128,17 @@ export class HeartbeatService {
|
|||||||
try {
|
try {
|
||||||
const currentTime = Math.floor(Date.now() / 1000);
|
const currentTime = Math.floor(Date.now() / 1000);
|
||||||
|
|
||||||
|
// 只更新心跳相关字段,不修改 base_url 等其他服务信息
|
||||||
await JimengServer.findOneAndUpdate(
|
await JimengServer.findOneAndUpdate(
|
||||||
{ server_id: this.serverId },
|
{ server_id: this.serverId },
|
||||||
{
|
{
|
||||||
last_heartbeat: currentTime,
|
last_heartbeat: currentTime, // 更新最后心跳时间
|
||||||
updated_at: currentTime,
|
updated_at: currentTime, // 更新记录修改时间
|
||||||
is_active: true
|
// is_active: true // 标记为活跃状态
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
logger.debug(`Heartbeat sent for server ${this.serverId}`);
|
// logger.debug(`Heartbeat sent for server ${this.serverId}`);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Failed to send heartbeat:', error);
|
logger.error('Failed to send heartbeat:', error);
|
||||||
@ -212,15 +170,6 @@ export class HeartbeatService {
|
|||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getServerInfo() {
|
|
||||||
return {
|
|
||||||
serverId: this.serverId,
|
|
||||||
serverName: this.serverName,
|
|
||||||
baseUrl: this.baseUrl,
|
|
||||||
isRunning: this.isRunning
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取所有活跃服务器
|
// 获取所有活跃服务器
|
||||||
public static async getActiveServers(): Promise<IJimengServer[]> {
|
public static async getActiveServers(): Promise<IJimengServer[]> {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -14,6 +14,8 @@ services:
|
|||||||
- SERVICE_ID=${SERVICE_ID:-jimeng-free-api}
|
- SERVICE_ID=${SERVICE_ID:-jimeng-free-api}
|
||||||
- INSTANCE_ID=${INSTANCE_ID:-instance-1}
|
- INSTANCE_ID=${INSTANCE_ID:-instance-1}
|
||||||
- SERVICE_NAME=${SERVICE_NAME:-jimeng-free-api}
|
- 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}
|
- MONGODB_URL=${MONGODB_URL:-mongodb://localhost:27017/jimeng-api}
|
||||||
- TOS_ACCESS_KEY_ID=${TOS_ACCESS_KEY_ID}
|
- TOS_ACCESS_KEY_ID=${TOS_ACCESS_KEY_ID}
|
||||||
- TOS_ACCESS_KEY_SECRET=${TOS_ACCESS_KEY_SECRET}
|
- TOS_ACCESS_KEY_SECRET=${TOS_ACCESS_KEY_SECRET}
|
||||||
@ -30,11 +32,11 @@ services:
|
|||||||
- VIDEO_TASK_TIMEOUT=${VIDEO_TASK_TIMEOUT:-86400}
|
- VIDEO_TASK_TIMEOUT=${VIDEO_TASK_TIMEOUT:-86400}
|
||||||
- RESULT_EXPIRE_TIME=${RESULT_EXPIRE_TIME:-86400}
|
- RESULT_EXPIRE_TIME=${RESULT_EXPIRE_TIME:-86400}
|
||||||
ports:
|
ports:
|
||||||
- "${API_PORT:-3302}:3302"
|
- "${API_PORT:-3302}:${API_PORT:-3302}"
|
||||||
volumes:
|
volumes:
|
||||||
- ./logs:/app/logs
|
- ./logs:/app/logs
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:3302/ping"]
|
test: ["CMD", "curl", "-f", "http://localhost:${API_PORT:-3302}/ping"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user