缓存私有云的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慢日志定时任务创建流程分析相关推荐

  1. 韩顺平Java学习笔记P245对象创建流程分析P246this关键字-P250

    P245对象创建流程分析 //1.先在方法区加载方法类 //2.在堆里开空间一个存放age,一个存放name //3.(先默认初始化有默认值age=0,name=null,再显示初始化age=90,n ...

  2. Android6.0 Reset恢复出厂设置流程分析

    点击Settings应用中的恢复出厂设置按钮后流程分析: 先使用grep命令搜索"恢复出厂设置"字符串,找到相应的布局文件: packages/apps/Settings/res/ ...

  3. Android 4.0按键事件以及系统流程分析

    Android 4.0中按键的处理流程 按键在Android系统中,有着不同的代表意义.以前的全键盘的手机代码没有阅读过,所以也不是很了解.本人介绍的是在触摸屏的手机上的按键消息的处理流程. 在现在触 ...

  4. Android AOSP 6.0.1 registerReceiver广播注册流程分析

    广播作为 Android 开发的四大组间之一,当我们发送广播以后,发生了什么?广播接收者最终如何收到了广播. 一.复盘广播的使用 在 Android 开发中使用广播分为三个步骤: 1.新建广播接收者 ...

  5. 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 ...

  6. Android12 (S) 去掉悬浮通知消息及通知创建流程分析

    目录 概述 问题分析 1.通知创建的流程 2.通知view的不同类型 3.HeadsUpView创建入口 4.shouldHeadsUp方法的实现 解决方案 概述 根据产品需求,产品定位不需要通知栏, ...

  7. Android4.0源码Launcher启动流程分析【android源码Launcher系列一】

    最近研究ICS4.0的Launcher,发现4.0和2.3有稍微点区别,但是区别不是特别大,所以我就先整理一下Launcher启动的大致流程. Launcher其实是贯彻于手机的整个系统的,时时刻刻都 ...

  8. Android中ICS4.0源码Launcher启动流程分析【android源码Launcher系列一】

    最近研究ICS4.0的Launcher,发现4.0和2.3有稍微点区别,但是区别不是特别大,所以我就先整理一下Launcher启动的大致流程.Launcher其实是贯彻于手机的整个系统的,时时刻刻都在 ...

  9. android9.0 MTK开始预览流程分析

    注:mpStreamOps对应的是preview_stream_ops,代码中调用是err = mpStreamOps->dequeue_buffer(mpStreamOps, &phB ...

  10. Alian解读SpringBoot 2.6.0 源码(六):启动流程分析之创建应用上下文

    目录 一.背景 1.1.run方法整体流程 1.2.本文解读范围 二.创建应用上下文 2.1.初始化入口 2.2.初始化AbstractApplicationContext 2.3.初始化Generi ...

最新文章

  1. des vue 双倍长 解密_3DES双倍长加密 - osc_ojx9hm4t的个人空间 - OSCHINA - 中文开源技术交流社区...
  2. 使用面部标记提取和深度神经网络进行“昏昏欲睡”的检测
  3. ThreadPoolExecutor使用详解
  4. Qt调用word 例子
  5. 【Android 安装包优化】Android 中使用 SVG 图片 ( SVG 矢量图简介 | Android 中生成 Vector 矢量图资源 )
  6. RocketMQ源码分析之RocketMQ事务消息实现原下篇(事务提交或回滚)
  7. 【数据结构与算法】之深入解析“分发糖果”的求解思路与算法示例
  8. 简介Linux磁盘管理与文件系统
  9. 从NetCore报错到MySql安全
  10. 清空了回收站怎么找回?你没用过的方法
  11. Nginx设置404错误页面跳转
  12. 快速插入参考文献的方法
  13. leetcode刷题之x的算术平方根
  14. python中assert的用法(简洁明了)
  15. 【CSDN AI周刊】第16期 | 黄仁勋怒怼TPU 龙之队惜败冷扑大师
  16. 楚留香手游服务器维护,楚留香手游3月1日更新全职业调整一览 6门派职业调整汇总...
  17. java-net-php-python-4jspm游艇俱乐部管理系统计算机毕业设计程序
  18. 要想成为郎朗,请AI监督练琴可不行!
  19. 在未来几年,有哪些职业可能被人工智能取代?
  20. 量化的股票交易策略是什么意思?

热门文章

  1. Tomcat 服务器—安装、配置、启动、停止
  2. rk3399_android7.1关于secureboot操作说明
  3. 创造型——简单工厂模式
  4. matlab里的deploy,MATLAB deploytool simulink未定义函数'load_system'
  5. Ansible详解(十六)——Ansible配合Redis
  6. lvs+keepalived实现负载均衡和高可用
  7. 一个实例明白AutoResetEvent和 ManulResetEvent的用法
  8. SSM框架面试题及答案整理
  9. dijkstra算法学习笔记
  10. mysql 查询优化 ~ 善用profie利器