CACHECLOUDV1.0慢日志定时任务创建流程分析
缓存私有云的github地址 https://github.com/sohutv/cachecloud.git ,此处分析的源码是tag1.0的源码,2.0的实现完全不一样。
spring-load.xml中的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd" default-autowire="byName"><!--初始化加载已有实例,测试时禁用--><bean class="com.sohu.cache.init.RedisInitLoad" init-method="init" /><bean class="com.sohu.cache.init.MachineInitLoad" init-method="init" />
</beans>
在spring-local.xml中是没有引入这个配置的,测试时禁用了,在这个配置中增加这个引用即和线上一样
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><import resource="classpath:spring/spring-config.xml"/><import resource="classpath:spring/spring-quartz.xml"/><!-- 增加 spring-load.xml的配置--><import resource="classpath:spring/spring-load.xml"/><import resource="classpath:spring/spring-mybatis.xml"/><import resource="classpath:spring/spring-service.xml"/><import resource="classpath:spring/spring-data.xml"/><import resource="classpath:spring/spring-manage.xml"/><import resource="classpath:spring/spring-mvc.xml"/><import resource="classpath:spring/spring-jmx.xml"/><import resource="classpath:spring/spring-alert.xml"/><import resource="classpath:spring/spring-client-report.xml"/><import resource="classpath:spring/spring-inspector.xml"/><import resource="classpath:spring/spring-gcache.xml"/><import resource="classpath:spring/spring-monitor.xml"/><import resource="classpath:spring/spring-gmq.xml"/>
</beans>
启动后会调用 RedisInitLoad类的init方法,debug判断要去掉,否则本地可能会无法进入部署慢日志收集任务方法
public void init() {if (ConstUtils.IS_DEBUG) {logger.warn("isDebug=true return");return;}……省略……
RedisInitLoad类的init方法中调用initByType方法创建慢日志收集的触发器。
private void initByType(int type) {List<InstanceInfo> instanceInfoList = instanceDao.getInstListByType(type);for (InstanceInfo instanceInfo : instanceInfoList) {instanceInfo.getPort());if (TypeUtil.isRedisSentinel(instanceInfo.getType())) {continue;}String host = instanceInfo.getIp();int port = instanceInfo.getPort();Long appId = instanceInfo.getAppId();redisCenter.deployRedisCollection(appId, host, port);//这里给每个实例增加慢日志收集的jobredisCenter.deployRedisSlowLogCollection(appId, host, port);}logger.info("init redis type={} deploy instance done.", type);}
RedisCenterImpl的deployRedisSlowLogCollection方法部署定时任务
@Overridepublic boolean deployRedisSlowLogCollection(long appId, String host, int port) {Assert.isTrue(appId > 0);Assert.hasText(host);Assert.isTrue(port > 0);Map<String, Object> dataMap = new HashMap<String, Object>();dataMap.put(ConstUtils.HOST_KEY, host);dataMap.put(ConstUtils.PORT_KEY, port);dataMap.put(ConstUtils.APP_KEY, appId);JobKey jobKey = JobKey.jobKey(ConstUtils.REDIS_SLOWLOG_JOB_NAME, ConstUtils.REDIS_SLOWLOG_JOB_GROUP);TriggerKey triggerKey = TriggerKey.triggerKey(ObjectConvert.linkIpAndPort(host, port), ConstUtils.REDIS_SLOWLOG_TRIGGER_GROUP + appId);boolean result = schedulerCenter.deployJobByCron(jobKey, triggerKey, dataMap, ScheduleUtil.getRandomHourCron(appId), false);return result;}
SchedulerCenter的实现类SchedulerCenterImpl中,注入了 clusterScheduler,这个bean是在spring-quartz.xml中定义的
<!-- 分布式QuartzScheduler --><bean id="clusterScheduler" name="clusterScheduler" lazy-init="false" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="dataSource" ref="cacheCloudDB"></property><property name="taskExecutor" ref="quartzThreadPool"/><!--<property name="transactionManager" ref="transactionManager"/>--><property name="quartzProperties"><props><prop key="org.quartz.scheduler.instanceName">CacheCloudScheduler</prop><prop key="org.quartz.scheduler.instanceId">AUTO</prop><prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop><prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop><!-- 表名前缀 --><prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop><prop key="org.quartz.jobStore.isClustered">${isClustered}</prop><prop key="org.quartz.jobStore.clusterCheckinInterval">15000</prop><prop key="org.quartz.jobStore.maxMisfiresToHandleAtATime">120</prop><prop key="org.quartz.jobStore.misfireThreshold">60000</prop><!-- 打开JMX 配置 --><prop key="org.quartz.scheduler.jmx.export">true</prop><prop key="org.quartz.plugin.shutdownHook.class">org.quartz.plugins.management.ShutdownHookPlugin</prop><prop key="org.quartz.plugin.shutdownHook.cleanShutdown">true</prop><prop key="org.terracotta.quartz.skipUpdateCheck">true</prop><!--<prop key="org.quartz.plugin.triggHistory.class">org.quartz.plugins.history.LoggingJobHistoryPlugin</prop>--></props></property><property name="schedulerName" value="CacheCloudScheduler"/><property name="applicationContextSchedulerContextKey" value="applicationContext"/><property name="overwriteExistingJobs" value="true"/><property name="waitForJobsToCompleteOnShutdown" value="false"/><property name="startupDelay" value="10"/><property name="autoStartup" value="true"/><property name="triggers"><array><ref bean="cleanUpStatisticsTrigger"/><ref bean="hostInspectorTrigger"/><ref bean="appInspectorTrigger"/><ref bean="appDailyTrigger"/></array></property><property name="jobDetails"><array><ref bean="redisJobDetail"/><ref bean="machineJobDetail"/><ref bean="serverJobDetail"/><ref bean="machineMonitorJobDetail"/><ref bean="redisSlowLogJobDetail"/><ref bean="cleanUpStatisticsJobDetail"/><ref bean="inspectorJobDetail"/><ref bean="appDailyJobDetail"/></array></property></bean>
部署定时任务
@Overridepublic boolean deployJobByCron(JobKey jobKey, TriggerKey triggerKey, Map<String, Object> dataMap, String cron, boolean replace) {Assert.isTrue(jobKey != null);Assert.isTrue(triggerKey != null);Assert.isTrue(CronExpression.isValidExpression(cron), "invalid cron = " + cron);try {//获取相应的任务执行器JobDetail jobDetail = clusterScheduler.getJobDetail(jobKey);if (jobDetail == null) {logger.error("JobKey {}:{} is not exist", jobKey.getName(), jobKey.getGroup());return false;}//在这里创建定时触发任务fireCronTrigger(triggerKey, jobDetail, cron, replace, dataMap);} catch (Exception e) {logger.error(e.getMessage(), e);return false;}return true;}
激活触发器
private boolean fireCronTrigger(TriggerKey triggerKey, JobDetail jobDetail, String cron, boolean replace, Map<String, Object> dataMap) {try {boolean isExists = clusterScheduler.checkExists(triggerKey);if (isExists) {if (replace) {logger.warn("replace trigger={}:{} ", triggerKey.getName(), triggerKey.getGroup());clusterScheduler.unscheduleJob(triggerKey);} else {logger.info("exist trigger={}:{} ", triggerKey.getName(), triggerKey.getGroup());return false;}}Date startDate = DateUtils.addSeconds(new Date(), 20);//组建定时任务触发器Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).forJob(jobDetail).withSchedule(CronScheduleBuilder.cronSchedule(cron)).startAt(startDate).build();if (dataMap != null && dataMap.size() > 0) {trigger.getJobDataMap().putAll(dataMap);}clusterScheduler.scheduleJob(trigger);} catch (SchedulerException e) {logger.error(e.getMessage(), e);return false;}return true;}
这里看的触发器的时间是每个小时的随机某分钟某秒,直接从实例服务器获取最新100条慢日志
// 从redis中获取慢查询日志,直接从服务器获取最新100条慢日志List<RedisSlowLog> redisLowLogList = getRedisSlowLogs(host, port, 100);if (CollectionUtils.isEmpty(redisLowLogList)) {return Collections.emptyList();}
CACHECLOUDV1.0慢日志定时任务创建流程分析相关推荐
- 韩顺平Java学习笔记P245对象创建流程分析P246this关键字-P250
P245对象创建流程分析 //1.先在方法区加载方法类 //2.在堆里开空间一个存放age,一个存放name //3.(先默认初始化有默认值age=0,name=null,再显示初始化age=90,n ...
- Android6.0 Reset恢复出厂设置流程分析
点击Settings应用中的恢复出厂设置按钮后流程分析: 先使用grep命令搜索"恢复出厂设置"字符串,找到相应的布局文件: packages/apps/Settings/res/ ...
- Android 4.0按键事件以及系统流程分析
Android 4.0中按键的处理流程 按键在Android系统中,有着不同的代表意义.以前的全键盘的手机代码没有阅读过,所以也不是很了解.本人介绍的是在触摸屏的手机上的按键消息的处理流程. 在现在触 ...
- Android AOSP 6.0.1 registerReceiver广播注册流程分析
广播作为 Android 开发的四大组间之一,当我们发送广播以后,发生了什么?广播接收者最终如何收到了广播. 一.复盘广播的使用 在 Android 开发中使用广播分为三个步骤: 1.新建广播接收者 ...
- Android10.0 开机广播BOOT_COMPLETED发送流程分析
原文地址:https://skytoby.github.io/2019/%E5%BC%80%E6%9C%BA%E5%B9%BF%E6%92%ADBOOT_COMPLETED%E5%8F%91%E9%8 ...
- Android12 (S) 去掉悬浮通知消息及通知创建流程分析
目录 概述 问题分析 1.通知创建的流程 2.通知view的不同类型 3.HeadsUpView创建入口 4.shouldHeadsUp方法的实现 解决方案 概述 根据产品需求,产品定位不需要通知栏, ...
- Android4.0源码Launcher启动流程分析【android源码Launcher系列一】
最近研究ICS4.0的Launcher,发现4.0和2.3有稍微点区别,但是区别不是特别大,所以我就先整理一下Launcher启动的大致流程. Launcher其实是贯彻于手机的整个系统的,时时刻刻都 ...
- Android中ICS4.0源码Launcher启动流程分析【android源码Launcher系列一】
最近研究ICS4.0的Launcher,发现4.0和2.3有稍微点区别,但是区别不是特别大,所以我就先整理一下Launcher启动的大致流程.Launcher其实是贯彻于手机的整个系统的,时时刻刻都在 ...
- android9.0 MTK开始预览流程分析
注:mpStreamOps对应的是preview_stream_ops,代码中调用是err = mpStreamOps->dequeue_buffer(mpStreamOps, &phB ...
- Alian解读SpringBoot 2.6.0 源码(六):启动流程分析之创建应用上下文
目录 一.背景 1.1.run方法整体流程 1.2.本文解读范围 二.创建应用上下文 2.1.初始化入口 2.2.初始化AbstractApplicationContext 2.3.初始化Generi ...
最新文章
- des vue 双倍长 解密_3DES双倍长加密 - osc_ojx9hm4t的个人空间 - OSCHINA - 中文开源技术交流社区...
- 使用面部标记提取和深度神经网络进行“昏昏欲睡”的检测
- ThreadPoolExecutor使用详解
- Qt调用word 例子
- 【Android 安装包优化】Android 中使用 SVG 图片 ( SVG 矢量图简介 | Android 中生成 Vector 矢量图资源 )
- RocketMQ源码分析之RocketMQ事务消息实现原下篇(事务提交或回滚)
- 【数据结构与算法】之深入解析“分发糖果”的求解思路与算法示例
- 简介Linux磁盘管理与文件系统
- 从NetCore报错到MySql安全
- 清空了回收站怎么找回?你没用过的方法
- Nginx设置404错误页面跳转
- 快速插入参考文献的方法
- leetcode刷题之x的算术平方根
- python中assert的用法(简洁明了)
- 【CSDN AI周刊】第16期 | 黄仁勋怒怼TPU 龙之队惜败冷扑大师
- 楚留香手游服务器维护,楚留香手游3月1日更新全职业调整一览 6门派职业调整汇总...
- java-net-php-python-4jspm游艇俱乐部管理系统计算机毕业设计程序
- 要想成为郎朗,请AI监督练琴可不行!
- 在未来几年,有哪些职业可能被人工智能取代?
- 量化的股票交易策略是什么意思?
热门文章
- Tomcat 服务器—安装、配置、启动、停止
- rk3399_android7.1关于secureboot操作说明
- 创造型——简单工厂模式
- matlab里的deploy,MATLAB deploytool simulink未定义函数'load_system'
- Ansible详解(十六)——Ansible配合Redis
- lvs+keepalived实现负载均衡和高可用
- 一个实例明白AutoResetEvent和 ManulResetEvent的用法
- SSM框架面试题及答案整理
- dijkstra算法学习笔记
- mysql 查询优化 ~ 善用profie利器