|
|
package com.yoho.unions.server.task;
|
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.Calendar;
|
|
|
import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.concurrent.locks.Lock;
|
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.dao.QueryTimeoutException;
|
|
|
import org.springframework.scheduling.annotation.Scheduled;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import com.yoho.unions.dal.IUnionClickLogsDAO;
|
|
|
import com.yoho.unions.dal.UnionClickCountDayMapper;
|
|
|
import com.yoho.unions.dal.model.UnionClickCount;
|
|
|
import com.yoho.unions.dal.model.UnionClickCountDay;
|
|
|
|
|
|
@Component
|
|
|
public class UnionClickCountDayTask {
|
|
|
|
|
|
private Logger logger = LoggerFactory.getLogger(UnionClickCountDayTask.class);
|
|
|
|
|
|
@Autowired
|
|
|
private UnionClickCountDayMapper unionClickCountDayMapper;
|
|
|
|
|
|
@Autowired
|
|
|
private IUnionClickLogsDAO unionClickLogsDAO;
|
|
|
|
|
|
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
private SimpleDateFormat formatDay = new SimpleDateFormat("yyyyMMdd");
|
|
|
|
|
|
// 防止交错执行
|
|
|
private Lock lock = new ReentrantLock();
|
|
|
|
|
|
// 每天00:05分执行
|
|
|
@Scheduled(cron = "* 05 0 * * ?")
|
|
|
//@Scheduled(cron = "* 0/2 * * * ?")
|
|
|
public void run() {
|
|
|
|
|
|
Calendar time = Calendar.getInstance();
|
|
|
time.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
time.set(Calendar.MINUTE, 0);
|
|
|
time.set(Calendar.SECOND, 0);
|
|
|
time.set(Calendar.MILLISECOND, 0);
|
|
|
int dayStart = (int) (time.getTimeInMillis() / 1000);
|
|
|
int begin = dayStart - 24 * 60 * 60;
|
|
|
int end = dayStart;
|
|
|
|
|
|
exeTask(begin, end);
|
|
|
}
|
|
|
|
|
|
public String exeTask(int begin, int end) {
|
|
|
|
|
|
if (!lock.tryLock()) {
|
|
|
logger.warn("UnionClickCountDayTask run time={} a job has running", format.format(new Date()));
|
|
|
return "a job has running";
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
|
|
|
if(end - begin > 24 * 60 * 60) {
|
|
|
logger.warn("UnionClickCountDayTask run time={} begin to end over a day", format.format(new Date()));
|
|
|
return "begin to end over a day";
|
|
|
}
|
|
|
|
|
|
if(format.format(new Date(begin * 1000L)).equals(format.format(new Date(end * 1000L - 1)))) {
|
|
|
logger.warn("UnionClickCountDayTask run time={} begin and end not in same day", format.format(new Date()));
|
|
|
return "begin and end not in same day";
|
|
|
}
|
|
|
|
|
|
int queryAcross = 5 * 60;
|
|
|
int timeoutRetryCount = 3;
|
|
|
logger.info("UnionClickCountDayTask run start={} , end={} , across={} , retry={}",
|
|
|
format.format(new Date(begin * 1000L)), format.format(new Date(end * 1000L - 1)), queryAcross,
|
|
|
timeoutRetryCount);
|
|
|
Map<String, UnionClickCount> map = new HashMap<>();
|
|
|
|
|
|
int count = 0;
|
|
|
// 当小于结束时间一直执行
|
|
|
while (begin < end) {
|
|
|
List<UnionClickCount> data = null;
|
|
|
for (int i = 0; i < timeoutRetryCount; i++) {
|
|
|
try {
|
|
|
|
|
|
logger.info("UnionClickCountDayTask run start={} , end={} , across={} , now_retry={}",
|
|
|
format.format(new Date(begin * 1000L)), format.format(new Date(end * 1000L - 1)),
|
|
|
queryAcross, i);
|
|
|
|
|
|
long exeStart = System.currentTimeMillis();
|
|
|
data = queryCountInfoByTime(begin, Math.min(begin + queryAcross, end));
|
|
|
begin += queryAcross;
|
|
|
long exeEnd = System.currentTimeMillis();
|
|
|
long use = exeEnd - exeStart;
|
|
|
|
|
|
logger.info("UnionClickCountDayTask run start={} , end={} , across={} , use={}",
|
|
|
format.format(new Date(begin * 1000L)), format.format(new Date(end * 1000L - 1)),
|
|
|
queryAcross, use);
|
|
|
if (use < 700) {
|
|
|
logger.info("UnionClickCountDayTask change across from {} to {}", queryAcross,
|
|
|
queryAcross + 60);
|
|
|
queryAcross += 60;
|
|
|
}
|
|
|
if (use > 800) {
|
|
|
logger.info("UnionClickCountDayTask change across from {} to {}", queryAcross,
|
|
|
queryAcross - 60);
|
|
|
queryAcross -= 60;
|
|
|
}
|
|
|
// 执行成功,则不再重试
|
|
|
break;
|
|
|
} catch (QueryTimeoutException e) {
|
|
|
logger.warn("Exe queryCountInfoByTime start={}, end={} timeout!", begin,
|
|
|
Math.min(begin + queryAcross, end));
|
|
|
if (queryAcross <= 2) {
|
|
|
logger.warn("Exe queryCountInfoByTime queryAcross={} return", queryAcross);
|
|
|
return "queryCountInfoByTime queryAcross < 2";
|
|
|
}
|
|
|
queryAcross >>>= 2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (data == null) {
|
|
|
logger.warn("Exe queryCountInfoByTime sleep start={}, end={} timeout!", begin,
|
|
|
Math.min(begin + queryAcross, end));
|
|
|
try {
|
|
|
Thread.sleep(1000);
|
|
|
} catch (InterruptedException e) {
|
|
|
}
|
|
|
} else {
|
|
|
logger.info("Exe queryCountInfoByTime data.size={} ", data.size());
|
|
|
addDataToMap(data, map);
|
|
|
}
|
|
|
}
|
|
|
// 把统计结果放到表里
|
|
|
logger.info("UnionClickCountDayTask run start to insert map.size={}", map.size());
|
|
|
String dayId = formatDay.format(new Date(begin * 1000L));
|
|
|
int successCount = 0;
|
|
|
int failedCount = 0;
|
|
|
for (Map.Entry<String, UnionClickCount> entry : map.entrySet()) {
|
|
|
|
|
|
try {
|
|
|
UnionClickCount info = entry.getValue();
|
|
|
UnionClickCountDay bean = new UnionClickCountDay();
|
|
|
bean.setDayId(dayId);
|
|
|
bean.setUnionType(info.getUnionType());
|
|
|
bean.setClientType(getClientType(info.getClientType()));
|
|
|
bean.setNum(info.getNum());
|
|
|
bean.setCreateTime((int) (System.currentTimeMillis() / 1000));
|
|
|
bean.setComb(dayId + "_" + bean.getUnionType() + "_" + bean.getClientType());
|
|
|
|
|
|
logger.info("UnionClickCountDayTask insert bean={}", bean);
|
|
|
unionClickCountDayMapper.insert(bean);
|
|
|
successCount++;
|
|
|
count += info.getNum();
|
|
|
} catch (Exception e) {
|
|
|
logger.warn("UnionClickCountDayTask insert error={}", e.getMessage());
|
|
|
failedCount++;
|
|
|
}
|
|
|
}
|
|
|
logger.info("UnionClickCountDayTask run over data count={}, insert over! success={}, error={}", count, successCount, failedCount);
|
|
|
return "UnionClickCountDayTask run over data count=" + count + ", insert success=" + successCount + ", error=" + failedCount;
|
|
|
} finally {
|
|
|
lock.unlock();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public String deleteData(int begin, int end) {
|
|
|
|
|
|
if (!lock.tryLock()) {
|
|
|
logger.warn("UnionClickCountDayTask deleteData time={} a job has running", format.format(new Date()));
|
|
|
return "a job has running";
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (end - begin > 24 * 60 * 60) {
|
|
|
logger.warn("UnionClickCountDayTask deleteData time={} begin to end over a day",
|
|
|
format.format(new Date()));
|
|
|
return "begin to end over a day";
|
|
|
}
|
|
|
|
|
|
if (format.format(new Date(begin * 1000L)).equals(format.format(new Date(end * 1000L - 1)))) {
|
|
|
logger.warn("UnionClickCountDayTask deleteData time={} begin and end not in same day",
|
|
|
format.format(new Date()));
|
|
|
return "begin and end not in same day";
|
|
|
}
|
|
|
|
|
|
int queryAcross = 5 * 60;
|
|
|
int timeoutRetryCount = 3;
|
|
|
logger.info("UnionClickCountDayTask deleteData start={} , end={} , across={} , retry={}",
|
|
|
format.format(new Date(begin * 1000L)), format.format(new Date(end * 1000L - 1)), queryAcross,
|
|
|
timeoutRetryCount);
|
|
|
Integer count = null;
|
|
|
try {
|
|
|
count = deleteCountInfoByTime(begin, end);
|
|
|
} catch (Exception e) {
|
|
|
logger.info("UnionClickCountDayTask deleteData error! msg={}", e.getMessage());
|
|
|
return "Error : " + e.getMessage();
|
|
|
}
|
|
|
logger.info("UnionClickCountDayTask deleteData over! deleteCount={}", count);
|
|
|
return "deleteData over, deleteCount=" + count;
|
|
|
} finally {
|
|
|
lock.unlock();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void addDataToMap(List<UnionClickCount> data, Map<String, UnionClickCount> map) {
|
|
|
for (UnionClickCount d : data) {
|
|
|
String key = d.getUnionType() + "_" + d.getClientType();
|
|
|
UnionClickCount store = map.get(key);
|
|
|
if (store == null) {
|
|
|
map.put(key, d);
|
|
|
} else {
|
|
|
store.setNum(store.getNum() + d.getNum());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private List<UnionClickCount> queryCountInfoByTime(int start, int end) {
|
|
|
return unionClickLogsDAO.queryCountInfoByTime(start, end);
|
|
|
}
|
|
|
|
|
|
private Integer deleteCountInfoByTime(int start, int end) {
|
|
|
return unionClickCountDayMapper.deleteCountInfoByTime(start, end);
|
|
|
}
|
|
|
|
|
|
private Integer getClientType(String clientType) {
|
|
|
if (clientType == null) {
|
|
|
return 0;
|
|
|
}
|
|
|
if (clientType.equals("android")) {
|
|
|
return 1;
|
|
|
}
|
|
|
if (clientType.equals("ios")) {
|
|
|
return 2;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
} |
...
|
...
|
|