feat: 1.5.0

1. 优化了场景配置提示信息
2. 修复远程重试次数日志打印错误,取远程的重试次数
3. 优化了初始化场景默认执行21次,任务停留3天。
This commit is contained in:
byteblogs168 2023-06-02 14:07:31 +08:00
parent a25dc3d3f1
commit 03ba7592b2
32 changed files with 78 additions and 17 deletions

View File

@ -33,7 +33,10 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;
@ -75,6 +78,10 @@ public class RetryEndPoint {
DispatchRetryResultDTO executeRespDto = new DispatchRetryResultDTO();
try {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
request.setAttribute("attemptNumber", executeReqDto.getRetryCount());
RetryerResultContext retryerResultContext = retryStrategy.openRetry(executeReqDto.getScene(), executeReqDto.getExecutorName(), deSerialize);
if (RetrySiteSnapshot.isRetryForStatusCode()) {

View File

@ -12,9 +12,13 @@ import com.aizuda.easy.retry.common.core.enums.RetryResultStatusEnum;
import com.aizuda.easy.retry.common.core.log.LogUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@ -108,12 +112,15 @@ public class RemoteRetryStrategies extends AbstractRetryStrategies {
return Collections.singletonList(new RetryListener() {
@Override
public <V> void onRetry(Attempt<V> attempt) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
Integer attemptNumber = (Integer) request.getAttribute("attemptNumber");
if (attempt.hasResult()) {
LogUtils.error(log, "easy-retry 远程重试成功,第[{}]次调度", attempt.getAttemptNumber());
LogUtils.info(log, "easy-retry 远程重试成功,第[{}]次调度", attemptNumber);
}
if (attempt.hasException()) {
LogUtils.error(log, "easy-retry 远程重试失败,第[{}]次调度 ", attempt.getAttemptNumber(), attempt.getExceptionCause());
LogUtils.error(log, "easy-retry 远程重试失败,第[{}]次调度 ", attemptNumber, attempt.getExceptionCause());
}
}

View File

@ -3,6 +3,8 @@ package com.aizuda.easy.retry.client.model;
import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 服务端调度重试入参
*
@ -21,4 +23,6 @@ public class DispatchRetryDTO {
private String executorName;
@NotBlank(message = "uniqueId 不能为空")
private String uniqueId;
@NotNull(message = "retryCount 不能为空")
private Integer retryCount;
}

View File

@ -1,6 +1,7 @@
package com.aizuda.easy.retry.server.service.impl;
import cn.hutool.core.lang.Assert;
import com.aizuda.easy.retry.common.core.enums.DelayLevelEnum;
import com.aizuda.easy.retry.common.core.enums.StatusEnum;
import com.aizuda.easy.retry.common.core.log.LogUtils;
import com.aizuda.easy.retry.server.exception.EasyRetryServerException;
@ -129,7 +130,7 @@ public class RetryServiceImpl implements RetryService {
sceneConfig.setSceneName(retryTaskDTO.getSceneName());
sceneConfig.setSceneStatus(StatusEnum.YES.getStatus());
sceneConfig.setBackOff(WaitStrategyEnum.DELAY_LEVEL.getBackOff());
sceneConfig.setMaxRetryCount(26);
sceneConfig.setMaxRetryCount(DelayLevelEnum._21.getLevel());
sceneConfig.setDescription("自动初始化场景");
Assert.isTrue(1 == sceneConfigMapper.insert(sceneConfig), () -> new EasyRetryServerException("init scene error"));
}

View File

@ -113,6 +113,7 @@ public class ExecUnitActor extends AbstractActor {
dispatchRetryDTO.setExecutorName(retryTask.getExecutorName());
dispatchRetryDTO.setArgsStr(retryTask.getArgsStr());
dispatchRetryDTO.setUniqueId(retryTask.getUniqueId());
dispatchRetryDTO.setRetryCount(retryTask.getRetryCount());
// 设置header
HttpHeaders requestHeaders = new HttpHeaders();

View File

@ -1 +1 @@
<!DOCTYPE html><html lang="zh-cmn-Hans"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/logo.png"><title>Easy-Retry</title><style>.first-loading-wrp{display:flex;justify-content:center;align-items:center;flex-direction:column;min-height:420px;height:100%}.first-loading-wrp>h1{font-size:128px}.first-loading-wrp .loading-wrp{padding:98px;display:flex;justify-content:center;align-items:center}.dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:32px;width:32px;height:32px;box-sizing:border-box}.dot i{width:14px;height:14px;position:absolute;display:block;background-color:#1890ff;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.dot i:nth-child(1){top:0;left:0}.dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}</style><link href="/css/chunk-758b2aa4.1c9c785f.css" rel="prefetch"><link href="/css/chunk-77aaac2a.99cbbcce.css" rel="prefetch"><link href="/css/chunk-ff9025ec.cd4961ff.css" rel="prefetch"><link href="/css/user.6ccd4506.css" rel="prefetch"><link href="/js/chunk-2d0a4079.6503c9e8.js" rel="prefetch"><link href="/js/chunk-2d0b7230.d76e8327.js" rel="prefetch"><link href="/js/chunk-2d0c8f97.1111cfe1.js" rel="prefetch"><link href="/js/chunk-2d0d43f4.76cfb7a0.js" rel="prefetch"><link href="/js/chunk-2d0f085f.06d06ef2.js" rel="prefetch"><link href="/js/chunk-2d21a08f.0b09f340.js" rel="prefetch"><link href="/js/chunk-2d228eef.b8e52655.js" rel="prefetch"><link href="/js/chunk-40597980.2d9d8e5b.js" rel="prefetch"><link href="/js/chunk-732da7b5.e9478532.js" rel="prefetch"><link href="/js/chunk-758b2aa4.c2fcb19f.js" rel="prefetch"><link href="/js/chunk-77aaac2a.13ae8ece.js" rel="prefetch"><link href="/js/chunk-ff9025ec.cbd49e0c.js" rel="prefetch"><link href="/js/fail.0b016cdb.js" rel="prefetch"><link href="/js/lang-zh-CN-account-settings.f8f25eaf.js" rel="prefetch"><link href="/js/lang-zh-CN-account.f7a734c3.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard-analysis.d7cabd65.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard.ffd6ecbd.js" rel="prefetch"><link href="/js/lang-zh-CN-form-basicForm.ff3088ac.js" rel="prefetch"><link href="/js/lang-zh-CN-form.39cd9999.js" rel="prefetch"><link href="/js/lang-zh-CN-global.bf0df5c8.js" rel="prefetch"><link href="/js/lang-zh-CN-menu.25425a62.js" rel="prefetch"><link href="/js/lang-zh-CN-result-fail.232762aa.js" rel="prefetch"><link href="/js/lang-zh-CN-result-success.3519c60c.js" rel="prefetch"><link href="/js/lang-zh-CN-result.b3df3bc6.js" rel="prefetch"><link href="/js/lang-zh-CN-setting.8c2ce690.js" rel="prefetch"><link href="/js/lang-zh-CN-user.81513cba.js" rel="prefetch"><link href="/js/lang-zh-CN.6ae67127.js" rel="prefetch"><link href="/js/user.ee4839e7.js" rel="prefetch"><link href="/css/app.37a20ada.css" rel="preload" as="style"><link href="/css/chunk-vendors.5be6e05a.css" rel="preload" as="style"><link href="/js/app.0e4b1d23.js" rel="preload" as="script"><link href="/js/chunk-vendors.b8c3b6d4.js" rel="preload" as="script"><link href="/css/chunk-vendors.5be6e05a.css" rel="stylesheet"><link href="/css/app.37a20ada.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"><div class="first-loading-wrp"><h2>Easy-Retry</h2><div class="loading-wrp"><span class="dot dot-spin"><i></i><i></i><i></i><i></i></span></div><div style="display: flex; justify-content: center; align-items: center;">分布式重试服务平台</div></div></div><script src="//cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script><script src="//cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script><script src="//cdn.jsdelivr.net/npm/vuex@3.1.1/dist/vuex.min.js"></script><script src="//cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js"></script><script src="/js/chunk-vendors.b8c3b6d4.js"></script><script src="/js/app.0e4b1d23.js"></script></body></html>
<!DOCTYPE html><html lang="zh-cmn-Hans"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/logo.png"><title>Easy-Retry</title><style>.first-loading-wrp{display:flex;justify-content:center;align-items:center;flex-direction:column;min-height:420px;height:100%}.first-loading-wrp>h1{font-size:128px}.first-loading-wrp .loading-wrp{padding:98px;display:flex;justify-content:center;align-items:center}.dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:32px;width:32px;height:32px;box-sizing:border-box}.dot i{width:14px;height:14px;position:absolute;display:block;background-color:#1890ff;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.dot i:nth-child(1){top:0;left:0}.dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}</style><link href="/css/chunk-758b2aa4.1c9c785f.css" rel="prefetch"><link href="/css/chunk-77aaac2a.99cbbcce.css" rel="prefetch"><link href="/css/chunk-ff9025ec.cd4961ff.css" rel="prefetch"><link href="/css/user.6ccd4506.css" rel="prefetch"><link href="/js/chunk-2d0a4079.211a0ec0.js" rel="prefetch"><link href="/js/chunk-2d0b7230.744dfabb.js" rel="prefetch"><link href="/js/chunk-2d0c8f97.cc136224.js" rel="prefetch"><link href="/js/chunk-2d0d43f4.80553fcb.js" rel="prefetch"><link href="/js/chunk-2d0f085f.f21e1806.js" rel="prefetch"><link href="/js/chunk-2d21a08f.6cbb4cc2.js" rel="prefetch"><link href="/js/chunk-2d228eef.9de243f8.js" rel="prefetch"><link href="/js/chunk-40597980.de54e7d4.js" rel="prefetch"><link href="/js/chunk-732da7b5.fd3e2a30.js" rel="prefetch"><link href="/js/chunk-758b2aa4.25d8d22f.js" rel="prefetch"><link href="/js/chunk-77aaac2a.dfff8cf0.js" rel="prefetch"><link href="/js/chunk-ff9025ec.a77794ad.js" rel="prefetch"><link href="/js/fail.026754f1.js" rel="prefetch"><link href="/js/lang-zh-CN-account-settings.f8f25eaf.js" rel="prefetch"><link href="/js/lang-zh-CN-account.c724e71d.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard-analysis.d7cabd65.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard.5180154b.js" rel="prefetch"><link href="/js/lang-zh-CN-form-basicForm.ff3088ac.js" rel="prefetch"><link href="/js/lang-zh-CN-form.cc39e450.js" rel="prefetch"><link href="/js/lang-zh-CN-global.bf0df5c8.js" rel="prefetch"><link href="/js/lang-zh-CN-menu.25425a62.js" rel="prefetch"><link href="/js/lang-zh-CN-result-fail.232762aa.js" rel="prefetch"><link href="/js/lang-zh-CN-result-success.3519c60c.js" rel="prefetch"><link href="/js/lang-zh-CN-result.32c5cf1c.js" rel="prefetch"><link href="/js/lang-zh-CN-setting.8c2ce690.js" rel="prefetch"><link href="/js/lang-zh-CN-user.81513cba.js" rel="prefetch"><link href="/js/lang-zh-CN.3dfa92aa.js" rel="prefetch"><link href="/js/user.b5997f11.js" rel="prefetch"><link href="/css/app.b0a9877f.css" rel="preload" as="style"><link href="/css/chunk-vendors.5be6e05a.css" rel="preload" as="style"><link href="/js/app.1239f620.js" rel="preload" as="script"><link href="/js/chunk-vendors.87c1e94d.js" rel="preload" as="script"><link href="/css/chunk-vendors.5be6e05a.css" rel="stylesheet"><link href="/css/app.b0a9877f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"><div class="first-loading-wrp"><h2>Easy-Retry</h2><div class="loading-wrp"><span class="dot dot-spin"><i></i><i></i><i></i><i></i></span></div><div style="display: flex; justify-content: center; align-items: center;">分布式重试服务平台</div></div></div><script src="//cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script><script src="//cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script><script src="//cdn.jsdelivr.net/npm/vuex@3.1.1/dist/vuex.min.js"></script><script src="//cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js"></script><script src="/js/chunk-vendors.87c1e94d.js"></script><script src="/js/app.1239f620.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -38,7 +38,7 @@
<dependency>
<groupId>com.aizuda</groupId>
<artifactId>easy-retry-client-starter</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>

View File

@ -26,7 +26,7 @@
:pagination="pagination"
:loading="memberLoading"
@change="handleTableChange"
:scroll="{ x: 1200 }"
:scroll="{ x: 1800 }"
>
<template v-for="(col, i) in ['sceneName', 'description']" :slot="col" slot-scope="text, record">
<a-input
@ -59,7 +59,7 @@
:value="text === 0 ? null: text"
@change="value => handleChange(value, record.key, 'backOff')">
<a-select-option value="1">延迟等级</a-select-option>
<a-select-option value="2">固定时间</a-select-option>
<a-select-option value="2">固定时间</a-select-option>
<a-select-option value="3">CRON表达式</a-select-option>
<a-select-option value="4">随机等待</a-select-option>
</a-select>
@ -72,8 +72,9 @@
:max="max"
style="width: 100%;"
:value="text"
placeholder="最大重试次数"
@change="value => handleChange(value, record.key, 'maxRetryCount')"/>
:placeholder="maxRetryCount[data.find(item => item.key === record.key).backOff].placeholder"
@change="value => handleChange(value, record.key, 'maxRetryCount')">
</a-input-number>
<template v-else>{{ text }}</template>
</template>
<template slot="deadlineRequest" slot-scope="text, record">
@ -91,11 +92,15 @@
<a-input
v-if="record.editable"
style="margin: -5px 0"
:placeholder="data.find(item => item.key === record.key).backOff === '3' ? '请输入CRON表达式' : '请输入间隔时间'"
:placeholder="triggerInterval[data.find(item => item.key === record.key).backOff].placeholder"
:value="text"
:disabled="data.find(item => item.key === record.key).backOff === '1'"
@change="e => handleChange(e.target.value, record.key, 'triggerInterval')"
/>
>
<a-tooltip slot="suffix" :title="triggerInterval[data.find(item => item.key === record.key).backOff].tooltip">
<a-icon type="info-circle" style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</a-input>
<template v-else>{{ text }}()</template>
</template>
<template slot="operation" slot-scope="text, record">
@ -205,7 +210,7 @@ export default {
pagination: {},
backOffLabels: {
'1': '延迟等级',
'2': '固定时间',
'2': '固定时间',
'3': 'CRON表达式',
'4': '随机等待'
},
@ -213,6 +218,42 @@ export default {
'0': '停用',
'1': '启用'
},
triggerInterval: {
'1': {
placeholder: '',
tooltip: ''
},
'2': {
placeholder: '请输入固定间隔时间',
tooltip: '请输入固定间隔时间'
},
'3': {
placeholder: '请输入CRON表达式',
tooltip: '通过CRON表达式计算执行时间'
},
'4': {
placeholder: '请输入最大间隔时间',
tooltip: '随机生成范围在[0, x]内的延迟时间; 其中x代表最大间隔时间'
}
},
maxRetryCount: {
'1': {
placeholder: '请输入延迟等级(max:26)',
tooltip: '请输入延迟等级max:26)'
},
'2': {
placeholder: '请输入最大重试次数',
tooltip: '请输入最大重试次数'
},
'3': {
placeholder: '请输入最大重试次数',
tooltip: '请输入最大重试次数'
},
'4': {
placeholder: '请输入最大重试次数',
tooltip: '请输入最大重试次数'
}
},
queryParam: {}
}
},