Apache DolphinScheduler 限制二级时序调度
背景
Apache DolphinScheduler 的定时任务配置使用 7 位 Crontab 表达式,分别对应秒、分、小时、日、月、周、年。
我们团队的日常开发工作中,工作流的时序调度一般不需要详细到秒级。但历史上也曾出现过因配置错误而导致故障的情况,比如原本应该每分钟执行一次的工作流被错误配置为每秒执行一次,导致短时间内生成大量工作流实例,影响工作效率。 Apache DolphinScheduler 服务和提交任务的 Hadoop 集群的可用性。
基于此,团队决定对DolphinScheduler的定时任务配置模块中的Crontab表达式进行限制,以防止此类事件在平台层面发生。
解决方案
我们的解决方案是从前端和后端都限制Crontab表达式的第一个位置:
- 前端配置不提供“每秒”选项
- 第一个位置为 * 时服务器端接口返回错误
前端修改
前端项目中,秒、分钟、小时都是统一的模板(CrontabTime),所以增加了一个新文件:dolphinscheduler-ui/src/components/crontab/modules/second.tsx
仅保留两种模式:intervalTime 和 SpecificTime
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import _ from 'lodash' import { defineComponent, onMounted, PropType, ref, toRefs, watch } from 'vue' import { NInputNumber, NRadio, NRadioGroup, NSelect } from 'naive-ui' import { useI18n } from 'vue-i18n' import { ICrontabI18n } from '../types' import { isStr, specificList } from '../common' import styles from '../index.module.scss' const props = { timeMin: { type: Number as PropType<number>, default: 0 }, timeMax: { type: Number as PropType<number>, default: 60 }, intervalPerform: { type: Number as PropType<number>, default: 5 }, intervalStart: { type: Number as PropType<number>, default: 3 }, timeSpecial: { type: Number as PropType<number | string>, default: 60 }, timeValue: { type: String as PropType<string>, default: '*' }, timeI18n: { type: Object as PropType<ICrontabI18n>, require: true } } export default defineComponent({ name: 'CrontabSecond', props, emits: ['update:timeValue'], setup(props, ctx) { const options = Array.from({ length: 60 }, (x, i) => ({ label: i.toString(), value: i })) const timeRef = ref() const radioRef = ref() const intervalStartRef = ref(props.intervalStart) const intervalPerformRef = ref(props.intervalPerform) const specificTimesRef = ref<Array<number>>([]) /** * Parse parameter value */ const analyticalValue = () => { const $timeVal = props.timeValue // Interval time const $interval = isStr($timeVal, '/') // Specific time const $specific = isStr($timeVal, ',') // Positive integer (times) if ( ($timeVal.length === 1 || $timeVal.length === 2 || $timeVal.length === 4) && _.isInteger(parseInt($timeVal)) ) { radioRef.value = 'specificTime' specificTimesRef.value = [parseInt($timeVal)] return } // Interval times if ($interval) { radioRef.value = 'intervalTime' intervalStartRef.value = parseInt($interval[0]) intervalPerformRef.value = parseInt($interval[1]) timeRef.value = `${intervalStartRef.value}/${intervalPerformRef.value}` return } // Specific times if ($specific) { radioRef.value = 'specificTime' specificTimesRef.value = $specific.map((item) => parseInt(item)) return } } // Interval start time(1) const onIntervalStart = (value: number | null) => { intervalStartRef.value = value || 0 if (radioRef.value === 'intervalTime') { timeRef.value = `${intervalStartRef.value}/${intervalPerformRef.value}` } } // Interval execution time(2) const onIntervalPerform = (value: number | null) => { intervalPerformRef.value = value || 0 if (radioRef.value === 'intervalTime') { timeRef.value = `${intervalStartRef.value}/${intervalPerformRef.value}` } } // Specific time const onSpecificTimes = (arr: Array<number>) => { specificTimesRef.value = arr if (radioRef.value === 'specificTime') { specificReset() } } // Reset interval time const intervalReset = () => { timeRef.value = `${intervalStartRef.value}/${intervalPerformRef.value}` } // Reset specific time const specificReset = () => { let timeValue = '0' if (specificTimesRef.value.length) { timeValue = specificTimesRef.value.join(',') } timeRef.value = timeValue } const updateRadioTime = (value: string) => { switch (value) { case 'intervalTime': intervalReset() break case 'specificTime': specificReset() break } } watch( () => timeRef.value, () => ctx.emit('update:timeValue', timeRef.value.toString()) ) onMounted(() => analyticalValue()) return { options, radioRef, intervalStartRef, intervalPerformRef, specificTimesRef, updateRadioTime, onIntervalStart, onIntervalPerform, onSpecificTimes, ...toRefs(props) } }, render() { const { t } = useI18n() return ( <NRadioGroup v-model:value={this.radioRef} onUpdateValue={this.updateRadioTime} > <div> <h3> Server-side </h3> <p>Add Crontab expression validation (there are two places: one is the new POST interface, and the other is the modified PUT interface), directly add a validation method for these two places to call:<br> </p> <pre class="brush:php;toolbar:false"> if (scheduleParam.getCrontab().startsWith("*")) { logger.error("The crontab must not start with *"); putMsg(result, Status.CRONTAB_EVERY_SECOND_ERROR); return result; }
本文到此结束。
以上是Apache DolphinScheduler 限制二级时序调度的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

探索前端中类似VSCode的面板拖拽调整功能的实现在前端开发中,如何实现类似于VSCode...
