feat: 添加可配置升级次数和优化日志时间戳

1. 在pm2.json中添加进程管理配置
2. 在YAML配置中增加upgrade_count字段控制升级次数
3. 修改升级逻辑支持N次升级后切换版本
4. 为API调用日志添加ISO时间戳
5. 更新项目文档说明可配置升级次数
This commit is contained in:
2026-01-22 14:06:22 +08:00
parent 99279006a2
commit 834ac02da5
6 changed files with 21 additions and 9 deletions

View File

@@ -2,6 +2,10 @@
"apps": [{ "apps": [{
"name": "rcu-upgrade-service", "name": "rcu-upgrade-service",
"script": "./src/index.js", "script": "./src/index.js",
"instances": 1,
"exec_mode": 'fork',
"autorestart": true,
"watch": false,
"env": { "env": {
"NODE_ENV": "production" "NODE_ENV": "production"
}, },

View File

@@ -5,7 +5,7 @@
4项目需要用pm2部署需要在项目根目录下创建一个pm2.json文件配置好启动参数。 4项目需要用pm2部署需要在项目根目录下创建一个pm2.json文件配置好启动参数。
5项目需要在.env文件配置好所有的环境变量和升级参数。 5项目需要在.env文件配置好所有的环境变量和升级参数。
6项目需要创建一个test_upgrade数据库数据库中需要有一个upgrade_log表用于记录升级日志。 6项目需要创建一个test_upgrade数据库数据库中需要有一个upgrade_log表用于记录升级日志。
7需要一个定时器每隔10分钟时间需要通过env配置文件修改调用升级接口。这里注意配置文件需要特殊设计因为可能需要同时对多个主机分多组进行升级每组主机的升级时间也可能是不同的需要根据实际情况进行配置roomtype_id应当是数组一个roomtype_id应当对应一组host_list_str每个host_list_str也应当是数组一组host_list_str对应2个fileName这里注意2个fileName是因为每一个版本需要连续升级2次,然后切换另一个版本,再升级再切换版本以此类推。每次升级最小升级单位是roomtype_id多个roomtype_id的情况下分别使用每一个roomtype_id和他对应的host_list_str以及fileName来调用接口进行下发。你需要设计好配置文件的结构并且给出一个案例。 7需要一个定时器每隔10分钟时间需要通过env配置文件修改调用升级接口。这里注意配置文件需要特殊设计因为可能需要同时对多个主机分多组进行升级每组主机的升级时间也可能是不同的需要根据实际情况进行配置roomtype_id应当是数组一个roomtype_id应当对应一组host_list_str每个host_list_str也应当是数组一组host_list_str对应2个fileName这里注意2个fileName是因为每一个版本需要连续升级N次N可配置默认为2,然后切换另一个版本,再升级N再切换版本以此类推。每次升级最小升级单位是roomtype_id多个roomtype_id的情况下分别使用每一个roomtype_id和他对应的host_list_str以及fileName来调用接口进行下发。你需要设计好配置文件的结构并且给出一个案例。
环境: 环境:
Windows server 2022 Windows server 2022

View File

@@ -178,6 +178,10 @@ components:
type: integer type: integer
fileName: fileName:
type: string type: string
upgrade_count:
type: integer
description: Number of times to upgrade this file before switching
default: 2
required: required:
- roomtype_id - roomtype_id
- fileName - fileName

View File

@@ -16,16 +16,16 @@ const triggerUpgrade = async (roomtype_id, host_list, fileName) => {
params.append('host_list_str', JSON.stringify(host_list)); params.append('host_list_str', JSON.stringify(host_list));
params.append('fileName', fileName); params.append('fileName', fileName);
console.log('[Upgrade_V2] Request', { console.log(`[${new Date().toISOString()}] [Upgrade_V2] Request`, {
roomtype_id, roomtype_id,
host_list_str: host_list, host_list_str: host_list,
fileName fileName
}); });
const response = await apiClient.post('/Upgrade_V2', params); const response = await apiClient.post('/Upgrade_V2', params);
console.log('[Upgrade_V2] Response', response.data); console.log(`[${new Date().toISOString()}] [Upgrade_V2] Response`, response.data);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error('Error calling Upgrade_V2:', error.message); console.error(`[${new Date().toISOString()}] Error calling Upgrade_V2:`, error.message);
throw error; throw error;
} }
}; };
@@ -35,14 +35,14 @@ const queryStatus = async (host_list) => {
const params = new URLSearchParams(); const params = new URLSearchParams();
params.append('HostIDList', JSON.stringify(host_list)); params.append('HostIDList', JSON.stringify(host_list));
console.log('[QueryUpdateHostProgressBar] Request', { console.log(`[${new Date().toISOString()}] [QueryUpdateHostProgressBar] Request`, {
HostIDList: host_list HostIDList: host_list
}); });
const response = await apiClient.post('/QueryUpdateHostProgressBar', params); const response = await apiClient.post('/QueryUpdateHostProgressBar', params);
console.log('[QueryUpdateHostProgressBar] Response', response.data); console.log(`[${new Date().toISOString()}] [QueryUpdateHostProgressBar] Response`, response.data);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error('Error calling QueryUpdateHostProgressBar:', error.message); console.error(`[${new Date().toISOString()}] Error calling QueryUpdateHostProgressBar:`, error.message);
throw error; throw error;
} }
}; };

View File

@@ -15,6 +15,9 @@ const parseUpgradeConfig = (configStr) => {
group.roomtypes.forEach((roomtype, rIdx) => { group.roomtypes.forEach((roomtype, rIdx) => {
if (!roomtype.roomtype_id) throw new Error(`Group ${idx} Roomtype ${rIdx} missing roomtype_id`); if (!roomtype.roomtype_id) throw new Error(`Group ${idx} Roomtype ${rIdx} missing roomtype_id`);
if (!roomtype.fileName) throw new Error(`Group ${idx} Roomtype ${rIdx} missing fileName`); if (!roomtype.fileName) throw new Error(`Group ${idx} Roomtype ${rIdx} missing fileName`);
if (roomtype.upgrade_count !== undefined && typeof roomtype.upgrade_count !== 'number') {
throw new Error(`Group ${idx} Roomtype ${rIdx} upgrade_count must be a number`);
}
}); });
}); });
return config; return config;

View File

@@ -16,12 +16,13 @@ const processGroup = async (group, groupIdx) => {
const roomtype = group.roomtypes[state.current_roomtype_index]; const roomtype = group.roomtypes[state.current_roomtype_index];
const roomtype_id = roomtype.roomtype_id; const roomtype_id = roomtype.roomtype_id;
const fileName = roomtype.fileName; const fileName = roomtype.fileName;
const upgradeCountLimit = roomtype.upgrade_count || 2;
let nextState = { ...state }; let nextState = { ...state };
nextState.execution_count += 1; nextState.execution_count += 1;
if (nextState.execution_count >= 2) { if (nextState.execution_count >= upgradeCountLimit) {
nextState.execution_count = 0; nextState.execution_count = 0;
nextState.current_roomtype_index = 1 - state.current_roomtype_index; nextState.current_roomtype_index = (state.current_roomtype_index + 1) % group.roomtypes.length;
} }
const sessionUuid = uuidv4(); const sessionUuid = uuidv4();