From e53abe6e2261a8dfe912440bc83858362c38991f Mon Sep 17 00:00:00 2001 From: expressgy Date: Wed, 13 Dec 2023 23:53:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=B5=84=E6=BA=90=E7=B1=BB?= =?UTF-8?q?=E3=80=81=E5=85=B3=E7=B3=BB=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cache/index.js | 10 +- src/common/tools/binarySearch.js | 17 +- src/common/tools/binarySearchMore.js | 1 + src/routes/graphResource2/atomModel/index.js | 23 ++ src/routes/graphResource2/baseDict/index.js | 3 +- .../graphResource2/resourceClass/index.dto.js | 10 +- .../graphResource2/resourceClass/index.js | 343 +++++++++++++++--- test/压力/getClassTreeForAtomMOdel.js | 13 +- 8 files changed, 345 insertions(+), 75 deletions(-) diff --git a/src/cache/index.js b/src/cache/index.js index 4005c41..5e5e575 100644 --- a/src/cache/index.js +++ b/src/cache/index.js @@ -382,7 +382,11 @@ async function makeResourceCache(sequelize) { // region 获取资源类关系表 const classRelationList = await sequelize.models.ResourceClassRelation.findAll( - sequelizeFindAllType, + {...sequelizeFindAllType,where: { + isDelete: { + [Op.is]: null, + }, + },}, ); // @ classRelationIdList - String - 描述:获取资源类关系ID列表 const classRelationIdList = []; @@ -394,7 +398,7 @@ async function makeResourceCache(sequelize) { const classRelationItem = classRelationList[i]; const classRelationItemId = classRelationItem.resourceClassRelationId; const targetId = classRelationItem.resourceClassRelationTarget; - classRelationIdList.push(classRelationItem); + classRelationIdList.push(classRelationItemId); classRelationObject[classRelationItemId] = classRelationItem; if (classRelationObjectForTargetClass[targetId] === undefined) { classRelationObjectForTargetClass[targetId] = [classRelationItem]; @@ -686,7 +690,7 @@ async function makeResourceCache(sequelize) { }; // @ 构建类关系 for (let i = 0; i < classRelationIdList.length; i++) { - const nodeId = classRelationIdList[i].resourceClassRelationId; + const nodeId = classRelationList[i].resourceClassRelationId; const classNode = classNodeObject[nodeId]; const fatherId = classNodeObject[nodeId].fatherId; classNodeObject[fatherId].children.push(classNode); diff --git a/src/common/tools/binarySearch.js b/src/common/tools/binarySearch.js index 9e88e9b..a5d095d 100644 --- a/src/common/tools/binarySearch.js +++ b/src/common/tools/binarySearch.js @@ -11,10 +11,23 @@ // | = // | ------------------------------------------------------------ -export default function binarySearch(arr, id, att) { +export default function binarySearch(arr, id, att = undefined) { let bi = 0, ai = arr.length -1; - if(!Object.keys(arr[0]).includes(att)){ + if(!Object.keys(arr[0]).includes(att) && att !== undefined){ throw new Error('不存在属性', att) + }else if(att === undefined){ + while (bi <= ai){ + const mi = Math.floor((bi + ai)/2); + const miId = arr[mi] + if(miId === id){ + return mi + }else if(miId < id){ + bi = mi + 1 + }else{ + ai = mi -1 + } + } + return -1 } while (bi <= ai){ const mi = Math.floor((bi + ai)/2); diff --git a/src/common/tools/binarySearchMore.js b/src/common/tools/binarySearchMore.js index 670aa57..d8a8026 100644 --- a/src/common/tools/binarySearchMore.js +++ b/src/common/tools/binarySearchMore.js @@ -30,6 +30,7 @@ function binarySearch2(arr, id, att, bi, ai) { } export default function binarySearchMore(arr, ids, att, bi, ai){ + if(ids.length == 0)return [] const firstIndex = binarySearch2(arr, ids[0], att, bi, ai); if(firstIndex != -1){ bi = firstIndex diff --git a/src/routes/graphResource2/atomModel/index.js b/src/routes/graphResource2/atomModel/index.js index a448faf..6e2ccc2 100644 --- a/src/routes/graphResource2/atomModel/index.js +++ b/src/routes/graphResource2/atomModel/index.js @@ -86,6 +86,29 @@ atomModel.post('/createAtomModelItem', async (ctx, next) => { ] = newAtomModel.dataValues; resourceCache.atomModelPool.length++; resourceCache.atomModelPool.updatetime = new Date().getTime(); + + const RRP = resourceCache.resourcePool; + RRP.classListForAtomModel[newAtomModel.dataValues.atomModelId] = [] + RRP.classNodeObjectForAtomModel[newAtomModel.dataValues.atomModelId] = [] + + // 给元分类加入基础几点 + const RBP = resourceCache.baseDictPool + RBP.atomModelObject[newAtomModel.dataValues.atomModelId] = { + baseDictTree: [], + reduceBaseDictTree: [], + }; + RBP.atomModelObject[newAtomModel.dataValues.atomModelId].baseDictTree = RBP.atomObject[ + '0' + ].children.filter( + (dict) => !(dict.atomModel && newAtomModel.dataValues.atomModelId != dict.atomModel), + ); + RBP.atomModelObject[newAtomModel.dataValues.atomModelId].reduceBaseDictTree = RBP.reduceObject[ + '0' + ].children.filter( + (dict) => !(dict.atomModel && newAtomModel.dataValues.atomModelId != dict.atomModel), + ); + + ctx.body = { message: '新建元分类成功。', data: newAtomModel.dataValues, diff --git a/src/routes/graphResource2/baseDict/index.js b/src/routes/graphResource2/baseDict/index.js index ea3e360..2c33738 100644 --- a/src/routes/graphResource2/baseDict/index.js +++ b/src/routes/graphResource2/baseDict/index.js @@ -219,6 +219,7 @@ baseDict.post('/createBaseDictItem', async (ctx, next) => { atomModelId, 'atomModelId', ); + // 判断字典缓存是否存在元分类 if (hasAtomModel == -1) { // 检查是否存在元分类/模型 return ctx.throw(400, { e: '不存在目标元分类/模型' }); @@ -275,7 +276,7 @@ baseDict.post('/createBaseDictItem', async (ctx, next) => { } // 分别压入精简原始字典对象到根节点树 RBP.atomModelObject[atomModelId].baseDictTree.push(newBaseDictItem); - RBP.atomModelObject[atomModelId].baseDictTree.push(reduceData); + RBP.atomModelObject[atomModelId].reduceBaseDictTree.push(reduceData); return (ctx.body = { message: '添加字典项成功', data: newBaseDictItem, diff --git a/src/routes/graphResource2/resourceClass/index.dto.js b/src/routes/graphResource2/resourceClass/index.dto.js index 65716c4..760cd03 100644 --- a/src/routes/graphResource2/resourceClass/index.dto.js +++ b/src/routes/graphResource2/resourceClass/index.dto.js @@ -369,19 +369,19 @@ export function DeleteResourceClassItemDTO(data) { const schema = { type: 'object', properties: { - resourceClassBaseId: { + nodeId: { type: ['integer'], minimum: 0, errorMessage: { - type: '资源类ID必须是整数', - minimum: '资源类ID是一个正整数', + type: '资源类节点ID必须是整数', + minimum: '资源类节点ID是一个正整数', }, }, }, - required: ['resourceClassBaseId'], + required: ['nodeId'], errorMessage: { required: { - resourceClassBaseId: '资源类ID为必填项', + nodeId: '资源类节点ID为必填项', }, }, }; diff --git a/src/routes/graphResource2/resourceClass/index.js b/src/routes/graphResource2/resourceClass/index.js index 6f27903..e18bd12 100644 --- a/src/routes/graphResource2/resourceClass/index.js +++ b/src/routes/graphResource2/resourceClass/index.js @@ -27,6 +27,9 @@ import { } from '#routes/graphResource2/resourceClass/index.dto.js'; import getPage from '#common/tools/getArrayPage.js'; import getNoSpacesStr from '#common/tools/getNoSpacesStr.js'; +import binarySearch from '#common/tools/binarySearch.js'; +import binarySearchMore from '#common/tools/binarySearchMore.js'; +import { Op } from 'sequelize'; const resourceClass = new Router(); @@ -145,16 +148,24 @@ resourceClass.post('/createResourceClassItem', async (ctx, next) => { return ctx.throw(400, { e: '资源类标识已存在' }); } // @ 判断是否存在父节点 - if(resourceClassRelationId != 0){ - if(RRP.classRelationObject[resourceClassRelationId] == undefined){ + if (resourceClassRelationId != 0) { + if (RRP.classRelationObject[resourceClassRelationId] == undefined) { return ctx.throw(400, { e: '不存在目标资源类树节点' }); } - if(!RRP.classListForAtomModel[atomModelId].some(i => i.resourceClassBaseId == RRP.classRelationObject[resourceClassRelationId].resourceClassRelationTarget)){ - return ctx.throw(400, { e: '目标资源类树节点不存在于目标元分类/模型中' }); + if ( + !RRP.classListForAtomModel[atomModelId].some( + (i) => + i.resourceClassBaseId == + RRP.classRelationObject[resourceClassRelationId] + .resourceClassRelationTarget, + ) + ) { + return ctx.throw(400, { + e: '目标资源类树节点不存在于目标元分类/模型中', + }); } } - // 写入资源类 const newClassItem = await ctx.sequelize.models.ResourceClassBase.create({ atomModel: atomModelId, @@ -196,9 +207,11 @@ resourceClass.post('/createResourceClassItem', async (ctx, next) => { // ! 写入classRelationObjectForTargetClass RRP.classRelationObjectForTargetClass[classId] = []; // @ 获取目标资源关系节点的资源类ID - const fatherClassId = resourceClassRelationId == 0 ? 0 : - RRP.classRelationObject[resourceClassRelationId] - .resourceClassRelationTarget; + const fatherClassId = + resourceClassRelationId == 0 + ? 0 + : RRP.classRelationObject[resourceClassRelationId] + .resourceClassRelationTarget; // 在数据库添加这条关系 const newClassRelation = await ctx.sequelize.models.ResourceClassRelation.create({ @@ -230,23 +243,20 @@ resourceClass.post('/createResourceClassItem', async (ctx, next) => { const nowRelationList = nowClassModel.classRelationList; // 拿到父节点和节点ID const nodeId = nowRelationList[0].resourceClassRelationId; - const classNode = new RRP.ClassNodeModel( - nowClassModel, - nodeId, - ); - RRP.classNodeObject[nodeId] = classNode + const classNode = new RRP.ClassNodeModel(nowClassModel, nodeId); + RRP.classNodeObject[nodeId] = classNode; RRP.classNodeObject[resourceClassRelationId].children.push(classNode); - if(resourceClassRelationId == 0){ - RRP.classNodeObjectForAtomModel[atomModelId].push(classNode) + if (resourceClassRelationId == 0) { + RRP.classNodeObjectForAtomModel[atomModelId].push(classNode); } ctx.body = { message: '创建资源类成功', data: { resourceClassBase: newClassData, - resourceClassRelation: newClassRelationData - } + resourceClassRelation: newClassRelationData, + }, }; }); @@ -264,67 +274,99 @@ resourceClass.post('/editResourceClassItem', async (ctx, next) => { resourceClassBaseAvatar, resourceClassBaseDefine, resourceClassBaseColor, - resourceClassBaseType + resourceClassBaseType, } = ctx.request.body; const RRP = resourceCache.resourcePool; - let oldName,oldIdentify,atomModelId + let oldName, oldIdentify, atomModelId; // @ 判断ID是否存在 - if(!RRP.classIdList.includes(resourceClassBaseId)){ + if (!RRP.classIdList.includes(resourceClassBaseId)) { return ctx.throw(400, { e: '资源类不存在' }); - }else{ - oldName = RRP.classObject[resourceClassBaseId].resourceClassBaseId - oldIdentify = RRP.classObject[resourceClassBaseId].resourceClassBaseIdentify - atomModelId = RRP.classObject[resourceClassBaseId].atomModel + } else { + oldName = RRP.classObject[resourceClassBaseId].resourceClassBaseId; + oldIdentify = + RRP.classObject[resourceClassBaseId].resourceClassBaseIdentify; + atomModelId = RRP.classObject[resourceClassBaseId].atomModel; } // @ 判断名称是否重复 - if(RRP.classListForAtomModel[atomModelId].some(i => i.resourceClassBaseName == getNoSpacesStr(resourceClassBaseName) && i.resourceClassBaseId != resourceClassBaseId)){ + if ( + RRP.classListForAtomModel[atomModelId].some( + (i) => + i.resourceClassBaseName == + getNoSpacesStr(resourceClassBaseName) && + i.resourceClassBaseId != resourceClassBaseId, + ) + ) { return ctx.throw(400, { e: '资源类重名' }); } // @ 判断标识是否重复 - if(RRP.classList.some(i => i.resourceClassBaseIdentify == getNoSpacesStr(resourceClassBaseIdentify).toUpperCase() && i.resourceClassBaseId != resourceClassBaseId)){ + if ( + RRP.classList.some( + (i) => + i.resourceClassBaseIdentify == + getNoSpacesStr(resourceClassBaseIdentify).toUpperCase() && + i.resourceClassBaseId != resourceClassBaseId, + ) + ) { return ctx.throw(400, { e: '资源类标识已存在' }); } // 修改信息 - RRP.classObject[resourceClassBaseId].resourceClassBaseName = getNoSpacesStr(resourceClassBaseName); - RRP.classObject[resourceClassBaseId].resourceClassBaseDescribe = resourceClassBaseDescribe; - RRP.classObject[resourceClassBaseId].resourceClassBaseIdentify = getNoSpacesStr(resourceClassBaseIdentify).toUpperCase(); - RRP.classObject[resourceClassBaseId].resourceClassBaseId = resourceClassBaseId; - RRP.classObject[resourceClassBaseId].resourceClassBaseAvatar = resourceClassBaseAvatar; - RRP.classObject[resourceClassBaseId].resourceClassBaseDefine = resourceClassBaseDefine; - RRP.classObject[resourceClassBaseId].resourceClassBaseColor = resourceClassBaseColor; - RRP.classObject[resourceClassBaseId].resourceClassBaseType = resourceClassBaseType; + RRP.classObject[resourceClassBaseId].resourceClassBaseName = getNoSpacesStr( + resourceClassBaseName, + ); + RRP.classObject[resourceClassBaseId].resourceClassBaseDescribe = + resourceClassBaseDescribe; + RRP.classObject[resourceClassBaseId].resourceClassBaseIdentify = + getNoSpacesStr(resourceClassBaseIdentify).toUpperCase(); + RRP.classObject[resourceClassBaseId].resourceClassBaseId = + resourceClassBaseId; + RRP.classObject[resourceClassBaseId].resourceClassBaseAvatar = + resourceClassBaseAvatar; + RRP.classObject[resourceClassBaseId].resourceClassBaseDefine = + resourceClassBaseDefine; + RRP.classObject[resourceClassBaseId].resourceClassBaseColor = + resourceClassBaseColor; + RRP.classObject[resourceClassBaseId].resourceClassBaseType = + resourceClassBaseType; // @ 是否修改标识 - console.log(oldIdentify, getNoSpacesStr(resourceClassBaseIdentify).toUpperCase()) - if(oldIdentify != getNoSpacesStr(resourceClassBaseIdentify).toUpperCase()){ - console.log('更改表名') + if ( + oldIdentify != getNoSpacesStr(resourceClassBaseIdentify).toUpperCase() + ) { // 需要更改表明 // ! 删除模型 - delete ctx.sequelize.models[oldIdentify.toLowerCase()] + delete ctx.sequelize.models[oldIdentify.toLowerCase()]; // ! 修改表名 - const results = await ctx.sequelize.queryInterface.renameTable('entity_' + oldIdentify.toLowerCase(),'entity_' + getNoSpacesStr(resourceClassBaseIdentify).toLowerCase()) + const results = await ctx.sequelize.queryInterface.renameTable( + 'entity_' + oldIdentify.toLowerCase(), + 'entity_' + getNoSpacesStr(resourceClassBaseIdentify).toLowerCase(), + ); // ! 启动新模型 await RRP.classModelObject[resourceClassBaseId].createSequelizeModel(); // | 更新资源实体ID } ctx.body = { - message: '修改资源类信息成功' + message: '修改资源类信息成功', }; - await next() - await ctx.sequelize.models.ResourceClassBase.update({ - resourceClassBaseName : getNoSpacesStr(resourceClassBaseName), - resourceClassBaseDescribe : resourceClassBaseDescribe, - resourceClassBaseIdentify : getNoSpacesStr(resourceClassBaseIdentify).toUpperCase(), - resourceClassBaseId : resourceClassBaseId, - resourceClassBaseAvatar : resourceClassBaseAvatar, - resourceClassBaseDefine : resourceClassBaseDefine, - resourceClassBaseColor : resourceClassBaseColor, - resourceClassBaseType : resourceClassBaseType, - },{ - where:{ - resourceClassBaseId - } - }) + await next(); + await ctx.sequelize.models.ResourceClassBase.update( + { + resourceClassBaseName: getNoSpacesStr(resourceClassBaseName), + resourceClassBaseDescribe: resourceClassBaseDescribe, + resourceClassBaseIdentify: getNoSpacesStr( + resourceClassBaseIdentify, + ).toUpperCase(), + resourceClassBaseId: resourceClassBaseId, + resourceClassBaseAvatar: resourceClassBaseAvatar, + resourceClassBaseDefine: resourceClassBaseDefine, + resourceClassBaseColor: resourceClassBaseColor, + resourceClassBaseType: resourceClassBaseType, + }, + { + where: { + resourceClassBaseId, + }, + }, + ); }); // @ 删除资源类 @@ -333,7 +375,195 @@ resourceClass.delete('/deleteResourceClassItem', async (ctx, next) => { if (!verif.status) { return ctx.throw(400, { e: verif.error.map((i) => i.message) }); } - ctx.body = 6; + const nodeId = ctx.query.nodeId; + // 判断是否存在节点 + const RRP = resourceCache.resourcePool; + const findNodeId = binarySearch(RRP.classRelationIdList, nodeId); + if (findNodeId == -1) { + return ctx.throw(400, { e: '不存在此资源类节点ID' }); + } + const classNodeObject = RRP.classNodeObject[nodeId]; + if (classNodeObject.children.length != 0) { + return ctx.throw(400, { + e: '该资源类节点下存在子节点,无法删除,请先删除子节点。', + }); + } + const classId = classNodeObject.classId; + const fatherId = classNodeObject.fatherId; + const atomModel = classNodeObject.atomModel; + const classIdentify = classNodeObject.classIdentify; + + let entityListB, expandListB; + + // @ 删掉关联列表 + RRP.classRelationList.splice(findNodeId, 1); + // @ 删掉关联ID列表 + RRP.classRelationIdList.splice(findNodeId, 1); + // @ 删掉关联ID对象集合 + delete RRP.classRelationObject[nodeId]; + // @ 删除资源类的关联对象中的当前节点 + const relationList = RRP.classRelationObjectForTargetClass[classId]; + relationList.splice( + binarySearch(relationList, nodeId, 'resourceClassRelationId'), + 1, + ); + + // @ 删除父节点下的children的此节点 + RRP.classNodeObject[fatherId].children.splice( + binarySearch(RRP.classNodeObject[fatherId].children, nodeId, 'nodeId'), + 1, + ); + // @ 删除节点列表上的此节点 + delete RRP.classNodeObject[nodeId]; + // 删除原分类下的根节点 + if (fatherId == 0) { + RRP.classNodeObjectForAtomModel[atomModel].splice( + binarySearch( + RRP.classNodeObjectForAtomModel[atomModel], + nodeId, + 'nodeId', + ), + 1, + ); + } + if (classNodeObject.classRelationIdList.length == 0) { + // 最后一个节点了,删掉的话就删掉了资源类 + // @ 删掉资源类的关联列表 + delete RRP.classRelationObjectForTargetClass[classId]; + // @ 删资源类 + const classIdIndex = binarySearch(RRP.classIdList, classId); + RRP.classList.splice(classIdIndex, 1); + RRP.classIdList.splice(classIdIndex, 1); + delete RRP.classObject[classId]; + RRP.classListForAtomModel[atomModel].splice( + binarySearch( + RRP.classListForAtomModel[atomModel], + classId, + 'resourceClassBaseId', + ), + ); + // @ 删资源类拓展字段 + if ( + Object.keys(RRP.classExpandForClassBaseObject).includes( + classId.toString(), + ) + ) { + const expandList = RRP.classExpandForClassBaseObject[classId]; + const expandIdList = Object.keys(expandList).map((i) => { + delete RRP.classExpandObject[ + expandList[i].resourceClassExpandFieldId + ]; + return expandList[i].resourceClassExpandFieldId; + }); + expandListB = expandIdList; + delete RRP.classExpandForClassBaseObject[classId]; + const expandIdIndexList = binarySearchMore( + RRP.classExpandList, + expandIdList, + 'resourceClassExpandFieldId', + 0, + RRP.classExpandList.length, + ).sort((a, b) => b - a); + for (let i of expandIdIndexList) { + RRP.classExpandList.splice(i, 1); + RRP.classExpandIdList.splice(i, 1); + } + } + + // @ 删除资源实体字段 + if ( + Object.keys(RRP.entityStructForClassBaseObject).includes( + classId.toString(), + ) + ) { + const entityNameObject = + RRP.entityStructForClassBaseObject[classId]; + const entityIdList = Object.keys(entityNameObject).map((i) => { + delete RRP.entityStructObject[ + entityNameObject[i].resourceEntityStructId + ]; + return entityNameObject[i].resourceEntityStructId; + }); + entityListB = entityIdList; + delete RRP.entityStructForClassBaseObject[classId]; + const entityIndexList = binarySearchMore( + RRP.entityStructList, + entityIdList, + 'resourceEntityStructId', + 0, + RRP.entityStructList.length, + ).sort((a, b) => b - a); + for (let i of entityIndexList) { + RRP.entityStructList.splice(i, 1); + RRP.entityStructIdList.splice(i, 1); + } + } + // ! @ 删资源对象 + // @ 删除表 + const data = await ctx.sequelize.query( + 'DROP TABLE IF EXISTS ' + 'entity_' + classIdentify.toLowerCase(), + ); + // 删除资源对象缓存 + } + ctx.body = { + message: '删除资源类节点成功。', + }; + // 删除关联 + ctx.sequelize.models.ResourceClassRelation.update( + { + isDelete: new Date().toISOString(), + }, + { + where: { + resourceClassRelationId: nodeId, + }, + }, + ); + + if (classNodeObject.classRelationIdList.length == 0) { + // 删除资源类 + ctx.sequelize.models.ResourceClassBase.update( + { + isDelete: new Date().toISOString(), + }, + { + where: { + resourceClassBaseId: classId, + }, + }, + ); + // 删除拓展字段 + if (expandListB) { + ctx.sequelize.models.ResourceClassExpandField.update( + { + isDelete: new Date().toISOString(), + }, + { + where: { + resourceClassExpandFieldId: { + [Op.in]: expandListB, + }, + }, + }, + ); + } + + // 删除实体字段 + if (entityListB) { + ctx.sequelize.models.ResourceEntityStruct.update( + { + isDelete: new Date().toISOString(), + }, + { + where: { + resourceEntityStructId: { + [Op.in]: entityListB, + }, + }, + }, + ); + } + } }); // @ 创建资源类关联 @@ -351,6 +581,7 @@ resourceClass.delete('/deleteResourceClassRelation', async (ctx, next) => { if (!verif.status) { return ctx.throw(400, { e: verif.error.map((i) => i.message) }); } + const RRP = resourceCache.resourcePool; ctx.body = 8; }); diff --git a/test/压力/getClassTreeForAtomMOdel.js b/test/压力/getClassTreeForAtomMOdel.js index 8a486d2..72a62f4 100644 --- a/test/压力/getClassTreeForAtomMOdel.js +++ b/test/压力/getClassTreeForAtomMOdel.js @@ -13,14 +13,11 @@ import loadtest from 'loadtest' // 定义要测试的目标 URL -const url = ['http://localhost:5000/graphResource2/resourceClass/getResourceClassTree?searchData&atomModelId=1', - 'http://localhost:5000/graphResource2/resourceClass/getResourceClassCompleteInfo?resourceClassBaseId=1&resourceClassBaseIdentify=', - 'http://localhost:5000/graphResource2/resourceClass/getResourceClassList?searchData=%E4%BC%81%E4%B8%9A&atomModelId=1' -] +const url = 'http://localhost:3001' // 定义 loadtest 的参数 const options = { url: url, - maxRequests: 1000, // 总请求数 + maxRequests: 50000, // 总请求数 concurrency: 20 // 并发请求数 }; @@ -28,15 +25,15 @@ loadtest.loadTest(options, function(error, result) { if (error) { console.error('压力测试失败:', error); } else { - console.log('压力测试结果1:'); + console.log('压力测试结果:'); console.log('总请求数:', result.totalRequests); console.log('请求失败数:', result.totalErrors); console.log('总运行时间(秒):', result.totalTimeSeconds); console.log('平均延迟时间(毫秒):', result.meanLatencyMs); console.log('最小延迟时间(毫秒):', result.minLatencyMs); console.log('最大延迟时间(毫秒):', result.maxLatencyMs); - console.log('请求总字节数:', result.requestBytes); - console.log('响应总字节数:', result.responseBytes); + // console.log('请求总字节数:', result.requestBytes); + // console.log('响应总字节数:', result.responseBytes); console.log('每秒请求数:', result.rps); } });