diff --git a/backend/src/main/java/io/metersphere/performance/controller/JmeterFileController.java b/backend/src/main/java/io/metersphere/performance/controller/JmeterFileController.java index 4a80c5fa12..bfd76594f6 100644 --- a/backend/src/main/java/io/metersphere/performance/controller/JmeterFileController.java +++ b/backend/src/main/java/io/metersphere/performance/controller/JmeterFileController.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.util.Arrays; @RestController @RequestMapping("jmeter") @@ -25,10 +26,11 @@ public class JmeterFileController { @GetMapping("download") public ResponseEntity downloadJmeterFiles(@RequestParam("testId") String testId, @RequestParam("resourceId") String resourceId, - @RequestParam("ratio") double ratio, + @RequestParam("ratio") String ratio, @RequestParam("reportId") String reportId, @RequestParam("resourceIndex") int resourceIndex) { long startTime = System.currentTimeMillis(); - byte[] bytes = jmeterFileService.downloadZip(testId, resourceId, ratio, startTime, reportId, resourceIndex); + double[] ratios = Arrays.stream(ratio.split(",")).mapToDouble(Double::parseDouble).toArray(); + byte[] bytes = jmeterFileService.downloadZip(testId, ratios, startTime, reportId, resourceIndex); return ResponseEntity.ok() .contentType(MediaType.parseMediaType("application/octet-stream")) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + testId + ".zip\"") diff --git a/backend/src/main/java/io/metersphere/performance/engine/EngineFactory.java b/backend/src/main/java/io/metersphere/performance/engine/EngineFactory.java index ae851a0f0c..efa6c6d22c 100644 --- a/backend/src/main/java/io/metersphere/performance/engine/EngineFactory.java +++ b/backend/src/main/java/io/metersphere/performance/engine/EngineFactory.java @@ -88,7 +88,7 @@ public class EngineFactory { return null; } - public static EngineContext createContext(LoadTestWithBLOBs loadTest, String resourceId, double ratio, long startTime, String reportId, int resourceIndex) { + public static EngineContext createContext(LoadTestWithBLOBs loadTest, double[] ratios, long startTime, String reportId, int resourceIndex) { final List fileMetadataList = performanceTestService.getFileMetadataByTestId(loadTest.getId()); if (org.springframework.util.CollectionUtils.isEmpty(fileMetadataList)) { MSException.throwException(Translator.get("run_load_test_file_not_found") + loadTest.getId()); @@ -124,7 +124,16 @@ public class EngineFactory { if (values instanceof List) { Object value = b.get("value"); if ("TargetLevel".equals(key)) { - value = Math.round(((Integer) b.get("value")) * ratio); + Integer targetLevel = ((Integer) b.get("value")); + if (resourceIndex + 1 == ratios.length) { + double beforeLast = 0; // 前几个线程数 + for (int k = 0; k < ratios.length - 1; k++) { + beforeLast += Math.round(targetLevel * ratios[k]); + } + value = Math.round(targetLevel - beforeLast); + } else { + value = Math.round(targetLevel * ratios[resourceIndex]); + } } ((List) values).add(value); engineContext.addProperty(key, values); diff --git a/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java b/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java index 3adbc2cb47..b5a7a904c8 100644 --- a/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java +++ b/backend/src/main/java/io/metersphere/performance/engine/docker/DockerTestEngine.java @@ -19,9 +19,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.web.client.RestTemplate; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.stream.Collectors; public class DockerTestEngine extends AbstractEngine { private static final String BASE_URL = "http://%s:%d"; @@ -50,20 +48,20 @@ public class DockerTestEngine extends AbstractEngine { if (threadNum > totalThreadNum - runningSumThreadNum) { MSException.throwException(Translator.get("max_thread_insufficient")); } - List resourceRatio = resourceList.stream() + Object[] resourceRatios = resourceList.stream() .filter(r -> ResourceStatusEnum.VALID.name().equals(r.getStatus())) .map(r -> JSON.parseObject(r.getConfiguration(), NodeDTO.class).getMaxConcurrency()) - .collect(Collectors.toList()); + .map(r -> r * 1.0 / totalThreadNum) + .map(r -> String.format("%.2f", r)) + .toArray(); for (int i = 0, size = resourceList.size(); i < size; i++) { - int ratio = resourceRatio.get(i); -// double realThreadNum = ((double) ratio / totalThreadNum) * threadNum; - runTest(resourceList.get(i), ((double) ratio / totalThreadNum), i); + runTest(resourceList.get(i), resourceRatios, i); } } - private void runTest(TestResource resource, double ratio, int resourceIndex) { + private void runTest(TestResource resource, Object[] ratios, int resourceIndex) { String configuration = resource.getConfiguration(); NodeDTO node = JSON.parseObject(configuration, NodeDTO.class); @@ -84,7 +82,7 @@ public class DockerTestEngine extends AbstractEngine { } Map env = new HashMap<>(); - env.put("RATIO", "" + ratio); + env.put("RATIO", StringUtils.join(ratios, ",")); env.put("RESOURCE_INDEX", "" + resourceIndex); env.put("METERSPHERE_URL", metersphereUrl); env.put("START_TIME", "" + this.getStartTime()); diff --git a/backend/src/main/java/io/metersphere/performance/service/JmeterFileService.java b/backend/src/main/java/io/metersphere/performance/service/JmeterFileService.java index e87f8b9b51..a0ad603bdc 100644 --- a/backend/src/main/java/io/metersphere/performance/service/JmeterFileService.java +++ b/backend/src/main/java/io/metersphere/performance/service/JmeterFileService.java @@ -26,12 +26,10 @@ public class JmeterFileService { @Resource private LoadTestMapper loadTestMapper; - public byte[] downloadZip(String testId, String resourceId, double ratio, long startTime, String reportId, int resourceIndex) { + public byte[] downloadZip(String testId, double[] ratios, long startTime, String reportId, int resourceIndex) { try { LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(testId); - // deep copy - LoadTestWithBLOBs subTest = SerializationUtils.clone(loadTest); - EngineContext context = EngineFactory.createContext(subTest, resourceId, ratio, startTime, reportId, resourceIndex); + EngineContext context = EngineFactory.createContext(loadTest, ratios, startTime, reportId, resourceIndex); return zipFilesToByteArray(context); } catch (MSException e) { LogUtil.error(e.getMessage(), e);