修复重试锁死问题
This commit is contained in:
parent
2305ad070f
commit
4c0c9175ed
@ -67,18 +67,74 @@ public class ExampleApplication {
|
||||
| localTimes |int|是|3| 本地重试次数 次数必须大于等于1|
|
||||
| localInterval |int|是|2| 本地重试间隔时间(s)|
|
||||
|
||||
## 初始化数据库
|
||||
|
||||
## 配置部署服务端调度平台
|
||||
### 初始化数据库
|
||||
数据库脚本位置
|
||||
```
|
||||
doc/sql/x_retry.sql
|
||||
```
|
||||
|
||||
## 配置部署服务端调度平台
|
||||
### 系统配置
|
||||
```yaml
|
||||
spring:
|
||||
datasource:
|
||||
name: x_retry
|
||||
url: jdbc:mysql://localhost:3306/x_retry?useSSL=false&characterEncoding=utf8&useUnicode=true
|
||||
username: root
|
||||
password: root
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
hikari:
|
||||
connection-timeout: 30000
|
||||
minimum-idle: 5
|
||||
maximum-pool-size: 20
|
||||
auto-commit: true
|
||||
idle-timeout: 30000
|
||||
pool-name: x_retry
|
||||
max-lifetime: 1800000
|
||||
connection-test-query: SELECT 1
|
||||
resources:
|
||||
static-locations: classpath:admin/
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath:/mapper/*.xml
|
||||
typeAliasesPackage: com.x.retry.server.persistence.mybatis.po
|
||||
global-config:
|
||||
db-config:
|
||||
field-strategy: NOT_EMPTY
|
||||
capital-mode: false
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
cache-enabled: true
|
||||
x-retry:
|
||||
lastDays: 30 # 拉取重试数据的天数
|
||||
retryPullPageSize: 100 # 拉取重试数据的每批次的大小
|
||||
nettyPort: 1788 # 服务端netty端口
|
||||
totalPartition: 32 # 重试和死信表的分区总数
|
||||
|
||||
### 组列表
|
||||
```
|
||||
##项目部署
|
||||
如果你已经正确按照系统了,那么你可以输入
|
||||
```
|
||||
http://localhost:8080
|
||||
```
|
||||
会出现登陆页面:
|
||||

|
||||
|
||||
输入用户名: admin, 密码: 123456
|
||||
|
||||
## 组配置
|
||||
通过`新建`按钮配置点开配置组、场景、通知界面
|
||||

|
||||
|
||||
### 组配置
|
||||
组名称: 名称是数字、字母、下划线组合,最长64个字符长度
|
||||
状态: 开启/关闭, 通过状态开启或关闭组状态
|
||||
路由策略:
|
||||
描述:
|
||||
知道分区 :
|
||||

|
||||
|
||||
### 场景配置
|
||||
|
BIN
doc/images/login.png
Normal file
BIN
doc/images/login.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -0,0 +1,54 @@
|
||||
package com.example.demo;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.example.mapper.SchoolMapper;
|
||||
import com.example.mapper.StudentMapper;
|
||||
import com.example.po.School;
|
||||
import com.example.po.Student;
|
||||
import com.x.retry.client.core.annotation.Retryable;
|
||||
import com.x.retry.common.core.model.Result;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author: www.byteblogs.com
|
||||
* @date : 2022-03-26 09:08
|
||||
*/
|
||||
@Component
|
||||
public class TestExistsTransactionalRetryService2 {
|
||||
|
||||
@Autowired
|
||||
private SchoolMapper schoolMapper;
|
||||
|
||||
@Autowired
|
||||
private StudentMapper studentMapper;
|
||||
|
||||
@Autowired
|
||||
private RemoteService remoteService;
|
||||
|
||||
@Retryable(scene = "testSimpleUpdate", bizNo = "#name", localTimes = 5)
|
||||
@Transactional
|
||||
public String testSimpleUpdate(Long id) {
|
||||
|
||||
School school = new School();
|
||||
school.setAddress(UUID.randomUUID().toString());
|
||||
school.setCreateDt(LocalDateTime.now());
|
||||
school.setUpdateDt(LocalDateTime.now());
|
||||
schoolMapper.update(school, new LambdaQueryWrapper<School>()
|
||||
.eq(School::getId, id));
|
||||
|
||||
|
||||
Result call = remoteService.call();
|
||||
System.out.println("-------------->"+call.getMessage());
|
||||
if (call.getStatus() == 0) {
|
||||
throw new UnsupportedOperationException("调用远程失败");
|
||||
}
|
||||
|
||||
return "testSimpleInsert"+school.getAddress();
|
||||
}
|
||||
|
||||
}
|
@ -36,4 +36,6 @@ mybatis-plus:
|
||||
logging:
|
||||
config: classpath:logback-boot.xml
|
||||
|
||||
|
||||
x-retry:
|
||||
server:
|
||||
host: 192.168.100.3
|
||||
|
@ -2,6 +2,7 @@ package com.example;
|
||||
|
||||
import com.example.demo.RemoteService;
|
||||
import com.example.demo.TestExistsTransactionalRetryService;
|
||||
import com.example.demo.TestExistsTransactionalRetryService2;
|
||||
import com.x.retry.common.core.model.Result;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -27,6 +28,8 @@ public class ExistsTransactionalRetryServiceTest {
|
||||
private TestExistsTransactionalRetryService testExistsTransactionalRetryService;
|
||||
@MockBean
|
||||
private RemoteService remoteService;
|
||||
@Autowired
|
||||
private TestExistsTransactionalRetryService2 testExistsTransactionalRetryService2;
|
||||
|
||||
@SneakyThrows
|
||||
@Test
|
||||
@ -35,7 +38,7 @@ public class ExistsTransactionalRetryServiceTest {
|
||||
Mockito.when(remoteService.call())
|
||||
.thenReturn(new Result(0, "1"))
|
||||
.thenReturn(new Result(0, "2"))
|
||||
.thenReturn(new Result(0, "3"))
|
||||
.thenReturn(new Result(1, "3"))
|
||||
.thenReturn(new Result(0, "4"))
|
||||
.thenReturn(new Result(0, "5"))
|
||||
;
|
||||
@ -50,4 +53,26 @@ public class ExistsTransactionalRetryServiceTest {
|
||||
Thread.sleep(90000);
|
||||
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Test
|
||||
public void testSimpleUpdate() {
|
||||
|
||||
Mockito.when(remoteService.call())
|
||||
.thenReturn(new Result(0, "1"))
|
||||
.thenReturn(new Result(0, "2"))
|
||||
.thenReturn(new Result(0, "3"))
|
||||
.thenReturn(new Result(0, "4"))
|
||||
.thenReturn(new Result(0, "5"))
|
||||
;
|
||||
try {
|
||||
String s = testExistsTransactionalRetryService2.testSimpleUpdate(243L);
|
||||
System.out.println(s);
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
|
||||
Thread.sleep(90000);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ export default {
|
||||
|
||||
'layouts.usermenu.dialog.title': 'Message',
|
||||
'layouts.usermenu.dialog.content': 'Are you sure you would like to logout?',
|
||||
'layouts.userLayout.title': 'Ant Design is the most influential web design specification in Xihu district',
|
||||
'layouts.userLayout.title': 'Easy to use distributed exception retry service platform',
|
||||
...components,
|
||||
...global,
|
||||
...menu,
|
||||
|
@ -1,8 +1,8 @@
|
||||
export default {
|
||||
'user.login.userName': 'userName',
|
||||
'user.login.password': 'password',
|
||||
'user.login.username.placeholder': 'Account: admin',
|
||||
'user.login.password.placeholder': 'password: admin or ant.design',
|
||||
'user.login.username.placeholder': 'Please enter the username',
|
||||
'user.login.password.placeholder': 'Please enter the password',
|
||||
'user.login.message-invalid-credentials':
|
||||
'Invalid username or password',
|
||||
'user.login.message-invalid-verification-code': 'Invalid verification code',
|
||||
|
@ -21,7 +21,7 @@ export default {
|
||||
|
||||
'layouts.usermenu.dialog.title': '信息',
|
||||
'layouts.usermenu.dialog.content': '您确定要注销吗?',
|
||||
'layouts.userLayout.title': 'Ant Design 是西湖区最具影响力的 Web 设计规范',
|
||||
'layouts.userLayout.title': '简单易用的分布式异常重试服务平台',
|
||||
...components,
|
||||
...global,
|
||||
...menu,
|
||||
|
@ -1,8 +1,8 @@
|
||||
export default {
|
||||
'user.login.userName': '用户名',
|
||||
'user.login.password': '密码',
|
||||
'user.login.username.placeholder': '账户: admin',
|
||||
'user.login.password.placeholder': '密码: admin or ant.design',
|
||||
'user.login.username.placeholder': '请输入账号',
|
||||
'user.login.password.placeholder': '请输入密码',
|
||||
'user.login.message-invalid-credentials': '账户或密码错误',
|
||||
'user.login.message-invalid-verification-code': '验证码错误',
|
||||
'user.login.tab-login-credentials': '账户密码登录',
|
||||
|
@ -1,43 +0,0 @@
|
||||
package com.x.retry.client.core.init;
|
||||
|
||||
import com.x.retry.client.core.Scanner;
|
||||
import com.x.retry.client.core.config.XRetryProperties;
|
||||
import com.x.retry.client.core.register.RetryableRegistrar;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: www.byteblogs.com
|
||||
* @date : 2022-03-03 16:50
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RetryInitialize implements SmartInitializingSingleton, ApplicationContextAware {
|
||||
|
||||
@Autowired
|
||||
private List<Scanner> scanners;
|
||||
|
||||
@Autowired
|
||||
private RetryableRegistrar retryableRegistrar;
|
||||
|
||||
@Autowired
|
||||
private XRetryProperties xRetryProperties;
|
||||
|
||||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,9 @@ import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
@ -32,12 +35,14 @@ public class RetryAspect {
|
||||
@Autowired
|
||||
@Qualifier("localRetryStrategies")
|
||||
private RetryStrategy retryStrategy;
|
||||
@Autowired(required = false)
|
||||
private TransactionTemplate transactionTemplate;
|
||||
|
||||
@Around("@annotation(com.x.retry.client.core.annotation.Retryable)")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
String traceId = UUID.randomUUID().toString();
|
||||
|
||||
LogUtils.debug("进入 aop [{}]",traceId);
|
||||
LogUtils.debug("进入 aop [{}]", traceId);
|
||||
Retryable retryable = getAnnotationParameter(point);
|
||||
String executorClassName = point.getTarget().getClass().getName();
|
||||
String methodEntrance = getMethodEntrance(retryable, executorClassName);
|
||||
@ -53,26 +58,12 @@ public class RetryAspect {
|
||||
throwable = t;
|
||||
} finally {
|
||||
|
||||
if (RetrySiteSnapshot.isMethodEntrance(methodEntrance) && !RetrySiteSnapshot.isRunning() && Objects.nonNull(throwable)) {
|
||||
LogUtils.debug("开始进行重试 aop [{}]", traceId);
|
||||
try {
|
||||
// 入口则开始处理重试
|
||||
RetryerResultContext context = retryStrategy.openRetry(retryable.scene(), executorClassName, point.getArgs());
|
||||
if (RetryResultStatusEnum.SUCCESS.getStatus().equals(context.getRetryResultStatusEnum().getStatus())) {
|
||||
LogUtils.debug("aop 结果成功 traceId:[{}] result:[{}]", traceId, context.getResult());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("重试组件处理异常,{}", e);
|
||||
// TODO调用通知
|
||||
|
||||
} finally {
|
||||
RetrySiteSnapshot.removeAll();
|
||||
}
|
||||
}
|
||||
LogUtils.debug("开始进行重试 aop [{}]", traceId);
|
||||
// 入口则开始处理重试
|
||||
doHandlerRetry(point, traceId, retryable, executorClassName, methodEntrance, throwable);
|
||||
}
|
||||
|
||||
LogUtils.debug("aop 结果处理 traceId:[{}] result:[{}] ", traceId, result, throwable);
|
||||
LogUtils.debug("aop 结果处理 traceId:[{}] result:[{}] ", traceId, result, throwable);
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
} else {
|
||||
@ -81,6 +72,47 @@ public class RetryAspect {
|
||||
|
||||
}
|
||||
|
||||
private void doHandlerRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName, String methodEntrance, Throwable throwable) {
|
||||
|
||||
if (!RetrySiteSnapshot.isMethodEntrance(methodEntrance) || RetrySiteSnapshot.isRunning() || Objects.isNull(throwable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TransactionSynchronizationManager.isActualTransactionActive()) {
|
||||
// 无事务, 开启重试
|
||||
openRetry(point, traceId, retryable, executorClassName);
|
||||
return;
|
||||
}
|
||||
|
||||
// 存在事物
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
|
||||
@Override
|
||||
public void afterCompletion(int status) {
|
||||
if (STATUS_ROLLED_BACK == status) {
|
||||
|
||||
// 有事务开启重试
|
||||
openRetry(point, traceId, retryable, executorClassName);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void openRetry(ProceedingJoinPoint point, String traceId, Retryable retryable, String executorClassName) {
|
||||
try {
|
||||
RetryerResultContext context = retryStrategy.openRetry(retryable.scene(), executorClassName, point.getArgs());
|
||||
if (RetryResultStatusEnum.SUCCESS.getStatus().equals(context.getRetryResultStatusEnum().getStatus())) {
|
||||
LogUtils.debug("aop 结果成功 traceId:[{}] result:[{}]", traceId, context.getResult());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("重试组件处理异常,{}", e);
|
||||
// TODO调用通知
|
||||
|
||||
} finally {
|
||||
RetrySiteSnapshot.removeAll();
|
||||
}
|
||||
}
|
||||
|
||||
public String getMethodEntrance(Retryable retryable, String executorClassName) {
|
||||
|
||||
if (Objects.isNull(retryable)) {
|
||||
|
@ -18,4 +18,6 @@ public class RetryerResultContext {
|
||||
|
||||
private String message;
|
||||
|
||||
private Throwable throwable;
|
||||
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public abstract class AbstractRetryStrategies implements RetryStrategy {
|
||||
|
||||
private Consumer<Throwable> getRetryErrorConsumer(RetryerResultContext context, Object... params) {
|
||||
return throwable -> {
|
||||
|
||||
context.setThrowable(throwable);
|
||||
context.setMessage(throwable.getMessage());
|
||||
|
||||
error(context);
|
||||
|
@ -9,5 +9,4 @@ EXPOSE 1788
|
||||
|
||||
WORKDIR /
|
||||
|
||||
#开机启动
|
||||
ENTRYPOINT ["java","-jar","x-retry-server.jar"]
|
||||
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /x-retry-server.jar $PARAMS"]
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.x.retry.server.support.dispatch.actor.result;
|
||||
|
||||
import akka.actor.AbstractActor;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.x.retry.common.core.enums.RetryStatusEnum;
|
||||
import com.x.retry.common.core.log.LogUtils;
|
||||
import com.x.retry.common.core.util.Assert;
|
||||
@ -60,9 +61,6 @@ public class FailureActor extends AbstractActor {
|
||||
retryTask.setRetryStatus(RetryStatusEnum.MAX_RETRY_COUNT.getLevel());
|
||||
}
|
||||
|
||||
RetryTaskLog retryTaskLog = new RetryTaskLog();
|
||||
retryTaskLog.setErrorMessage(StringUtils.EMPTY);
|
||||
|
||||
try {
|
||||
retryTaskAccess.updateRetryTask(retryTask);
|
||||
} catch (Exception e) {
|
||||
@ -71,11 +69,11 @@ public class FailureActor extends AbstractActor {
|
||||
getContext().stop(getSelf());
|
||||
|
||||
// 记录重试日志
|
||||
BeanUtils.copyProperties(retryTask, retryTaskLog);
|
||||
retryTaskLog.setCreateDt(LocalDateTime.now());
|
||||
retryTaskLog.setId(null);
|
||||
Assert.isTrue(1 == retryTaskLogMapper.insert(retryTaskLog),
|
||||
new XRetryServerException("新增重试日志失败"));
|
||||
RetryTaskLog retryTaskLog = new RetryTaskLog();
|
||||
retryTaskLog.setRetryStatus(retryTask.getRetryStatus());
|
||||
Assert.isTrue(1 == retryTaskLogMapper.update(retryTaskLog,
|
||||
new LambdaQueryWrapper<RetryTaskLog>().eq(RetryTaskLog::getBizId, retryTask.getBizId())),
|
||||
new XRetryServerException("更新重试日志失败"));
|
||||
}
|
||||
|
||||
}).build();
|
||||
|
@ -49,8 +49,6 @@ public class FinishActor extends AbstractActor {
|
||||
|
||||
retryTask.setRetryStatus(RetryStatusEnum.FINISH.getLevel());
|
||||
|
||||
RetryTaskLog retryTaskLog = new RetryTaskLog();
|
||||
retryTaskLog.setErrorMessage(StringUtils.EMPTY);
|
||||
|
||||
try {
|
||||
retryTaskAccess.updateRetryTask(retryTask);
|
||||
@ -61,11 +59,11 @@ public class FinishActor extends AbstractActor {
|
||||
getContext().stop(getSelf());
|
||||
|
||||
// 记录重试日志
|
||||
BeanUtils.copyProperties(retryTask, retryTaskLog);
|
||||
retryTaskLog.setCreateDt(LocalDateTime.now());
|
||||
retryTaskLog.setId(null);
|
||||
Assert.isTrue(1 == retryTaskLogMapper.insert(retryTaskLog),
|
||||
new XRetryServerException("新增重试日志失败"));
|
||||
RetryTaskLog retryTaskLog = new RetryTaskLog();
|
||||
retryTaskLog.setRetryStatus(retryTask.getRetryStatus());
|
||||
Assert.isTrue(1 == retryTaskLogMapper.update(retryTaskLog,
|
||||
new LambdaQueryWrapper<RetryTaskLog>().eq(RetryTaskLog::getBizId, retryTask.getBizId())),
|
||||
new XRetryServerException("更新重试日志失败"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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>X-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-1ab37f3c.3d18d222.css" rel="prefetch"><link href="/css/chunk-25728828.1a0c6d40.css" rel="prefetch"><link href="/css/chunk-7da4eb58.e728df71.css" rel="prefetch"><link href="/css/chunk-8b6319a2.2634f734.css" rel="prefetch"><link href="/css/user.6ccd4506.css" rel="prefetch"><link href="/js/chunk-182ca22a.03fcf245.js" rel="prefetch"><link href="/js/chunk-1ab37f3c.8de58c12.js" rel="prefetch"><link href="/js/chunk-2187724d.750eefe4.js" rel="prefetch"><link href="/js/chunk-2515aa86.56b830ae.js" rel="prefetch"><link href="/js/chunk-25728828.72403b96.js" rel="prefetch"><link href="/js/chunk-2672acfa.f21ce0e0.js" rel="prefetch"><link href="/js/chunk-35f6c8ac.ba9dc4ea.js" rel="prefetch"><link href="/js/chunk-3f8d11fc.0a406521.js" rel="prefetch"><link href="/js/chunk-7da4eb58.42370445.js" rel="prefetch"><link href="/js/chunk-8b6319a2.ce4381a7.js" rel="prefetch"><link href="/js/chunk-a31b7d0a.26cf2cba.js" rel="prefetch"><link href="/js/chunk-c70de2f6.079cc723.js" rel="prefetch"><link href="/js/chunk-f6267108.805d13c0.js" rel="prefetch"><link href="/js/fail.2fbe761d.js" rel="prefetch"><link href="/js/lang-zh-CN-account-settings.c67af352.js" rel="prefetch"><link href="/js/lang-zh-CN-account.ae001550.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard-analysis.2fc3e69f.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard.99f39538.js" rel="prefetch"><link href="/js/lang-zh-CN-form-basicForm.2de7abab.js" rel="prefetch"><link href="/js/lang-zh-CN-form.827c727b.js" rel="prefetch"><link href="/js/lang-zh-CN-global.2ab19788.js" rel="prefetch"><link href="/js/lang-zh-CN-menu.3e33ed30.js" rel="prefetch"><link href="/js/lang-zh-CN-result-fail.e3747840.js" rel="prefetch"><link href="/js/lang-zh-CN-result-success.349556c5.js" rel="prefetch"><link href="/js/lang-zh-CN-result.ae8b0e63.js" rel="prefetch"><link href="/js/lang-zh-CN-setting.78d9e9d1.js" rel="prefetch"><link href="/js/lang-zh-CN-user.f0b0e0c8.js" rel="prefetch"><link href="/js/lang-zh-CN.d4df1883.js" rel="prefetch"><link href="/js/user.5bc5ffe1.js" rel="prefetch"><link href="/css/app.7dac075b.css" rel="preload" as="style"><link href="/css/chunk-vendors.f716a607.css" rel="preload" as="style"><link href="/js/app.fbb09a18.js" rel="preload" as="script"><link href="/js/chunk-vendors.7a131374.js" rel="preload" as="script"><link href="/css/chunk-vendors.f716a607.css" rel="stylesheet"><link href="/css/app.7dac075b.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"><h1>X-RETRY</h1><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;">X-RETRY</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.7a131374.js"></script><script src="/js/app.fbb09a18.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>X-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-1ab37f3c.3d18d222.css" rel="prefetch"><link href="/css/chunk-25728828.1a0c6d40.css" rel="prefetch"><link href="/css/chunk-7da4eb58.e728df71.css" rel="prefetch"><link href="/css/chunk-8b6319a2.2634f734.css" rel="prefetch"><link href="/css/user.6ccd4506.css" rel="prefetch"><link href="/js/chunk-182ca22a.8c34614c.js" rel="prefetch"><link href="/js/chunk-1ab37f3c.6610a799.js" rel="prefetch"><link href="/js/chunk-2187724d.5ce67d3e.js" rel="prefetch"><link href="/js/chunk-2515aa86.e77b4462.js" rel="prefetch"><link href="/js/chunk-25728828.58065cc5.js" rel="prefetch"><link href="/js/chunk-2672acfa.a463d565.js" rel="prefetch"><link href="/js/chunk-35f6c8ac.0e2089f4.js" rel="prefetch"><link href="/js/chunk-3f8d11fc.36654171.js" rel="prefetch"><link href="/js/chunk-7da4eb58.f8e4729e.js" rel="prefetch"><link href="/js/chunk-8b6319a2.08c27435.js" rel="prefetch"><link href="/js/chunk-a31b7d0a.583cee66.js" rel="prefetch"><link href="/js/chunk-c70de2f6.c1b55ec1.js" rel="prefetch"><link href="/js/chunk-f6267108.b893984c.js" rel="prefetch"><link href="/js/fail.a308c208.js" rel="prefetch"><link href="/js/lang-zh-CN-account-settings.c67af352.js" rel="prefetch"><link href="/js/lang-zh-CN-account.31178b83.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard-analysis.2fc3e69f.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard.8c2660f7.js" rel="prefetch"><link href="/js/lang-zh-CN-form-basicForm.2de7abab.js" rel="prefetch"><link href="/js/lang-zh-CN-form.9e72dbc7.js" rel="prefetch"><link href="/js/lang-zh-CN-global.2ab19788.js" rel="prefetch"><link href="/js/lang-zh-CN-menu.3e33ed30.js" rel="prefetch"><link href="/js/lang-zh-CN-result-fail.e3747840.js" rel="prefetch"><link href="/js/lang-zh-CN-result-success.349556c5.js" rel="prefetch"><link href="/js/lang-zh-CN-result.5e7f6923.js" rel="prefetch"><link href="/js/lang-zh-CN-setting.78d9e9d1.js" rel="prefetch"><link href="/js/lang-zh-CN-user.696e6d3c.js" rel="prefetch"><link href="/js/lang-zh-CN.4df4bdd0.js" rel="prefetch"><link href="/js/user.2123b527.js" rel="prefetch"><link href="/css/app.7dac075b.css" rel="preload" as="style"><link href="/css/chunk-vendors.f716a607.css" rel="preload" as="style"><link href="/js/app.3d45d60a.js" rel="preload" as="script"><link href="/js/chunk-vendors.a56c9037.js" rel="preload" as="script"><link href="/css/chunk-vendors.f716a607.css" rel="stylesheet"><link href="/css/app.7dac075b.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"><h1>X-RETRY</h1><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;">X-RETRY</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.a56c9037.js"></script><script src="/js/app.3d45d60a.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
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["lang-zh-CN-user"],{2518:function(e,r,s){"use strict";s.r(r),r["default"]={"user.login.userName":"用户名","user.login.password":"密码","user.login.username.placeholder":"请输入账号","user.login.password.placeholder":"请输入密码","user.login.message-invalid-credentials":"账户或密码错误","user.login.message-invalid-verification-code":"验证码错误","user.login.tab-login-credentials":"账户密码登录","user.login.tab-login-mobile":"手机号登录","user.login.mobile.placeholder":"手机号","user.login.mobile.verification-code.placeholder":"验证码","user.login.remember-me":"自动登录","user.login.forgot-password":"忘记密码","user.login.sign-in-with":"其他登录方式","user.login.signup":"注册账户","user.login.login":"登录","user.register.register":"注册","user.register.email.placeholder":"邮箱","user.register.password.placeholder":"请至少输入 6 个字符。请不要使用容易被猜到的密码。","user.register.password.popover-message":"请至少输入 6 个字符。请不要使用容易被猜到的密码。","user.register.confirm-password.placeholder":"确认密码","user.register.get-verification-code":"获取验证码","user.register.sign-in":"使用已有账户登录","user.register-result.msg":"你的账户:{email} 注册成功","user.register-result.activation-email":"激活邮件已发送到你的邮箱中,邮件有效期为24小时。请及时登录邮箱,点击邮件中的链接激活帐户。","user.register-result.back-home":"返回首页","user.register-result.view-mailbox":"查看邮箱","user.email.required":"请输入邮箱地址!","user.email.wrong-format":"邮箱地址格式错误!","user.userName.required":"请输入帐户名或邮箱地址","user.password.required":"请输入密码!","user.password.twice.msg":"两次输入的密码不匹配!","user.password.strength.msg":"密码强度不够 ","user.password.strength.strong":"强度:强","user.password.strength.medium":"强度:中","user.password.strength.low":"强度:低","user.password.strength.short":"强度:太短","user.confirm-password.required":"请确认密码!","user.phone-number.required":"请输入正确的手机号","user.phone-number.wrong-format":"手机号格式错误!","user.verification-code.required":"请输入验证码!"}}}]);
|
@ -1 +0,0 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["lang-zh-CN-user"],{2518:function(e,r,s){"use strict";s.r(r),r["default"]={"user.login.userName":"用户名","user.login.password":"密码","user.login.username.placeholder":"账户: admin","user.login.password.placeholder":"密码: admin or ant.design","user.login.message-invalid-credentials":"账户或密码错误","user.login.message-invalid-verification-code":"验证码错误","user.login.tab-login-credentials":"账户密码登录","user.login.tab-login-mobile":"手机号登录","user.login.mobile.placeholder":"手机号","user.login.mobile.verification-code.placeholder":"验证码","user.login.remember-me":"自动登录","user.login.forgot-password":"忘记密码","user.login.sign-in-with":"其他登录方式","user.login.signup":"注册账户","user.login.login":"登录","user.register.register":"注册","user.register.email.placeholder":"邮箱","user.register.password.placeholder":"请至少输入 6 个字符。请不要使用容易被猜到的密码。","user.register.password.popover-message":"请至少输入 6 个字符。请不要使用容易被猜到的密码。","user.register.confirm-password.placeholder":"确认密码","user.register.get-verification-code":"获取验证码","user.register.sign-in":"使用已有账户登录","user.register-result.msg":"你的账户:{email} 注册成功","user.register-result.activation-email":"激活邮件已发送到你的邮箱中,邮件有效期为24小时。请及时登录邮箱,点击邮件中的链接激活帐户。","user.register-result.back-home":"返回首页","user.register-result.view-mailbox":"查看邮箱","user.email.required":"请输入邮箱地址!","user.email.wrong-format":"邮箱地址格式错误!","user.userName.required":"请输入帐户名或邮箱地址","user.password.required":"请输入密码!","user.password.twice.msg":"两次输入的密码不匹配!","user.password.strength.msg":"密码强度不够 ","user.password.strength.strong":"强度:强","user.password.strength.medium":"强度:中","user.password.strength.low":"强度:低","user.password.strength.short":"强度:太短","user.confirm-password.required":"请确认密码!","user.phone-number.required":"请输入正确的手机号","user.phone-number.wrong-format":"手机号格式错误!","user.verification-code.required":"请输入验证码!"}}}]);
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,4 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
datasource:
|
||||
name: x_retry
|
||||
url: jdbc:mysql://localhost:3306/x_retry?useSSL=false&characterEncoding=utf8&useUnicode=true
|
||||
@ -32,6 +30,10 @@ mybatis-plus:
|
||||
map-underscore-to-camel-case: true
|
||||
cache-enabled: true
|
||||
|
||||
|
||||
x-retry:
|
||||
lastDays: 30 # 拉取重试数据的天数
|
||||
retryPullPageSize: 100 # 拉取重试数据的每批次的大小
|
||||
nettyPort: 1788 # 服务端netty端口
|
||||
totalPartition: 32 # 重试和死信表的分区总数
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user