业务相关参数详解
1. 概述
在实际业务场景中,SnailJob 支持通过一系列业务参数实现更灵活的重试任务管理,包括幂等ID、业务编号、重试方法、回调方法等。合理配置这些参数,可以实现任务唯一性、业务追踪、自定义重试与回调逻辑等高级功能。
2. 参数说明
参数 | 描述 | 默认值 | 必须指定 |
---|---|---|---|
idempotentId | 幂等id生成器 | SimpleIdempotentIdGenerate | ✅ |
retryMethod | 重试处理入口 | ExecutorAnnotationMethod | ✅ |
retryCompleteCallback | 服务端重试完成(重试成功、重试到达最大次数)回调客户端 | SimpleRetryCompleteCallback | ❌ |
bizNo | 标识具有业务特点的值比如订单号、物流编号等,可以根据具体的业务场景生成,生成规则采用Spel表达式解析。 | 无 | ❌ |
2.1 idempotentId(幂等ID生成器)
- 作用:保证每个重试任务的唯一性,防止重复任务。
- 默认实现:SimpleIdempotentIdGenerate,基于场景、执行器、参数、方法名等信息生成MD5。
- 自定义:可实现 IdempotentIdGenerate 接口,按需定制唯一ID生成规则。
- 示例代码:java
public class SimpleIdempotentIdGenerate implements IdempotentIdGenerate { @Override public String idGenerate(IdempotentIdGenerateEntity idempotentIdGenerateEntity) throws Exception { return SecureUtil.md5(idempotentIdGenerateEntity.toString()); } }
2.2 bizNo(业务编号)
- 作用:用于标识具有业务特点的值如订单号、物流编号等,便于控制台检索和追踪。
- 用法:支持SpEL表达式,如
bizNo = "orderVo.orderId"
。 - 示例代码:java
@Retryable(scene = "remoteRetryWithBizNo", retryStrategy = RetryType.ONLY_REMOTE, bizNo = "orderVo.orderId") public boolean remoteRetryWithBizNo(OrderVo orderVo) { throw new NullPointerException(); }
2.3 retryMethod(重试处理入口)
- 作用:自定义重试函数的入口方法。
- 默认实现:ExecutorAnnotationMethod,反射调用原重试方法。
- 自定义:实现 ExecutorMethod 接口,按需定制重试逻辑。
- 示例代码:java
@Slf4j public class ExecutorAnnotationMethod implements ExecutorMethod { private RetryerInfo retryerInfo; public ExecutorAnnotationMethod(RetryerInfo retryerInfo) { this.retryerInfo = retryerInfo; } @Override public Object doExecute(Object params) { Class<?>[] paramTypes = retryerInfo.getMethod().getParameterTypes(); LogUtils.info(log, "执行原重试方法:[{}],参数为:[{}]", retryerInfo.getExecutorClassName(), JsonUtil.toJsonString(params)); if (paramTypes.length > 0) { return ReflectionUtils.invokeMethod(retryerInfo.getMethod(), retryerInfo.getExecutor(), (Object[]) params); } else { return ReflectionUtils.invokeMethod(retryerInfo.getMethod(), retryerInfo.getExecutor()); } } } public interface ExecutorMethod { Object doExecute(Object params); }
- 自定义方法示例:java
@Component public class OrderRetryMethod implements ExecutorMethod { @Override public Object doExecute(Object params) { Object[] args = (Object[]) params; OrderVo orderVo = (OrderVo) args[0]; log.info("进入自定义的回调方法,参数信息是{}", JSONUtil.toJsonStr(orderVo)); throw new ArithmeticException(); } } @Retryable(scene = "remoteRetryWithRetryMethod", retryStrategy = RetryType.ONLY_REMOTE, retryMethod = OrderRetryMethod.class) public boolean remoteRetryWithRetryMethod(OrderVo orderVo) { throw new NullPointerException(); }
2.4 retryCompleteCallback(重试完成回调)
- 作用:自定义重试完成(成功或到达最大次数)后的回调逻辑。
- 默认实现:SimpleRetryCompleteCallback,默认无操作。
- 自定义:实现 RetryCompleteCallback 接口,按需处理成功/失败回调。
- 示例代码:java
@Component @Slf4j public class SimpleRetryCompleteCallback implements RetryCompleteCallback { @Override public void doSuccessCallback(String sceneName, String executorName, Object[] params) {} @Override public void doMaxRetryCallback(String sceneName, String executorName, Object[] params) {} } // 自定义回调 @Slf4j public class OrderCompleteCallback implements RetryCompleteCallback { @Autowired private FailOrderBaseMapper failOrderBaseMapper; @Override public void doSuccessCallback(String sceneName, String executorName, Object[] objects) { OrderVo orderVo = (OrderVo) objects[0]; log.info("远程重试成功,场景{},执行器{},参数信息",sceneName,executorName, JSONUtil.toJsonStr(objects)); failOrderBaseMapper.delete( new LambdaQueryChainWrapper<>(failOrderBaseMapper) .eq(FailOrderPo::getOrderId,orderVo.getOrderId()) ); } @Override public void doMaxRetryCallback(String sceneName, String executorName, Object[] objects) { OrderVo orderVo = (OrderVo) objects[0]; log.info("远程重试达到最大限度,场景{},执行器{},参数信息",sceneName,executorName, JSONUtil.toJsonStr(objects)); failOrderBaseMapper.insert(FailOrderPo.builder() .orderId(orderVo.getOrderId()) .sourceId(orderVo.getSource()) .sceneName(sceneName) .executorName(executorName) .args(JSONUtil.toJsonStr(objects)) .build()); } } @Retryable(scene = "remoteRetryWithCompleteCallback", retryStrategy = RetryType.LOCAL_REMOTE, retryCompleteCallback = OrderCompleteCallback.class) public boolean remoteRetryWithCompleteCallback(OrderVo orderVo) { Random random = new Random(); double probability = random.nextDouble(); if (probability <= 0.5) { throw new NullPointerException(); } return true; }
3. 配置与代码示例
3.1 幂等ID自定义场景
java
@Data
public class OrderVo {
private String orderId; // 订单ID,用于唯一标识订单的编号
private Integer source; // 订单来源信息,1-手机端下单 2-PC端下单
}
public class OrderIdempotentIdGenerate implements IdempotentIdGenerate {
@Override
public String idGenerate(IdempotentIdContext idempotentIdContext) throws Exception {
Object[] args = idempotentIdContext.getArgs();
OrderVo orderVo = (OrderVo) args[0];
return SecureUtil.md5(orderVo.getOrderId());
}
}
@Retryable(scene = "remoteRetryWithIdempotentId", retryStrategy = RetryType.ONLY_REMOTE, idempotentId = OrderIdempotentIdGenerate.class)
public boolean remoteRetryWithIdempotentId(OrderVo orderVo) {
double i = 1 / 0;
return true;
}
- 多端下单同一订单号只生成一次重试任务。
3.2 业务编号追踪场景
java
@Retryable(scene = "remoteRetryWithBizNo", retryStrategy = RetryType.ONLY_REMOTE, bizNo = "orderVo.orderId")
public boolean remoteRetryWithBizNo(OrderVo orderVo) {
throw new NullPointerException();
}
- 控制台可通过业务编号快速检索重试任务。
3.3 自定义重试方法与回调场景
见上文 retryMethod 与 retryCompleteCallback 示例。
4. 最佳实践
- 业务唯一性强的场景建议自定义幂等ID生成规则,防止重复任务。
- 充分利用 bizNo 便于业务追踪和控制台检索。
- 复杂业务可自定义 retryMethod 和 retryCompleteCallback,实现更灵活的重试与回调逻辑。
- 结合实际业务需求合理配置各参数,提升系统健壮性与可维护性。