需求:每过一段时间统计一次目标调用次数,做成折线图的形式。redis做计数,写入mongoDB中。redis的key以天为单位,value递增,每五分钟存入mongoDB一次。
1,define redis key
public static String getCallBaiDuTTSKey(String time) {
return String .format("BaiDuTTSCount:%s:",time);
}
2, get redis key
String baiduTtsRedisKey = RedisKeyCenter.getCallBaiDuTTSKey(LocalDate.now().toString());
3, key increment and set expire time
redisService.incrementKey(baiduTtsRedisKey, 1);
redisService.expire(baiduTtsRedisKey, 24, TimeUnit.HOURS);
4, core quartz task code
@Override
public void updateCallTtsCount() {
String baiduTtsRedisKey = RedisKeyCenter.getCallBaiDuTTSKey(LocalDate.now().toString());
// query from Redis
Integer baiduCount = redisService.get(baiduTtsRedisKey, Integer.class);
baiduCount = baiduCount == null ? 0 : baiduCount;
// save into MongoDB
CallTtsCountPO callTtsCountPO = new CallTtsCountPO();
callTtsCountPO.setQueryTime(LocalDateTime.now());
callTtsCountPO.setBaiduCount(baiduCount);
mongoTemplate.save(callTtsCountPO);
}
5, LoggedJob sub class
public class UpdateCallTtsCountQuartzJob extends LoggedJob {
@Resource
private TtsService ttsService;
@Override
protected void executeInternalLogged(JobExecutionContext jobExecutionContext) {
ttsService.updateCallTtsCount();
}
}
LoggedJob
public abstract class LoggedJob extends QuartzJobBean {
private Class clazz = this.getClass();
protected final Logger logger = LoggerFactory.getLogger(clazz);
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) {
NewMDCDecoratorRunnable runnable = new NewMDCDecoratorRunnable(() -> {
String fireInstanceId = jobExecutionContext.getFireInstanceId();
logger.debug("定时任务开始执行, instanceId={}", fireInstanceId);
try {
executeInternalLogged(jobExecutionContext);
} catch (Exception e) {
logger.error("定时任务执行失败, instanceId={}", fireInstanceId, e);
}
logger.debug("定时任务执行完成, instanceId={}", fireInstanceId);
});
runnable.run();
}
protected abstract void executeInternalLogged(JobExecutionContext jobExecutionContext);
}
6, task config
/**
* 定时任务配置
*/
@Configuration
public class QuartzConfig {
@Resource
private DataSource engineMasterDataSource;
@Bean
public SchedulerFactoryBean schedulerFactoryBean(@Qualifier("triggers") Trigger[] triggers,
JobFactory jobFactory, MySpringBeanJobFactory mySpringBeanJobFactory,
PlatformTransactionManager transactionManager) {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
// this allows to update triggers in DB when updating settings in config file:
// 用于quartz集群,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
factory.setOverwriteExistingJobs(true);
factory.setJobFactory(mySpringBeanJobFactory);
// 用于quartz集群,加载quartz数据源
factory.setDataSource(engineMasterDataSource);
// QuartzScheduler 延时启动,应用启动完10秒后 QuartzScheduler 再启动
factory.setStartupDelay(10);
factory.setJobFactory(jobFactory);
factory.setApplicationContextSchedulerContextKey("applicationContext");
// 注册触发器
factory.setTriggers(triggers);
factory.setTransactionManager(transactionManager);
factory.setTaskExecutor(new ThreadPoolExecutor(10, 100, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(200)));
// 直接使用配置文件
factory.setConfigLocation(new FileSystemResource(this.getClass().getResource("/quartz.properties").getPath()));
factory.setWaitForJobsToCompleteOnShutdown(true);
return factory;
}
/**
* 加载触发器
*/
@Bean(name = "triggers")
public Trigger[] loadJobTriggers() throws ParseException {
List<Trigger> triggerList = new ArrayList<>();
if (!ApplicationConstant.CURR_ENV.isLocalization()) {
//
triggerList.add(createTrigger(UpdateCallTtsCountQuartzJob.class, "0 0/5 * * * ?"));
return triggerList.toArray(new Trigger[triggerList.size()]);
}
/**
* 创建触发器工厂
*/
private static Trigger createTrigger(Class<?> jobClass, String cronExpression) throws ParseException {
// 创建JobDetail
JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
jobDetailFactoryBean.setJobClass((Class<? extends Job>) jobClass);
jobDetailFactoryBean.setName(jobClass.getSimpleName());
jobDetailFactoryBean.setDurability(true);
jobDetailFactoryBean.setRequestsRecovery(true);
jobDetailFactoryBean.afterPropertiesSet();
JobDetail jobDetail = jobDetailFactoryBean.getObject();
// 创建触发器CronTrigger
CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
factoryBean.setName(jobClass.getSimpleName());
factoryBean.setCronExpression(cronExpression);
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
}
7, mongo query entity
@Data
@Document(collection = CallTtsCountPO.COLLECTION_NAME)
public class CallTtsCountPO {
public final static String COLLECTION_NAME = "TTS_CALL_COUNT";
public final static String TIME_COLUMN_NAME = "queryTime";
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Indexed(name = "query_time_idx")
private LocalDateTime queryTime;
private Integer baiduCount;
}
8, query count list message
@Override
public List<CallTtsCountPO> getCallTtsCountType(LocalDateTime startTime, LocalDateTime endTime) {
// default query
if (Objects.isNull(startTime) && Objects.isNull(endTime)) {
startTime = LocalDateTime.now().minusDays(7);
endTime = LocalDateTime.now();
}
List<AggregationOperation> aggregationOperationList = new ArrayList<>();
if (startTime != null) {
aggregationOperationList.add(Aggregation.match(Criteria.where(CallTtsCountPO.TIME_COLUMN_NAME).gte(startTime)));
}
if (endTime != null) {
aggregationOperationList.add(Aggregation.match(Criteria.where(CallTtsCountPO.TIME_COLUMN_NAME).lte(endTime)));
}
Aggregation aggregation = Aggregation.newAggregation(aggregationOperationList);
return mongoTemplate.aggregate(aggregation, CallTtsCountPO.COLLECTION_NAME, CallTtsCountPO.class).getMappedResults();
}
点击查看更多内容
2人点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦