From 834ac02da5e4a7b6bb84f22936ae54a97a31744b Mon Sep 17 00:00:00 2001 From: XuJiacheng Date: Thu, 22 Jan 2026 14:06:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=8F=AF=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=8D=87=E7=BA=A7=E6=AC=A1=E6=95=B0=E5=92=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=97=A5=E5=BF=97=E6=97=B6=E9=97=B4=E6=88=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 在pm2.json中添加进程管理配置 2. 在YAML配置中增加upgrade_count字段控制升级次数 3. 修改升级逻辑支持N次升级后切换版本 4. 为API调用日志添加ISO时间戳 5. 更新项目文档说明可配置升级次数 --- pm2.json | 4 ++++ project.md | 2 +- spec/rcu-upgrade-flow.yaml | 4 ++++ src/apiClient.js | 12 ++++++------ src/config.js | 3 +++ src/upgradeController.js | 5 +++-- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/pm2.json b/pm2.json index d275fea..22cb73d 100644 --- a/pm2.json +++ b/pm2.json @@ -2,6 +2,10 @@ "apps": [{ "name": "rcu-upgrade-service", "script": "./src/index.js", + "instances": 1, + "exec_mode": 'fork', + "autorestart": true, + "watch": false, "env": { "NODE_ENV": "production" }, diff --git a/project.md b/project.md index c9f398b..5924ba3 100644 --- a/project.md +++ b/project.md @@ -5,7 +5,7 @@ 4,项目需要用pm2部署,需要在项目根目录下创建一个pm2.json文件,配置好启动参数。 5,项目需要在.env文件,配置好所有的环境变量和升级参数。 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 diff --git a/spec/rcu-upgrade-flow.yaml b/spec/rcu-upgrade-flow.yaml index 160f104..5711ec7 100644 --- a/spec/rcu-upgrade-flow.yaml +++ b/spec/rcu-upgrade-flow.yaml @@ -178,6 +178,10 @@ components: type: integer fileName: type: string + upgrade_count: + type: integer + description: Number of times to upgrade this file before switching + default: 2 required: - roomtype_id - fileName diff --git a/src/apiClient.js b/src/apiClient.js index 68768c3..780a7d3 100644 --- a/src/apiClient.js +++ b/src/apiClient.js @@ -16,16 +16,16 @@ const triggerUpgrade = async (roomtype_id, host_list, fileName) => { params.append('host_list_str', JSON.stringify(host_list)); params.append('fileName', fileName); - console.log('[Upgrade_V2] Request', { + console.log(`[${new Date().toISOString()}] [Upgrade_V2] Request`, { roomtype_id, host_list_str: host_list, fileName }); 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; } catch (error) { - console.error('Error calling Upgrade_V2:', error.message); + console.error(`[${new Date().toISOString()}] Error calling Upgrade_V2:`, error.message); throw error; } }; @@ -35,14 +35,14 @@ const queryStatus = async (host_list) => { const params = new URLSearchParams(); params.append('HostIDList', JSON.stringify(host_list)); - console.log('[QueryUpdateHostProgressBar] Request', { + console.log(`[${new Date().toISOString()}] [QueryUpdateHostProgressBar] Request`, { HostIDList: host_list }); 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; } catch (error) { - console.error('Error calling QueryUpdateHostProgressBar:', error.message); + console.error(`[${new Date().toISOString()}] Error calling QueryUpdateHostProgressBar:`, error.message); throw error; } }; diff --git a/src/config.js b/src/config.js index e0667f1..2090241 100644 --- a/src/config.js +++ b/src/config.js @@ -15,6 +15,9 @@ const parseUpgradeConfig = (configStr) => { group.roomtypes.forEach((roomtype, rIdx) => { 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.upgrade_count !== undefined && typeof roomtype.upgrade_count !== 'number') { + throw new Error(`Group ${idx} Roomtype ${rIdx} upgrade_count must be a number`); + } }); }); return config; diff --git a/src/upgradeController.js b/src/upgradeController.js index 7e0a5f9..7ca672c 100644 --- a/src/upgradeController.js +++ b/src/upgradeController.js @@ -16,12 +16,13 @@ const processGroup = async (group, groupIdx) => { const roomtype = group.roomtypes[state.current_roomtype_index]; const roomtype_id = roomtype.roomtype_id; const fileName = roomtype.fileName; + const upgradeCountLimit = roomtype.upgrade_count || 2; let nextState = { ...state }; nextState.execution_count += 1; - if (nextState.execution_count >= 2) { + if (nextState.execution_count >= upgradeCountLimit) { 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();