feat: 实现多商户管理模块与前端服务
refactor: 优化服务层代码并修复类型问题 docs: 更新开发进度文档 feat(merchant): 新增商户监控与数据统计服务 feat(dashboard): 添加商户管理前端页面与服务 fix: 修复类型转换与可选参数处理 feat: 实现商户订单、店铺与结算管理功能 refactor: 重构审计日志格式与服务调用 feat: 新增商户入驻与身份注册功能 fix(controller): 修复路由参数类型问题 feat: 添加商户排名与统计报告功能 chore: 更新模拟数据与服务配置
This commit is contained in:
277
server/src/services/MerchantPerformanceTest.ts
Normal file
277
server/src/services/MerchantPerformanceTest.ts
Normal file
@@ -0,0 +1,277 @@
|
||||
/**
|
||||
* [OP-ST004] 多商户性能测试服务
|
||||
* @description 测试多商户系统的性能,分析并发情况下的系统表现
|
||||
* @version 1.0
|
||||
*/
|
||||
export class MerchantPerformanceTest {
|
||||
/**
|
||||
* 执行多商户性能测试
|
||||
* @param params 测试参数
|
||||
* @param traceInfo 追踪信息
|
||||
* @returns 性能测试结果
|
||||
*/
|
||||
public static async runPerformanceTest(params: {
|
||||
concurrentMerchants: number;
|
||||
testDuration: number; // 测试持续时间(秒)
|
||||
operationsPerSecond: number;
|
||||
}, traceInfo: {
|
||||
tenantId: string;
|
||||
shopId: string;
|
||||
taskId: string;
|
||||
traceId: string;
|
||||
businessType: 'TOC' | 'TOB';
|
||||
}): Promise<{
|
||||
testId: string;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
concurrentMerchants: number;
|
||||
operationsPerSecond: number;
|
||||
results: {
|
||||
averageResponseTime: number;
|
||||
throughput: number;
|
||||
errorRate: number;
|
||||
maxResponseTime: number;
|
||||
p95ResponseTime: number;
|
||||
p99ResponseTime: number;
|
||||
};
|
||||
}> {
|
||||
// 生成测试ID
|
||||
const testId = `PT-${Date.now()}`;
|
||||
const startTime = new Date().toISOString();
|
||||
|
||||
// 模拟性能测试过程
|
||||
console.log(`[MerchantPerformanceTest] 开始性能测试 - ID: ${testId}, 并发商户数: ${params.concurrentMerchants}`, {
|
||||
...traceInfo,
|
||||
testId
|
||||
});
|
||||
|
||||
// 模拟测试执行
|
||||
await new Promise(resolve => setTimeout(resolve, params.testDuration * 1000));
|
||||
|
||||
// 生成模拟性能数据
|
||||
const responseTimes: number[] = [];
|
||||
for (let i = 0; i < params.concurrentMerchants * params.operationsPerSecond * params.testDuration; i++) {
|
||||
// 生成正态分布的响应时间
|
||||
const responseTime = this.generateNormalDistribution(150, 50);
|
||||
responseTimes.push(responseTime);
|
||||
}
|
||||
|
||||
// 计算性能指标
|
||||
responseTimes.sort((a, b) => a - b);
|
||||
const totalOperations = responseTimes.length;
|
||||
const errorCount = Math.floor(totalOperations * 0.01); // 1% 错误率
|
||||
|
||||
const results = {
|
||||
averageResponseTime: responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length,
|
||||
throughput: totalOperations / params.testDuration,
|
||||
errorRate: errorCount / totalOperations,
|
||||
maxResponseTime: Math.max(...responseTimes),
|
||||
p95ResponseTime: responseTimes[Math.floor(responseTimes.length * 0.95)],
|
||||
p99ResponseTime: responseTimes[Math.floor(responseTimes.length * 0.99)]
|
||||
};
|
||||
|
||||
const endTime = new Date().toISOString();
|
||||
|
||||
// 记录测试完成日志
|
||||
console.log(`[MerchantPerformanceTest] 性能测试完成 - ID: ${testId}, 吞吐量: ${results.throughput.toFixed(2)} ops/s`, {
|
||||
...traceInfo,
|
||||
testId,
|
||||
results
|
||||
});
|
||||
|
||||
return {
|
||||
testId,
|
||||
startTime,
|
||||
endTime,
|
||||
concurrentMerchants: params.concurrentMerchants,
|
||||
operationsPerSecond: params.operationsPerSecond,
|
||||
results
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成正态分布的随机数
|
||||
* @param mean 均值
|
||||
* @param stdDev 标准差
|
||||
* @returns 随机数
|
||||
*/
|
||||
private static generateNormalDistribution(mean: number, stdDev: number): number {
|
||||
let u = 0, v = 0;
|
||||
while (u === 0) u = Math.random();
|
||||
while (v === 0) v = Math.random();
|
||||
const num = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
|
||||
return Math.max(0, mean + num * stdDev);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成性能报告
|
||||
* @param testId 测试ID
|
||||
* @param traceInfo 追踪信息
|
||||
* @returns 性能报告
|
||||
*/
|
||||
public static async generatePerformanceReport(testId: string, traceInfo: {
|
||||
tenantId: string;
|
||||
shopId: string;
|
||||
taskId: string;
|
||||
traceId: string;
|
||||
businessType: 'TOC' | 'TOB';
|
||||
}): Promise<{
|
||||
reportId: string;
|
||||
testId: string;
|
||||
timestamp: string;
|
||||
summary: string;
|
||||
performanceMetrics: any;
|
||||
bottlenecks: string[];
|
||||
recommendations: string[];
|
||||
}> {
|
||||
// 生成报告ID
|
||||
const reportId = `PR-${Date.now()}`;
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
// 模拟性能数据
|
||||
const performanceMetrics = {
|
||||
system: {
|
||||
cpuUsage: 65,
|
||||
memoryUsage: 72,
|
||||
diskI/O: 45,
|
||||
networkThroughput: 120
|
||||
},
|
||||
application: {
|
||||
averageResponseTime: 180,
|
||||
throughput: 850,
|
||||
errorRate: 0.01,
|
||||
maxResponseTime: 550,
|
||||
p95ResponseTime: 320,
|
||||
p99ResponseTime: 480
|
||||
},
|
||||
database: {
|
||||
queryTime: 80,
|
||||
connectionPoolUsage: 60,
|
||||
cacheHitRate: 75
|
||||
}
|
||||
};
|
||||
|
||||
// 生成瓶颈分析
|
||||
const bottlenecks: string[] = [];
|
||||
if (performanceMetrics.system.cpuUsage > 70) {
|
||||
bottlenecks.push('CPU使用率过高');
|
||||
}
|
||||
if (performanceMetrics.system.memoryUsage > 80) {
|
||||
bottlenecks.push('内存使用过高');
|
||||
}
|
||||
if (performanceMetrics.application.p95ResponseTime > 300) {
|
||||
bottlenecks.push('P95响应时间过长');
|
||||
}
|
||||
if (performanceMetrics.database.queryTime > 100) {
|
||||
bottlenecks.push('数据库查询时间过长');
|
||||
}
|
||||
|
||||
// 生成建议
|
||||
const recommendations: string[] = [];
|
||||
if (bottlenecks.length > 0) {
|
||||
recommendations.push('优化系统资源配置');
|
||||
recommendations.push('考虑数据库索引优化');
|
||||
recommendations.push('实施缓存策略');
|
||||
recommendations.push('优化代码逻辑');
|
||||
} else {
|
||||
recommendations.push('保持当前系统配置');
|
||||
recommendations.push('定期进行性能测试');
|
||||
}
|
||||
|
||||
// 生成摘要
|
||||
const summary = `系统性能良好,平均响应时间 ${performanceMetrics.application.averageResponseTime}ms,吞吐量 ${performanceMetrics.application.throughput} ops/s`;
|
||||
|
||||
// 记录报告生成日志
|
||||
console.log(`[MerchantPerformanceTest] 生成性能报告 - ID: ${reportId}, 测试: ${testId}`, {
|
||||
...traceInfo,
|
||||
reportId
|
||||
});
|
||||
|
||||
return {
|
||||
reportId,
|
||||
testId,
|
||||
timestamp,
|
||||
summary,
|
||||
performanceMetrics,
|
||||
bottlenecks,
|
||||
recommendations
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行负载测试
|
||||
* @param params 测试参数
|
||||
* @param traceInfo 追踪信息
|
||||
* @returns 负载测试结果
|
||||
*/
|
||||
public static async runLoadTest(params: {
|
||||
merchantIds: string[];
|
||||
rampUpTime: number; // ramp-up时间(秒)
|
||||
steadyStateTime: number; // 稳定状态时间(秒)
|
||||
operationsPerSecond: number;
|
||||
}, traceInfo: {
|
||||
tenantId: string;
|
||||
shopId: string;
|
||||
taskId: string;
|
||||
traceId: string;
|
||||
businessType: 'TOC' | 'TOB';
|
||||
}): Promise<{
|
||||
loadTestId: string;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
merchantCount: number;
|
||||
results: Array<{
|
||||
phase: 'ramp-up' | 'steady-state';
|
||||
throughput: number;
|
||||
averageResponseTime: number;
|
||||
errorRate: number;
|
||||
}>;
|
||||
}> {
|
||||
// 生成负载测试ID
|
||||
const loadTestId = `LT-${Date.now()}`;
|
||||
const startTime = new Date().toISOString();
|
||||
|
||||
console.log(`[MerchantPerformanceTest] 开始负载测试 - ID: ${loadTestId}, 商户数: ${params.merchantIds.length}`, {
|
||||
...traceInfo,
|
||||
loadTestId
|
||||
});
|
||||
|
||||
// 模拟ramp-up阶段
|
||||
await new Promise(resolve => setTimeout(resolve, params.rampUpTime * 1000));
|
||||
|
||||
// 模拟steady-state阶段
|
||||
await new Promise(resolve => setTimeout(resolve, params.steadyStateTime * 1000));
|
||||
|
||||
// 生成测试结果
|
||||
const results = [
|
||||
{
|
||||
phase: 'ramp-up' as const,
|
||||
throughput: params.operationsPerSecond * 0.7,
|
||||
averageResponseTime: 200,
|
||||
errorRate: 0.005
|
||||
},
|
||||
{
|
||||
phase: 'steady-state' as const,
|
||||
throughput: params.operationsPerSecond,
|
||||
averageResponseTime: 250,
|
||||
errorRate: 0.01
|
||||
}
|
||||
];
|
||||
|
||||
const endTime = new Date().toISOString();
|
||||
|
||||
// 记录测试完成日志
|
||||
console.log(`[MerchantPerformanceTest] 负载测试完成 - ID: ${loadTestId}`, {
|
||||
...traceInfo,
|
||||
loadTestId
|
||||
});
|
||||
|
||||
return {
|
||||
loadTestId,
|
||||
startTime,
|
||||
endTime,
|
||||
merchantCount: params.merchantIds.length,
|
||||
results
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user