From 867fea760537c45849fe8ccae1fa76add9e52751 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Thu, 20 Oct 2022 15:04:03 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96=E7=BC=93=E5=AD=98=E5=8F=96=E5=80=BC?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E5=90=8E=E5=86=8D=E4=BB=8E=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E5=8F=96=E5=80=BC=EF=BC=8C=E4=B8=8D=E5=BD=B1=E5=93=8D?= =?UTF-8?q?=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1018411 --user=赵勇 [接口测试]github#18657测试计划执行中,报 redis 连接超时,导致测试计划一直是 Running 状态,建议优化 redis 连接配置和测试计划异常处理机制 https://www.tapd.cn/55049933/s/1269608 --- .../service/ApiExecutionQueueService.java | 47 +++++++------------ .../service/RedisTemplateService.java | 42 +++++++++++++++++ .../service/TestResultService.java | 6 +-- 3 files changed, 62 insertions(+), 33 deletions(-) create mode 100644 api-test/backend/src/main/java/io/metersphere/service/RedisTemplateService.java diff --git a/api-test/backend/src/main/java/io/metersphere/service/ApiExecutionQueueService.java b/api-test/backend/src/main/java/io/metersphere/service/ApiExecutionQueueService.java index 1ceb774232..ef577dd2db 100644 --- a/api-test/backend/src/main/java/io/metersphere/service/ApiExecutionQueueService.java +++ b/api-test/backend/src/main/java/io/metersphere/service/ApiExecutionQueueService.java @@ -6,23 +6,10 @@ import io.metersphere.api.exec.queue.DBTestQueue; import io.metersphere.api.exec.scenario.ApiScenarioSerialService; import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.jmeter.JMeterThreadUtils; -import io.metersphere.service.scenario.ApiScenarioReportService; -import io.metersphere.base.domain.ApiDefinitionExecResult; -import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs; -import io.metersphere.base.domain.ApiExecutionQueue; -import io.metersphere.base.domain.ApiExecutionQueueDetail; -import io.metersphere.base.domain.ApiExecutionQueueDetailExample; -import io.metersphere.base.domain.ApiExecutionQueueExample; -import io.metersphere.base.domain.ApiScenarioReport; -import io.metersphere.base.domain.ApiScenarioReportResultExample; -import io.metersphere.base.domain.ApiScenarioReportWithBLOBs; -import io.metersphere.base.mapper.ApiDefinitionExecResultMapper; -import io.metersphere.base.mapper.ApiScenarioReportMapper; -import io.metersphere.base.mapper.ApiScenarioReportResultMapper; -import io.metersphere.base.mapper.ApiExecutionQueueDetailMapper; -import io.metersphere.base.mapper.ApiExecutionQueueMapper; -import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper; +import io.metersphere.base.domain.*; +import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.ext.BaseApiExecutionQueueMapper; +import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper; import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper; import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.KafkaTopicConstants; @@ -34,26 +21,19 @@ import io.metersphere.commons.utils.LogUtil; import io.metersphere.constants.RunModeConstants; import io.metersphere.dto.ResultDTO; import io.metersphere.dto.RunModeConfigDTO; +import io.metersphere.service.scenario.ApiScenarioReportService; import io.metersphere.utils.LoggerUtil; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.TimeUnit; +import java.util.*; import java.util.stream.Collectors; @Service @@ -63,7 +43,7 @@ public class ApiExecutionQueueService { @Resource private ApiExecutionQueueDetailMapper executionQueueDetailMapper; @Resource - private RedisTemplate redisTemplate; + private RedisTemplateService redisTemplateService; @Resource private ApiScenarioSerialService apiScenarioSerialService; @Resource @@ -333,12 +313,18 @@ public class ApiExecutionQueueService { if (StringUtils.equals(dto.getRunType(), RunModeConstants.SERIAL.toString())) { LoggerUtil.info("当前执行队列是:" + JSON.toJSONString(executionQueue.getDetail())); // 防止重复执行 - boolean isNext = redisTemplate.opsForValue().setIfAbsent(RunModeConstants.SERIAL.name() + "_" + executionQueue.getDetail().getReportId(), executionQueue.getDetail().getQueueId()); + String key = StringUtils.join(RunModeConstants.SERIAL.name(), "_", executionQueue.getDetail().getReportId()); + boolean isNext = redisTemplateService.setIfAbsent(key, executionQueue.getDetail().getQueueId()); if (!isNext) { return; } - redisTemplate.expire(RunModeConstants.SERIAL.name() + "_" + executionQueue.getDetail().getReportId(), 60, TimeUnit.MINUTES); - if (StringUtils.equalsAny(executionQueue.getRunMode(), ApiRunMode.SCENARIO.name(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { + redisTemplateService.expire(key); + if (StringUtils.equalsAny(executionQueue.getRunMode(), + ApiRunMode.SCENARIO.name(), + ApiRunMode.SCENARIO_PLAN.name(), + ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), + ApiRunMode.SCHEDULE_SCENARIO.name(), + ApiRunMode.JENKINS_SCENARIO_PLAN.name())) { apiScenarioSerialService.serial(executionQueue); } else { apiCaseSerialService.serial(executionQueue); @@ -409,7 +395,8 @@ public class ApiExecutionQueueService { LoggerUtil.info("超时处理报告:" + report.getId()); if (queue != null && StringUtils.equalsIgnoreCase(item.getType(), RunModeConstants.SERIAL.toString())) { // 删除串行资源锁 - redisTemplate.delete(RunModeConstants.SERIAL.name() + "_" + dto.getReportId()); + String key = StringUtils.join(RunModeConstants.SERIAL.name(), "_", dto.getReportId()); + redisTemplateService.delete(key); LoggerUtil.info("超时处理报告:【" + report.getId() + "】进入下一个执行"); dto.setTestPlanReportId(queue.getReportId()); diff --git a/api-test/backend/src/main/java/io/metersphere/service/RedisTemplateService.java b/api-test/backend/src/main/java/io/metersphere/service/RedisTemplateService.java new file mode 100644 index 0000000000..5284561b18 --- /dev/null +++ b/api-test/backend/src/main/java/io/metersphere/service/RedisTemplateService.java @@ -0,0 +1,42 @@ +package io.metersphere.service; + +import io.metersphere.commons.utils.LogUtil; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.concurrent.TimeUnit; + +@Service +public class RedisTemplateService { + @Resource + private RedisTemplate redisTemplate; + public static final long TIME_OUT = 30; + + public boolean setIfAbsent(String key, String value) { + try { + return redisTemplate.opsForValue().setIfAbsent(key, value); + } catch (Exception e) { + LogUtil.error(e); + return true; + } + } + + public boolean expire(String key) { + try { + return redisTemplate.expire(key, TIME_OUT, TimeUnit.MINUTES); + } catch (Exception e) { + LogUtil.error(e); + return false; + } + } + + public boolean delete(String key) { + try { + return redisTemplate.delete(key); + } catch (Exception e) { + LogUtil.error(e); + return false; + } + } +} diff --git a/api-test/backend/src/main/java/io/metersphere/service/TestResultService.java b/api-test/backend/src/main/java/io/metersphere/service/TestResultService.java index 59ecfd470d..2c513dac05 100644 --- a/api-test/backend/src/main/java/io/metersphere/service/TestResultService.java +++ b/api-test/backend/src/main/java/io/metersphere/service/TestResultService.java @@ -28,7 +28,6 @@ import io.metersphere.service.scenario.ApiScenarioService; import org.apache.commons.beanutils.BeanMap; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -51,7 +50,7 @@ public class TestResultService { @Resource private ApiEnvironmentRunningParamService apiEnvironmentRunningParamService; @Resource - private RedisTemplate redisTemplate; + private RedisTemplateService redisTemplateService; @Resource private ApiScenarioExecutionInfoService scenarioExecutionInfoService; @Resource @@ -148,7 +147,8 @@ public class TestResultService { public void testEnded(ResultDTO dto) { // 删除串行资源锁 if (StringUtils.equals(dto.getRunType(), RunModeConstants.SERIAL.toString())) { - redisTemplate.delete(RunModeConstants.SERIAL.name() + "_" + dto.getReportId()); + String key = StringUtils.join(RunModeConstants.SERIAL.name(), "_", dto.getReportId()); + redisTemplateService.delete(key); } if (dto.getRequestResults() == null) { dto.setRequestResults(new LinkedList<>());