网站后台系统有哪些,建筑工程网手机版,有什么软件可以制作抽奖页面,做服装公司需要什么网站背景
Apache DolphinScheduler 定时任务配置采用的 7 位 Crontab 表达式#xff0c;分别对应秒、分、时、月天、月、周天、年。
在团队日常开发工作中#xff0c;工作流的定时调度一般不会细化到秒级别。但历史上出现过因配置的疏忽大意而产生故障时间#xff0c;如应该配…背景
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.scssconst props {timeMin: {type: Number as PropTypenumber,default: 0},timeMax: {type: Number as PropTypenumber,default: 60},intervalPerform: {type: Number as PropTypenumber,default: 5},intervalStart: {type: Number as PropTypenumber,default: 3},timeSpecial: {type: Number as PropTypenumber | string,default: 60},timeValue: {type: String as PropTypestring,default: *},timeI18n: {type: Object as PropTypeICrontabI18n,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 refArraynumber([])/*** Parse parameter value*/const analyticalValue () {const $timeVal props.timeValue// Interval timeconst $interval isStr($timeVal, /)// Specific timeconst $specific isStr($timeVal, ,)// Positive integer (times)if (($timeVal.length 1 ||$timeVal.length 2 ||$timeVal.length 4) _.isInteger(parseInt($timeVal))) {radioRef.value specificTimespecificTimesRef.value [parseInt($timeVal)]return}// Interval timesif ($interval) {radioRef.value intervalTimeintervalStartRef.value parseInt($interval[0])intervalPerformRef.value parseInt($interval[1])timeRef.value ${intervalStartRef.value}/${intervalPerformRef.value}return}// Specific timesif ($specific) {radioRef.value specificTimespecificTimesRef.value $specific.map((item) parseInt(item))return}}// Interval start time1const onIntervalStart (value: number | null) {intervalStartRef.value value || 0if (radioRef.value intervalTime) {timeRef.value ${intervalStartRef.value}/${intervalPerformRef.value}}}// Interval execution time2const onIntervalPerform (value: number | null) {intervalPerformRef.value value || 0if (radioRef.value intervalTime) {timeRef.value ${intervalStartRef.value}/${intervalPerformRef.value}}}// Specific timeconst onSpecificTimes (arr: Arraynumber) {specificTimesRef.value arrif (radioRef.value specificTime) {specificReset()}}// Reset interval timeconst intervalReset () {timeRef.value ${intervalStartRef.value}/${intervalPerformRef.value}}// Reset specific timeconst specificReset () {let timeValue 0if (specificTimesRef.value.length) {timeValue specificTimesRef.value.join(,)}timeRef.value timeValue}const updateRadioTime (value: string) {switch (value) {case intervalTime:intervalReset()breakcase 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 (NRadioGroupv-model:value{this.radioRef}onUpdateValue{this.updateRadioTime}div class{styles[crontab-list]}NRadio value{intervalTime} /div class{styles[crontab-list-item]}div class{styles[item-text]}{t(this.timeI18n!.every)}/divdiv class{styles[number-input]}NInputNumberdefaultValue{5}min{this.timeMin}max{this.timeMax}v-model:value{this.intervalPerformRef}onUpdateValue{this.onIntervalPerform}//divdiv class{styles[item-text]}{t(this.timeI18n!.timeCarriedOut)}/divdiv class{styles[number-input]}NInputNumberdefaultValue{3}min{this.timeMin}max{this.timeMax}v-model:value{this.intervalStartRef}onUpdateValue{this.onIntervalStart}//divdiv class{styles[item-text]}{t(this.timeI18n!.timeStart)}/div/div/divdiv class{styles[crontab-list]}NRadio value{specificTime} /div class{styles[crontab-list-item]}div{t(this.timeI18n!.specificTime)}/divdiv class{styles[select-input]}NSelectmultipleoptions{specificList[this.timeSpecial]}placeholder{t(this.timeI18n!.specificTimeTip)}v-model:value{this.specificTimesRef}onUpdateValue{this.onSpecificTimes}//div/div/div/NRadioGroup)}
})服务端
添加Crontab表达式检验有两处一处是新增Post接口、另一处是修改PUT接口直接添加个检测方法供这两处调用 if (scheduleParam.getCrontab().startsWith(*)) {logger.error(The crontab must not start with *);putMsg(result, Status.CRONTAB_EVERY_SECOND_ERROR);return result;}本文完 本文由 白鲸开源科技 提供发布支持