Initial commit
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
```
|
||||
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);
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user