>웹 프론트엔드 >JS 튜토리얼 >Apache DolphinScheduler는 두 번째 수준에서 타이밍 예약을 제한합니다.

Apache DolphinScheduler는 두 번째 수준에서 타이밍 예약을 제한합니다.

Barbara Streisand
Barbara Streisand원래의
2024-12-22 14:55:13406검색

Apache DolphinScheduler Restricts Timing Scheduling at the Second Level

배경

Apache DolphinScheduler의 타이밍 작업 구성은 초, 분, 시간, 일, 월, 요일 및 연도에 해당하는 7위치 Crontab 표현식을 사용합니다.

우리 팀의 일상적인 개발 작업에서 워크플로의 타이밍 일정은 일반적으로 두 번째 수준까지 자세히 설명할 필요가 없습니다. 그러나 1분마다 실행해야 하는 워크플로가 1초마다 실행되도록 잘못 구성되어 짧은 시간 내에 많은 수의 워크플로 인스턴스가 생성되어 영향을 미치는 등 오류 시간을 초래하는 잘못된 구성 사고가 역사적으로 있었습니다. Apache DolphinScheduler 서비스 및 작업이 제출되는 Hadoop 클러스터의 가용성.

이를 토대로 팀은 플랫폼 수준에서 이러한 사고가 발생하지 않도록 DolphinScheduler의 타이밍 작업 구성 모듈에서 Crontab 표현을 제한하기로 결정했습니다.

해결책

우리의 해결책은 Crontab 표현식의 첫 번째 위치를 전면과 후면 모두에서 제한하는 것입니다.

  • 프런트엔드 구성에서는 "매초" 옵션을 제공하지 않습니다
  • 첫 번째 위치가 *
  • 일 때 서버 측 인터페이스에서 오류를 반환합니다.

프런트엔드 수정

프런트엔드 프로젝트에서는 초, 분, 시간이 모두 통합 템플릿(CrontabTime)이므로 새로운 파일이 추가됩니다: 돌핀스케줄러-ui/src/comComponents/crontab/modules/second.tsx

intervalTime 및 특정Time의 두 가지 모드만 유지됩니다

/*
 * 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.