修复重启没应用代理问题
This commit is contained in:
+38
-1
@@ -1,14 +1,51 @@
|
|||||||
const { defaultLogger } = require('./utils/logger');
|
const { defaultLogger } = require('./utils/logger');
|
||||||
|
const Fse = require('fs-extra');
|
||||||
|
const Path = require('path');
|
||||||
|
|
||||||
// 创建logger实例
|
// 创建logger实例
|
||||||
const logger = defaultLogger.child('ProxyConfig');
|
const logger = defaultLogger.child('ProxyConfig');
|
||||||
|
|
||||||
|
// 配置文件路径
|
||||||
|
const CONFIG_FILE_DIR = require('appdata-path').getAppDataPath('pmanager');
|
||||||
|
const CONFIG_FILE = Path.resolve(CONFIG_FILE_DIR, 'config.json');
|
||||||
|
|
||||||
|
// 读取用户配置中的代理设置
|
||||||
|
function getUserProxyConfig() {
|
||||||
|
try {
|
||||||
|
if (Fse.existsSync(CONFIG_FILE)) {
|
||||||
|
const config = Fse.readJsonSync(CONFIG_FILE);
|
||||||
|
if (config.proxy) {
|
||||||
|
// 解析代理URL获取端口
|
||||||
|
const proxyUrl = config.proxy;
|
||||||
|
const match = proxyUrl.match(/http:\/\/127\.0\.0\.1:(\d+)/);
|
||||||
|
if (match) {
|
||||||
|
return parseInt(match[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.debug('读取用户代理配置失败:', error.message);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// 代理配置
|
// 代理配置
|
||||||
const proxyConfig = {
|
const proxyConfig = {
|
||||||
// 系统代理配置
|
// 系统代理配置
|
||||||
system: {
|
system: {
|
||||||
host: '127.0.0.1',
|
host: '127.0.0.1',
|
||||||
port: process.env.PROXY_PORT ? parseInt(process.env.PROXY_PORT) : 7890,
|
port: (() => {
|
||||||
|
// 优先级:环境变量 > 用户配置 > 默认值
|
||||||
|
if (process.env.PROXY_PORT) {
|
||||||
|
return parseInt(process.env.PROXY_PORT);
|
||||||
|
}
|
||||||
|
const userPort = getUserProxyConfig();
|
||||||
|
if (userPort) {
|
||||||
|
logger.info('从用户配置读取代理端口:', userPort);
|
||||||
|
return userPort;
|
||||||
|
}
|
||||||
|
return 7890;
|
||||||
|
})(),
|
||||||
protocol: 'http'
|
protocol: 'http'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -22,18 +22,21 @@ router.post('/restart', async (req, res) => {
|
|||||||
// 延迟执行重启,给响应时间发送
|
// 延迟执行重启,给响应时间发送
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
// 获取服务器实例(通过全局变量或其他方式)
|
// 获取服务器实例
|
||||||
const server = req.app.locals.serverInstance;
|
const server = req.app.locals.serverInstance;
|
||||||
if (server && typeof server.restart === 'function') {
|
if (server && typeof server.restart === 'function') {
|
||||||
|
logger.info('开始执行服务器重启...');
|
||||||
await server.restart();
|
await server.restart();
|
||||||
} else {
|
} else {
|
||||||
logger.error('无法获取服务器实例或重启方法');
|
logger.error('无法获取服务器实例或重启方法');
|
||||||
// 如果无法优雅重启,则退出进程让进程管理器重启
|
// 如果无法优雅重启,则退出进程让进程管理器重启
|
||||||
|
logger.info('尝试直接退出进程进行重启');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('重启失败:', error);
|
logger.error('重启失败:', error);
|
||||||
// 强制退出进程
|
// 强制退出进程
|
||||||
|
logger.info('重启失败,强制退出进程');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}, 1000); // 延迟1秒执行重启
|
}, 1000); // 延迟1秒执行重启
|
||||||
|
|||||||
+45
-6
@@ -31,6 +31,19 @@ class PixivServer {
|
|||||||
this.port = 3000; // 默认端口,会在init时重新设置
|
this.port = 3000; // 默认端口,会在init时重新设置
|
||||||
this.logLevel = process.env.LOG_LEVEL || 'info'; // 获取日志级别
|
this.logLevel = process.env.LOG_LEVEL || 'info'; // 获取日志级别
|
||||||
this.isVerboseMode = ['debug', 'trace'].includes(this.logLevel.toLowerCase()); // 检查是否为详细模式
|
this.isVerboseMode = ['debug', 'trace'].includes(this.logLevel.toLowerCase()); // 检查是否为详细模式
|
||||||
|
|
||||||
|
// 保存启动时的命令行参数和环境变量
|
||||||
|
this.startupArgs = {
|
||||||
|
argv: [...process.argv], // 复制命令行参数
|
||||||
|
env: {
|
||||||
|
PORT: process.env.PORT,
|
||||||
|
PROXY_PORT: process.env.PROXY_PORT,
|
||||||
|
LOG_LEVEL: process.env.LOG_LEVEL,
|
||||||
|
NODE_ENV: process.env.NODE_ENV,
|
||||||
|
AUTO_OPEN_BROWSER: process.env.AUTO_OPEN_BROWSER,
|
||||||
|
UV_THREADPOOL_SIZE: process.env.UV_THREADPOOL_SIZE
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -203,15 +216,41 @@ class PixivServer {
|
|||||||
await this.backend.cleanup?.();
|
await this.backend.cleanup?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info('正在重新初始化服务器...');
|
logger.info('正在使用原始启动参数重新启动服务器...');
|
||||||
|
|
||||||
// 重新初始化
|
// 使用spawn重新启动进程,保持原始参数
|
||||||
await this.init();
|
const { spawn } = require('child_process');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
// 重新启动
|
// 构建启动命令
|
||||||
this.start();
|
const nodeExecutable = process.execPath;
|
||||||
|
const startScript = path.join(__dirname, 'start.js');
|
||||||
|
|
||||||
|
// 获取原始命令行参数(排除node和脚本路径)
|
||||||
|
const originalArgs = this.startupArgs.argv.slice(2);
|
||||||
|
|
||||||
|
logger.info('重启命令:', nodeExecutable, [startScript, ...originalArgs]);
|
||||||
|
|
||||||
|
// 启动新进程
|
||||||
|
const child = spawn(nodeExecutable, [startScript, ...originalArgs], {
|
||||||
|
detached: true,
|
||||||
|
stdio: 'inherit',
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
...this.startupArgs.env // 恢复原始环境变量
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 分离子进程
|
||||||
|
child.unref();
|
||||||
|
|
||||||
|
logger.info('新进程已启动,当前进程即将退出');
|
||||||
|
|
||||||
|
// 延迟退出当前进程
|
||||||
|
setTimeout(() => {
|
||||||
|
process.exit(0);
|
||||||
|
}, 500);
|
||||||
|
|
||||||
logger.info('服务器重启完成');
|
|
||||||
return { success: true, message: '服务器重启成功' };
|
return { success: true, message: '服务器重启成功' };
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
+31
-3
@@ -147,6 +147,22 @@ class Logger {
|
|||||||
/**
|
/**
|
||||||
* 格式化日志消息
|
* 格式化日志消息
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* 安全的JSON序列化,避免循环引用
|
||||||
|
*/
|
||||||
|
safeStringify(obj, space = 2) {
|
||||||
|
const seen = new WeakSet();
|
||||||
|
return JSON.stringify(obj, (key, val) => {
|
||||||
|
if (val != null && typeof val === 'object') {
|
||||||
|
if (seen.has(val)) {
|
||||||
|
return '[Circular Reference]';
|
||||||
|
}
|
||||||
|
seen.add(val);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}, space);
|
||||||
|
}
|
||||||
|
|
||||||
formatMessage(level, message, data = null) {
|
formatMessage(level, message, data = null) {
|
||||||
const timeStr = this.getTimeString();
|
const timeStr = this.getTimeString();
|
||||||
const levelName = LogLevelTexts[level];
|
const levelName = LogLevelTexts[level];
|
||||||
@@ -167,12 +183,24 @@ class Logger {
|
|||||||
if (errorProps.length > 0) {
|
if (errorProps.length > 0) {
|
||||||
const additionalProps = {};
|
const additionalProps = {};
|
||||||
errorProps.forEach(prop => {
|
errorProps.forEach(prop => {
|
||||||
additionalProps[prop] = data[prop];
|
try {
|
||||||
|
additionalProps[prop] = data[prop];
|
||||||
|
} catch (e) {
|
||||||
|
additionalProps[prop] = '[Unable to serialize]';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
formattedMessage += `\n Additional: ${JSON.stringify(additionalProps, null, 2)}`;
|
try {
|
||||||
|
formattedMessage += `\n Additional: ${this.safeStringify(additionalProps)}`;
|
||||||
|
} catch (e) {
|
||||||
|
formattedMessage += `\n Additional: [Serialization failed]`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (typeof data === 'object') {
|
} else if (typeof data === 'object') {
|
||||||
formattedMessage += ` ${JSON.stringify(data, null, 2)}`;
|
try {
|
||||||
|
formattedMessage += ` ${this.safeStringify(data)}`;
|
||||||
|
} catch (e) {
|
||||||
|
formattedMessage += ` [Object serialization failed]`;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
formattedMessage += ` ${data}`;
|
formattedMessage += ` ${data}`;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user