主要写一下最近写的日终的东西,日终主要是每日统计跑数,就不需要在用统计的时候
大量的带条件分组去查询,从而提高统计信息的查询效率。
简单的来说日终的主要逻辑就是定时的跑一个方法,从而去把需要的数据统计出来,
放到指定的数据库表里面的操作;
里面运用到的方法和技术主要有:java的反序列化,activeMQ,spring定时器。
spring配置定时器quartz配置
表达式 | 意义 |
---|---|
0 0 12 * *? | 每天中午12点触发 |
0 15 10 ? ** | 每天上午10:15触发 |
0 15 10 * *? | 每天上午10:15触发 |
0 15 10 * * ?* | 每天上午10:15触发 |
0 15 10 * * ?2005 | 2005年的每天上午10:15触发 |
0 * 14 * *? | 在每天下午2点到下午2:59期间的每1分钟触发 |
0 0/5 14 * *? | 在每天下午2点到下午2:55期间的每5分钟触发 |
0 0/5 14,18 ** ? | 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 |
0 0-5 14 * *? | 在每天下午2点到下午2:05期间的每1分钟触发 |
0 10,44 14 ? 3WED | 每年三月的星期三的下午2:10和2:44触发 |
0 15 10 ? *MON-FRI | 周一至周五的上午10:15触发 |
0 15 10 15 *? | 每月15日上午10:15触发 |
0 15 10 L *? | 每月最后一日的上午10:15触发 |
0 15 10 ? *6L | 每月的最后一个星期五上午10:15触发 |
0 15 10 ? * 6L2002-2005 | 2002年至2005年的每月的最后一个星期五上午10:15触发 |
0 15 10 ? *6#3 | 每月的第三个星期五上午10:15触发 |
当然也可以用spring的注解形式:(ps:这个是我自己写的一个定时生成一个xls并且上传到阿里云的OSS的方法)
@Scheduled(cron = "0/40 * * * * ? ")
public void poiExprotUgiftDate() {
System.out.println(111);
try {
File directory = new File("");
String path = null;
try {
path = directory.getCanonicalPath();// 获取当前路径
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// String time = CommUtil.fetchSystemDate("yyyy-MM-dd");
String time = "2018-02-02";
path += "\\"+time+".xls";
File file = new File(path);
// // 如果文件夹不存在则创建
// if (!file.exists() && !file.isDirectory()) {
// file.mkdir();
// }
// 存入地址
OutputStream out = new FileOutputStream(path);
// 表头
String[] headers = { "订单号", "产品条码", "订单状态", "买家id", "子订单编号", "商品名称", "商品数量", "收货人姓名", "收货地址-省市",
"收货地址-街道地址", "收货人手机", "订单创建时间", "付款时间" };
Pattern patternSeachName = Pattern.compile("^.*" + time + ".*$",
Pattern.CASE_INSENSITIVE);
// Pattern patternSeachName = Pattern.compile("^.*" + "2018-01-29" + ".*$",
// Pattern.CASE_INSENSITIVE);
Query query = new Query();
query.addCriteria(Criteria.where("insertTime").regex(patternSeachName));
List<Integer> arr = new ArrayList<Integer>();
arr.add(0);
arr.add(1);
query.addCriteria(Criteria.where("status").in(arr).and("userStatus").ne("1"));
query.with(new Sort(Direction.DESC, "insertTime"));
// 获取寄送列表
List<Ugift> result1 = this.baseMongoDAO.findObject(query, Ugift.class);
System.out.println(result1.size());
// 每行数据
List<List<String>> result = new ArrayList<List<String>>();
for (Ugift map : result1) {
List<String> oList = new ArrayList<String>();
String id = map.getGiftId();
String[] idsStrings = map.getCatchLogidStr().split(",");
Query queryFtoysQuery = new Query();
queryFtoysQuery.addCriteria(Criteria.where("_id").in(idsStrings));
List<Ftoys> ftoysList = this.baseMongoDAO.findObject(queryFtoysQuery, Ftoys.class);
List<List<String>> foList = new ArrayList<List<String>>();
for (Ftoys ftoys : ftoysList) {
// System.out.println(JSON.toJSONString(ftoys));
int num = 0;
String resourceId = "";
String resourceName = "";
if(ftoys.getIncomeType()==0){
RProducts products = (RProducts) basedao.get(RProducts.class, ftoys.getProductId());
resourceId = JSON.toJSONString(products.getResourceId());
resourceName = products.getResourceName();
}else {
ExcProduct products = (ExcProduct) basedao.get(ExcProduct.class, ftoys.getProductId());
resourceId = JSON.toJSONString(products.getResoureId());
resourceName = products.getResoureName();
}
// 去重复
if (!"".equals(CommUtil.toString(resourceId))) {
for (List<String> string : foList) {
if (resourceId.equals(string.get(1))) {
string.set(6,
CommUtil.toString(Integer.parseInt(CommUtil.toString(string.get(6))) + 1));
num++;
break;
}
}
}
if (num == 0) {
oList = new ArrayList<String>();
oList.add(id);
oList.add(resourceId);
oList.add("买家已付款,等待卖家发货");
oList.add(CommUtil.toString(map.getUserId()));
oList.add(id);
oList.add(resourceName);
oList.add("1");
oList.add(CommUtil.toString(map.getPhoneUserName()));
oList.add(CommUtil.toString(map.getAddressee()).split("//")[0]);
oList.add(CommUtil.toString(map.getAddressee()));
oList.add(CommUtil.toString(map.getPhoneNum()));
oList.add(CommUtil.toString(map.getInsertTime()));
oList.add(CommUtil.toString(map.getInsertTime()));
foList.add(oList);
}
}
result.addAll(foList);
}
HSSFWorkbook workbook = new HSSFWorkbook();
upload.exportExcel(workbook, 0, "寄送导出", headers, result, out);
// 原理就是将所有的数据一起写入,然后再关闭输入流。
workbook.write(out);
out.close();
String fileName = CommUtil.fetchSystemDate("yyyyMMdd");
ossUtil.uploadFile(fileName, new File(path), "xls");
System.out.println(222);
} catch (Exception e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
日终模块的activeMQ,是有可能会存在先后生成的数据。所以需要指定的排序去排队:
反序列化代码:
T serviceBeanName = (T) LightApplicationContext.getBeanById(serviceName);
Method md = serviceBeanName.getClass().getMethod(funcName, String.class);
执行的实际方法:
public void autoTask(Map<String, Object> map) {
String tranDate = CommUtil.getLastDay();
int status = 0;
Method md;
String eventMsg = "失败:";
String eventId = CommUtil.toString(map.get("eventId"));
String serviceName = CommUtil.toString(map.get("serviceName"));
String funcName = CommUtil.toString(map.get("funcName"));
String data = CommUtil.toString(map.get("data"));
// ugift.poiExprotUgiftDate();
T serviceBeanName = (T) LightApplicationContext.getBeanById(serviceName);
try {
md = serviceBeanName.getClass().getMethod(funcName, String.class);
//
// if ("".equals(orgId)) {
dayEndRecordLog.setEventForDate(eventId, tranDate, 1, "");
// }
// dayEndRecordLog.setStatusOfOrg(tranDate, orgId, eventId, 1);
Map<String, Object> eventMap = (Map<String, Object>) md.invoke(serviceBeanName, data);
if (!eventMap.get("rstState").toString().equals("00000")) {
status = 3;
}
if (status == 3) {
dayEndRecordLog.setEventForDate(eventId, tranDate, status, eventMsg);
} else {
dayEndRecordLog.setEventForDate(eventId, tranDate, 2, "");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
当然也可以手动的去点击日终,防治spring定时器跑数失败或者其他的问题,
做两手准备,这个是后动请求发送activeMQ,让这个日终service去排队执行日终方法。
public Map<String,Object> sendDayEndMQ(String serviceName, String funcName, String orgId, String eventId){
Map<String,Object> rstMap = new HashMap<String,Object>();
Map<String,Object> dayEndMap = new HashMap<String,Object>();
dayEndMap.put("serviceName", serviceName);
dayEndMap.put("funcName", funcName);
dayEndMap.put("eventId", eventId);
try {
jmsQueueTemplate.send(dayenDestination,new MessageCreator() {
@Override
public TextMessage createMessage(Session session)
throws JMSException {
TextMessage textMessage = session
.createTextMessage(JSON.toJSONString(dayEndMap));
return textMessage;
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rstMap.put("state", "00000");
return rstMap;