Browse Source

异步计算,根据客户加锁,同一个客户同时只能有一个线程执行计算。

dev_shibei_match
wxz 5 years ago
parent
commit
c426ba5b08
  1. 11
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java
  2. 41
      epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/controller/IndexCalculateController.java

11
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java

@ -305,4 +305,15 @@ public class RedisKeys {
public static String getIndexCodeFieldReKey() {
return rootPrefix.concat("data:index:indexcode:field");
}
/**
* 客户统计的计算标记
* 0:未在计算
* 1:正在计算
* @param customerId
* @return
*/
public static String getCustomerStatsCalFlag(String customerId) {
return String.format(rootPrefix+"stats:calflag:%s", customerId);
}
}

41
epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/controller/IndexCalculateController.java

@ -2,6 +2,8 @@ package com.epmet.controller;
import com.epmet.commons.extappauth.annotation.ExternalAppRequestAuth;
import com.epmet.commons.extappauth.bean.ExternalAppRequestParam;
import com.epmet.commons.tools.redis.RedisKeys;
import com.epmet.commons.tools.redis.RedisUtils;
import com.epmet.commons.tools.utils.DateUtils;
import com.epmet.commons.tools.utils.Result;
import com.epmet.dto.indexcal.CalculateCommonFormDTO;
@ -9,6 +11,7 @@ import com.epmet.service.evaluationindex.indexcal.CpcIndexCalculateService;
import com.epmet.service.evaluationindex.indexcal.IndexCalculateService;
import com.epmet.util.DimIdGenerator;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -43,6 +46,12 @@ public class IndexCalculateController {
@Autowired
private CpcIndexCalculateService cpcIndexCalculateService;
@Autowired
private RedisUtils redisUtils;
// 计算同步锁
private Object statsCalLock = new Object();
/**
* 按照客户计算所有指标(按照月份)
*
@ -54,14 +63,32 @@ public class IndexCalculateController {
@ExternalAppRequestAuth
@PostMapping("all")
public Result<Boolean> indexCalculate(ExternalAppRequestParam externalAppRequestParam, @RequestBody CalculateCommonFormDTO formDTO) {
singleThreadPool.execute(() -> {
formDTO.setCustomerId(externalAppRequestParam.getCustomerId());
long start = System.currentTimeMillis();
Boolean aBoolean = indexCalculateService.indexCalculate(formDTO);
if (aBoolean) {
log.error("全部指标计算完成,总耗时:{}秒", (System.currentTimeMillis() - start) / 1000);
String customerId = externalAppRequestParam.getCustomerId();
Boolean executing = (Boolean) redisUtils.get(RedisKeys.getCustomerStatsCalFlag(customerId));
if (executing == null || !executing) {
synchronized (statsCalLock) {
Boolean executing2 = (Boolean) redisUtils.get(RedisKeys.getCustomerStatsCalFlag(customerId));
if (executing2 != null && executing2) {
log.error(String.format("该客户正在执行计算,请勿重复提交计算请求。", customerId));
return new Result<Boolean>().ok(false);
}
singleThreadPool.execute(() -> {
formDTO.setCustomerId(customerId);
long start = System.currentTimeMillis();
Boolean aBoolean = indexCalculateService.indexCalculate(formDTO);
if (aBoolean) {
log.error("全部指标计算完成,总耗时:{}秒", (System.currentTimeMillis() - start) / 1000);
}
redisUtils.set(RedisKeys.getCustomerStatsCalFlag(customerId), false);
});
redisUtils.set(RedisKeys.getCustomerStatsCalFlag(customerId), true);
}
});
} else {
log.error(String.format("该客户正在执行计算,请勿重复提交计算请求。", customerId));
return new Result<Boolean>().ok(false);
}
return new Result<Boolean>().ok(true);
}

Loading…
Cancel
Save