引入重试机制

沃森川job同步飞书
YXY 1 year ago
parent 996bcefc98
commit aafa9df04d

@ -6,6 +6,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
@ -18,10 +19,9 @@ import org.springframework.stereotype.Component;
*
* @author ruoyi
**/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@SuppressWarnings(value = {"unchecked", "rawtypes"})
@Component
public class RedisCache
{
public class RedisCache {
@Autowired
public RedisTemplate redisTemplate;
@ -31,8 +31,7 @@ public class RedisCache
* @param key
* @param value
*/
public <T> void setCacheObject(final String key, final T value)
{
public <T> void setCacheObject(final String key, final T value) {
redisTemplate.opsForValue().set(key, value);
}
@ -44,12 +43,11 @@ public class RedisCache
* @param timeout
* @param timeUnit
*/
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
{
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
public Long getExpireTime(String key){
public Long getExpireTime(String key) {
return redisTemplate.getExpire(key);
}
@ -60,8 +58,7 @@ public class RedisCache
* @param timeout
* @return true=false=
*/
public boolean expire(final String key, final long timeout)
{
public boolean expire(final String key, final long timeout) {
return expire(key, timeout, TimeUnit.SECONDS);
}
@ -73,8 +70,7 @@ public class RedisCache
* @param unit
* @return true=false=
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit)
{
public boolean expire(final String key, final long timeout, final TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
@ -84,8 +80,7 @@ public class RedisCache
* @param key
* @return
*/
public <T> T getCacheObject(final String key)
{
public <T> T getCacheObject(final String key) {
ValueOperations<String, T> operation = redisTemplate.opsForValue();
return operation.get(key);
}
@ -95,8 +90,7 @@ public class RedisCache
*
* @param key
*/
public boolean deleteObject(final String key)
{
public boolean deleteObject(final String key) {
return redisTemplate.delete(key);
}
@ -106,8 +100,7 @@ public class RedisCache
* @param collection
* @return
*/
public long deleteObject(final Collection collection)
{
public long deleteObject(final Collection collection) {
return redisTemplate.delete(collection);
}
@ -118,8 +111,7 @@ public class RedisCache
* @param dataList List
* @return
*/
public <T> long setCacheList(final String key, final List<T> dataList)
{
public <T> long setCacheList(final String key, final List<T> dataList) {
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
@ -130,8 +122,7 @@ public class RedisCache
* @param key
* @return
*/
public <T> List<T> getCacheList(final String key)
{
public <T> List<T> getCacheList(final String key) {
return redisTemplate.opsForList().range(key, 0, -1);
}
@ -142,12 +133,10 @@ public class RedisCache
* @param dataSet
* @return
*/
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
{
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
Iterator<T> it = dataSet.iterator();
while (it.hasNext())
{
while (it.hasNext()) {
setOperation.add(it.next());
}
return setOperation;
@ -159,8 +148,7 @@ public class RedisCache
* @param key
* @return
*/
public <T> Set<T> getCacheSet(final String key)
{
public <T> Set<T> getCacheSet(final String key) {
return redisTemplate.opsForSet().members(key);
}
@ -170,8 +158,7 @@ public class RedisCache
* @param key
* @param dataMap
*/
public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
{
public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
if (dataMap != null) {
redisTemplate.opsForHash().putAll(key, dataMap);
}
@ -183,8 +170,7 @@ public class RedisCache
* @param key
* @return
*/
public <T> Map<String, T> getCacheMap(final String key)
{
public <T> Map<String, T> getCacheMap(final String key) {
return redisTemplate.opsForHash().entries(key);
}
@ -195,8 +181,7 @@ public class RedisCache
* @param hKey Hash
* @param value
*/
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
{
public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
redisTemplate.opsForHash().put(key, hKey, value);
}
@ -207,8 +192,7 @@ public class RedisCache
* @param hKey Hash
* @return Hash
*/
public <T> T getCacheMapValue(final String key, final String hKey)
{
public <T> T getCacheMapValue(final String key, final String hKey) {
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
return opsForHash.get(key, hKey);
}
@ -220,8 +204,7 @@ public class RedisCache
* @param hKeys Hash
* @return Hash
*/
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
{
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
return redisTemplate.opsForHash().multiGet(key, hKeys);
}
@ -231,8 +214,16 @@ public class RedisCache
* @param pattern
* @return
*/
public Collection<String> keys(final String pattern)
{
public Collection<String> keys(final String pattern) {
return redisTemplate.keys(pattern);
}
public void rightPush(String key, Object obj) {
redisTemplate.opsForList().rightPush(key, obj);
}
public Object leftPop(String key) {
return redisTemplate.opsForList().leftPop(key);
}
}

@ -37,4 +37,13 @@ public enum AppType {
public String getInfo() {
return info;
}
public static AppType getByCode(String code){
for (AppType value : AppType.values()) {
if (value.getCode().equals(code)){
return value;
}
}
return null;
}
}

@ -23,6 +23,8 @@ public class MailInfoController extends BaseController {
@Autowired
private MonitorJobTask monitorJobTask;
@Autowired
private RetryErrorSyncJob retryErrorSyncJob;
@Autowired
private ManufactureOrderSyncJob manufactureOrderSyncJob;
@Autowired
private PurchaseArrivalOpenSyncJob purchaseArrivalOpenSyncJob;

@ -0,0 +1,37 @@
package com.ruoyi.quartz.domain;
import com.ruoyi.common.utils.DateUtils;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author yuxiangyong
* @create 2023-07-17 20:31
*/
@Data
@NoArgsConstructor
public class CJTRetryRequest implements Serializable {
private LocalDateTime executeTime;
private Integer count;
public CJTRetryRequest(LocalDateTime executeTime, Integer count) {
this.executeTime = executeTime;
this.count = count;
}
public void addCount(){
count++;
}
public String getQueryFrom(Long reduceMinutes){
return DateUtils.ldt2str(executeTime.minusMinutes(reduceMinutes),DateUtils.YYYY_MM_DD_HH_MM_SS);
}
public String getQueryTo(){
return DateUtils.ldt2str(executeTime,DateUtils.YYYY_MM_DD_HH_MM_SS);
}
}

@ -0,0 +1,110 @@
package com.ruoyi.quartz.task.CJT;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.AppType;
import com.ruoyi.quartz.domain.CJTRetryRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
/**
* @author yuxiangyong
* @create 2023-08-02 20:14
*/
@Slf4j
@Component("retryErrorSyncJob")
public class RetryErrorSyncJob {
@Autowired
private RedisCache redisCache;
@Autowired
private ManufactureOrderSyncJob manufactureOrderSyncJob;
@Autowired
private PurchaseArrivalOpenSyncJob purchaseArrivalOpenSyncJob;
@Autowired
private PurchaseOrderSyncJob purchaseOrderSyncJob;
@Autowired
private SaleDeliverySyncJob saleDeliverySyncJob;
@Autowired
private SaleDispatchSyncJob saleDispatchSyncJob;
@Autowired
private SaleOrderSyncJob saleOrderSyncJob;
public void execute(String appTypeCode) {
AppType appType = AppType.getByCode(appTypeCode);
if (appType != null) {
executeDetail(appType);
}
}
public void execute() {
List<AppType> retryJobList = retryJobList();
for (AppType retryJobType : retryJobList) {
executeDetail(retryJobType);
}
}
private void executeDetail(AppType retryJobType) {
CJTRetryRequest request = null;
String retryKey = null;
switch (retryJobType) {
case SYNC_CJT_MANUFACTURE_ORDER_DATA_TO_MULTI_TABLE:
retryKey = manufactureOrderSyncJob.getRetryKey();
do {
request = (CJTRetryRequest) redisCache.leftPop(retryKey);
manufactureOrderSyncJob.execute(request);
} while (request != null);
break;
case SYNC_CJT_PURCHASE_ARRIVAL_ORDER_DATA_TO_MULTI_TABLE:
retryKey = purchaseArrivalOpenSyncJob.getRetryKey();
do {
request = (CJTRetryRequest) redisCache.leftPop(retryKey);
purchaseArrivalOpenSyncJob.execute(request);
} while (request != null);
break;
case SYNC_CJT_PURCHASE_ORDER_DATA_TO_MULTI_TABLE:
retryKey = purchaseOrderSyncJob.getRetryKey();
do {
request = (CJTRetryRequest) redisCache.leftPop(retryKey);
purchaseOrderSyncJob.execute(request);
} while (request != null);
break;
case SYNC_CJT_SALE_DELIVERY_DATA_TO_MULTI_TABLE:
retryKey = saleDeliverySyncJob.getRetryKey();
do {
request = (CJTRetryRequest) redisCache.leftPop(retryKey);
saleDeliverySyncJob.execute(request);
} while (request != null);
break;
case SYNC_CJT_SALE_ORDER_DATA_TO_MULTI_TABLE:
retryKey = saleOrderSyncJob.getRetryKey();
do {
request = (CJTRetryRequest) redisCache.leftPop(retryKey);
saleOrderSyncJob.execute(request);
} while (request != null);
break;
case SYNC_CJT_SALE_DISPATCH_DATA_TO_MULTI_TABLE:
retryKey = saleDispatchSyncJob.getRetryKey();
do {
request = (CJTRetryRequest) redisCache.leftPop(retryKey);
saleDispatchSyncJob.execute(request);
} while (request != null);
break;
default:
break;
}
}
public List<AppType> retryJobList() {
return Arrays.asList(
AppType.SYNC_CJT_MANUFACTURE_ORDER_DATA_TO_MULTI_TABLE,
AppType.SYNC_CJT_PURCHASE_ARRIVAL_ORDER_DATA_TO_MULTI_TABLE,
AppType.SYNC_CJT_PURCHASE_ORDER_DATA_TO_MULTI_TABLE,
AppType.SYNC_CJT_SALE_DELIVERY_DATA_TO_MULTI_TABLE,
AppType.SYNC_CJT_SALE_ORDER_DATA_TO_MULTI_TABLE,
AppType.SYNC_CJT_SALE_DISPATCH_DATA_TO_MULTI_TABLE
);
}
}

@ -65,6 +65,10 @@ public abstract class SyncAccountsJobAbstract {
private static final String CJT_APP_KEY = "wwjSb5Vl";
private static final String CJT_APP_SECRET = "C661F71361CC4C5636396480FF08BBA4";
public static final String RETRY_KEY = "RETRY_CJT:%s";
private static final Long REDUCE_MINUTES = 4L;
/**
*
*/
@ -83,10 +87,50 @@ public abstract class SyncAccountsJobAbstract {
*/
private static final String CERTIFICATE = "OXYwHSWAc22UPHxfIUM0SSFZwziCLmBfOzBaN+PCNp0SNfV3ewYIaWLJCCrYToCU46x3PJO8t4TXV57bGpbiqClld5DiAkQ3EX1qqxoyaE9J0HAsfnp/PkPurKMQewBHICM2oEPRyLU5GUQjTCucfLvO4xT3DKlelbjBsIkKLqs=";
public void executeSync(String queryFromTime,String queryToTime) {
private CJTJobContext initContext(String queryFromTime,String queryToTime,LocalDateTime now){
CJTJobContext context = new CJTJobContext();
if (!StringUtils.isEmpty(queryFromTime)){
queryFromTime = DateUtils.ldt2str(now.minusMinutes(REDUCE_MINUTES), DateUtils.YYYY_MM_DD_HH_MM_SS);
}
context.setQueryFromTime(queryFromTime);
if (!StringUtils.isEmpty(queryToTime)){
queryToTime = DateUtils.ldt2str(now, DateUtils.YYYY_MM_DD_HH_MM_SS);
}
context.setQueryToTime(queryToTime);
return context;
}
public void execute(CJTRetryRequest request) {
if (request == null){
return;
}
CJTJobContext context = new CJTJobContext();
context.setQueryFromTime(request.getQueryFrom(REDUCE_MINUTES));
context.setQueryToTime(request.getQueryTo());
try {
log.info("===================== {} {} retry strat ======================",this.getClassName(),context.getQueryToTime());
//初始化飞书信息及相关配置
initLarkInfo(context);
//重置ticket
resetTicket(context);
//执行分页同步
sync(context);
} catch (Exception e) {
log.error("{} ", getClassName(), e);
if (request.getCount() == 2){
larkRobotHelper.sendMessageByBot(ROBOT_GROUP, buildRobotErrorCountMessage(e,request));
}else {
request.addCount();
redisCache.rightPush(getRetryKey(),request);
}
}finally {
log.info("===================== {} {} retry end ======================",this.getClassName(),context.getQueryToTime());
}
}
public void executeSync(String queryFromTime,String queryToTime) {
LocalDateTime now = LocalDateTime.now();
CJTJobContext context = initContext(queryFromTime,queryToTime,now);
try {
log.info("===================== {} strat ======================",this.getClassName());
//初始化飞书信息及相关配置
@ -96,15 +140,32 @@ public abstract class SyncAccountsJobAbstract {
//执行分页同步
sync(context);
} catch (Exception e) {
log.error("{} 执行失败"
, getClassName()
, e);
larkRobotHelper.sendMessageByBot(ROBOT_GROUP, buildRobotErrorMessage(e));
log.error("{} 执行失败", getClassName(), e);
CJTRetryRequest request = new CJTRetryRequest(now,1);
redisCache.rightPush(getRetryKey(),request);
}finally {
log.info("===================== {} end ======================",this.getClassName());
}
}
public String getRetryKey(){
return String.format(RETRY_KEY, syncLarkAppType().getCode());
}
private String buildRobotErrorCountMessage(Exception e,CJTRetryRequest request){
JSONObject jsonObject = new JSONObject();
jsonObject.put("同步任务",getClassName());
jsonObject.put("重试失败",request.getCount());
jsonObject.put("重试开始时间",request.getQueryFrom(REDUCE_MINUTES));
jsonObject.put("重试结束时间",request.getQueryTo());
String errorMessage = e.getMessage();
if (org.apache.commons.lang3.StringUtils.isNotBlank(errorMessage)){
errorMessage = errorMessage.replaceAll("\\\\","");
}
jsonObject.put("异常信息", errorMessage);
return jsonObject.toJSONString();
}
private String buildRobotErrorMessage(Exception e){
JSONObject jsonObject = new JSONObject();
jsonObject.put("同步任务",getClassName());
@ -150,7 +211,7 @@ public abstract class SyncAccountsJobAbstract {
LocalDateTime now = LocalDateTime.now();
String startTime = context.getQueryFromTime();
if (StringUtils.isEmpty(startTime)){
startTime = DateUtils.ldt2str(now.minusMinutes(4L), DateUtils.YYYY_MM_DD_HH_MM_SS);
startTime = DateUtils.ldt2str(now.minusMinutes(REDUCE_MINUTES), DateUtils.YYYY_MM_DD_HH_MM_SS);
}
String endTime = context.getQueryToTime();
if (StringUtils.isEmpty(endTime)){

Loading…
Cancel
Save