Files
notes/work/移动杭研/开发记录/7.12.0/测试数据.md
T
2026-03-01 01:43:46 +08:00

225 lines
10 KiB
Markdown

```
FOR 循环
"batchSize": 1000
2025-07-29 14:50:35 [XNIO-1 task-2] INFO c.c.p.g.s.GwForwardRecordService:364 - 测试数据生成完成,总计: 100 条
2025-07-29 14:50:35 [XNIO-1 task-2] INFO c.c.p.c.w.i.PlusWebInvokeTimeInterceptor:81 - [PLUS]结束请求 => URL[POST /gateway/record/generate-test-data],耗时:[12,736]毫秒
2025-07-29 14:53:15 [XNIO-1 task-2] INFO c.c.p.g.s.GwForwardRecordService:364 - 测试数据生成完成,总计: 1000 条
2025-07-29 14:53:15 [XNIO-1 task-2] INFO c.c.p.c.w.i.PlusWebInvokeTimeInterceptor:81 - [PLUS]结束请求 => URL[POST /gateway/record/generate-test-data],耗时:[65,119]毫秒
2025-07-29 15:05:18 [XNIO-1 task-2] INFO c.c.p.g.s.GwForwardRecordService:364 - 测试数据生成完成,总计: 2000 条
2025-07-29 15:05:18 [XNIO-1 task-2] INFO c.c.p.c.w.i.PlusWebInvokeTimeInterceptor:81 - [PLUS]结束请求 => URL[POST /gateway/record/generate-test-data],耗时:[131919]毫秒
批量插入
"batchSize": 1000
2025-07-29 15:13:02 [XNIO-1 task-2] INFO c.c.p.g.s.GwForwardRecordService:357 - 测试数据生成完成,总计: 1000 条
2025-07-29 15:13:02 [XNIO-1 task-2] INFO c.c.p.c.w.i.PlusWebInvokeTimeInterceptor:81 - [PLUS]结束请求 => URL[POST /gateway/record/generate-test-data],耗时:[1153]毫秒
2025-07-29 15:13:40 [XNIO-1 task-2] INFO c.c.p.g.s.GwForwardRecordService:357 - 测试数据生成完成,总计: 10000 条
2025-07-29 15:13:40 [XNIO-1 task-2] INFO c.c.p.c.w.i.PlusWebInvokeTimeInterceptor:81 - [PLUS]结束请求 => URL[POST /gateway/record/generate-test-data],耗时:[6060]毫秒
"batchSize": 2000
2025-07-29 15:14:32 [XNIO-1 task-2] INFO c.c.p.g.s.GwForwardRecordService:357 - 测试数据生成完成,总计: 10000 条
2025-07-29 15:14:32 [XNIO-1 task-2] INFO c.c.p.c.w.i.PlusWebInvokeTimeInterceptor:81 - [PLUS]结束请求 => URL[POST /gateway/record/generate-test-data],耗时:[8088]毫秒
"batchSize": 3000
2025-07-29 15:15:02 [XNIO-1 task-2] INFO c.c.p.g.s.GwForwardRecordService:357 - 测试数据生成完成,总计: 10000 条
2025-07-29 15:15:02 [XNIO-1 task-2] INFO c.c.p.c.w.i.PlusWebInvokeTimeInterceptor:81 - [PLUS]结束请求 => URL[POST /gateway/record/generate-test-data],耗时:[9107]毫秒
"batchSize": 1000
2025-07-29 15:16:40 [XNIO-1 task-2] INFO c.c.p.g.s.GwForwardRecordService:357 - 测试数据生成完成,总计: 50000 条
2025-07-29 15:16:40 [XNIO-1 task-2] INFO c.c.p.c.w.i.PlusWebInvokeTimeInterceptor:81 - [PLUS]结束请求 => URL[POST /gateway/record/generate-test-data],耗时:[39666]毫秒【数据犯了5倍,但时间6倍】
"batchSize": 5000
2025-07-29 15:18:37 [XNIO-1 task-2] INFO c.c.p.g.s.GwForwardRecordService:357 - 测试数据生成完成,总计: 50000 条
2025-07-29 15:18:37 [XNIO-1 task-2] INFO c.c.p.c.w.i.PlusWebInvokeTimeInterceptor:81 - [PLUS]结束请求 => URL[POST /gateway/record/generate-test-data],耗时:[45076]毫秒【多了十五秒】
```
### 最左前缀原则
```
/**
* 生成测试数据
*/
@PostMapping("/generate-test-data")
public R<String> generateTestData(@Valid @RequestBody GwForwardRecordTestDataReq request) {
long startTime = System.currentTimeMillis();
gwForwardRecordService.generateTestData(request);
long endTime = System.currentTimeMillis();
String message = String.format("成功生成 %d 条测试数据,耗时 %d 毫秒",
request.getCount(), endTime - startTime);
return R.ok(message);
}
/**
* 生成测试数据
*/
public void generateTestData(GwForwardRecordTestDataReq request) {
log.info("开始生成测试数据,数量: {}", request.getCount());
// 设置默认时间范围
LocalDateTime endTime = request.getEndTime() != null ? request.getEndTime() : LocalDateTime.now();
LocalDateTime startTime = request.getStartTime() != null ? request.getStartTime() : endTime.minusDays(7);
// 获取路由配置
Map<String, Long> routeNameToIdMap = gwRouteConfigService.selectRouteNameToIdMap();
if (routeNameToIdMap.isEmpty()) {
throw new RuntimeException("没有找到路由配置,请先配置路由");
}
List<String> routeNames = new ArrayList<>(routeNameToIdMap.keySet());
int batchSize = request.getBatchSize();
int totalCount = request.getCount();
int processedCount = 0;
try {
while (processedCount < totalCount) {
int currentBatchSize = Math.min(batchSize, totalCount - processedCount);
List<GwForwardRecord> records = generateBatchTestData(currentBatchSize, startTime, endTime,
routeNames, routeNameToIdMap);
// 批量插入主表数据
recordMapper.insertBatch(records, currentBatchSize);
processedCount += currentBatchSize;
if (processedCount % (batchSize * 10) == 0) {
log.info("已生成测试数据: {}/{}", processedCount, totalCount);
}
}
log.info("测试数据生成完成,总计: {} 条", totalCount);
} catch (Exception e) {
log.error("生成测试数据失败", e);
throw new RuntimeException("生成测试数据失败: " + e.getMessage());
}
}
/**
* 生成批量测试数据
*/
private List<GwForwardRecord> generateBatchTestData(int count, LocalDateTime startTime, LocalDateTime endTime,
List<String> routeNames, Map<String, Long> routeNameToIdMap) {
List<GwForwardRecord> records = new ArrayList<>(count);
ThreadLocalRandom random = ThreadLocalRandom.current();
// 预定义的API路径模板
String[] apiPaths = {
"/api/v1/user/login", "/api/v1/user/logout", "/api/v1/user/profile",
"/api/v2/sync/BBOSS/PreCheckServ", "/api/v2/sync/BBOSS/QueryServ", "/api/v2/sync/BBOSS/UpdateServ",
"/api/v1/order/create", "/api/v1/order/query", "/api/v1/order/update", "/api/v1/order/cancel",
"/api/v1/payment/create", "/api/v1/payment/query", "/api/v1/payment/callback",
"/api/v1/product/list", "/api/v1/product/detail", "/api/v1/product/search",
"/api/v1/system/health", "/api/v1/system/config", "/api/v1/system/monitor"
};
// HTTP方法
String[] methods = {"GET", "POST", "PUT", "DELETE"};
// 目标服务地址
String[] targetEndpoints = {
"127.0.0.1:8080", "127.0.0.1:8081", "127.0.0.1:8082",
"192.168.1.100:8080", "192.168.1.101:8080", "192.168.1.102:8080"
};
// 网关地址
String[] gatewayEndpoints = {
"192.168.208.16:8087", "192.168.208.17:8087", "192.168.208.18:8087"
};
// HTTP状态码权重分布(模拟真实场景)
int[] httpCodes = {200, 200, 200, 200, 200, 200, 200, 200, 200, 201, 400, 401, 403, 404, 500, 502, 503};
long startTimestamp = startTime.atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli();
long endTimestamp = endTime.atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli();
for (int i = 0; i < count; i++) {
// 随机生成时间
long randomTimestamp = random.nextLong(startTimestamp, endTimestamp);
LocalDateTime requestTime = LocalDateTime.ofInstant(
java.time.Instant.ofEpochMilli(randomTimestamp), java.time.ZoneId.systemDefault());
// 随机选择路由
String routeName = routeNames.get(random.nextInt(routeNames.size()));
// 生成UUID和TraceId
String uuid = java.util.UUID.randomUUID().toString();
String traceId = uuid.replace("-", "").substring(0, 16);
// 随机选择API路径
String requestUrl = apiPaths[random.nextInt(apiPaths.length)];
// 随机选择HTTP方法
String method = methods[random.nextInt(methods.length)];
// 随机选择目标地址
String targetEndpoint = targetEndpoints[random.nextInt(targetEndpoints.length)];
// 随机选择网关地址
String gatewayEndpoint = gatewayEndpoints[random.nextInt(gatewayEndpoints.length)];
// 随机选择HTTP状态码
Integer httpCode = httpCodes[random.nextInt(httpCodes.length)];
// 生成响应时间(模拟真实分布)
Integer costTime = generateRealisticCostTime(random, httpCode);
GwForwardRecord record = GwForwardRecord.builder()
.uuid(uuid)
.requestTime(requestTime)
.requestUrl(requestUrl)
.method(method)
.targetEndpoint(targetEndpoint)
.httpCode(httpCode)
.traceId(traceId)
.gatewayEndpoint(gatewayEndpoint)
.routeId(routeNameToIdMap.get(routeName))
.costTime(costTime)
.build();
records.add(record);
}
return records;
}
/**
* 生成真实的响应时间分布
*/
private Integer generateRealisticCostTime(ThreadLocalRandom random, Integer httpCode) {
// 根据HTTP状态码生成不同的响应时间分布
if (httpCode >= 200 && httpCode < 300) {
// 成功请求:大部分在100-2000ms之间,少数较慢
if (random.nextDouble() < 0.8) {
return random.nextInt(100, 2000); // 80%的请求在100-2000ms
} else if (random.nextDouble() < 0.95) {
return random.nextInt(2000, 5000); // 15%的请求在2-5秒
} else {
return random.nextInt(5000, 15000); // 5%的请求在5-15秒
}
} else if (httpCode >= 400 && httpCode < 500) {
// 客户端错误:通常较快
return random.nextInt(50, 1000);
} else if (httpCode >= 500) {
// 服务器错误:可能很慢或超时
if (random.nextDouble() < 0.7) {
return random.nextInt(1000, 10000); // 70%在1-10秒
} else {
return random.nextInt(10000, 30000); // 30%在10-30秒
}
} else {
// 其他状态码
return random.nextInt(100, 3000);
}
}
```