dolphinscheduler 2.0.5和2.0.6 体验记录及优化扩展(任务出现kill状态、未设置延时执行出现延时执行、系统变量扩展)

news2025/7/6 20:38:08

目录

  • 🐬未停止工作流的情况下出现kill状态的任务实例
  • 🐬未设置延时执行出现延时执行
    • 🐠集群服务器时间有误差导致的
    • 🐠优化:增加延时时间判断
  • 🐬系统变量
    • 🐠第N周扩展

*️⃣主目录:dolphinscheduler 3.0.1功能梳理及源码解读

🐬未停止工作流的情况下出现kill状态的任务实例


停止工作流的时候,其下的任务节点会出现kill状态,除此之外还有一种情况,手动运行选择失败策略的时候,任务节点同样被kill掉:

  • 模拟失败
    在这里插入图片描述
  • 手动运行选择结束
    在这里插入图片描述 - 状态停止/kill
    在这里插入图片描述
    在这里插入图片描述
  • 停止和选择结束,工作流实例状态都是停止(2.0.5版本测试结果:工作流实例为失败,任务状态为kill)
    在这里插入图片描述

🐬未设置延时执行出现延时执行


创建工作流,延时执行时间为0,但是任务执行的时候出现延迟执行状态(2.0.5版本),2.0.6则显示提交成功(还不如2.0.5正确呢,延时的时候状态应该为延时执行)
在这里插入图片描述

  • 2.0.5
    在这里插入图片描述
  • 2.0.6
    在这里插入图片描述

🐠集群服务器时间有误差导致的


在这里插入图片描述

🐠优化:增加延时时间判断


org.apache.dolphinscheduler.common.Constants.DateUtils.getRemainTime(Date baseTime, long intervalSeconds)
public static long getRemainTime(Date baseTime, long intervalSeconds) {
        if (baseTime == null || intervalSeconds == 0) {
            return 0;
        }
        long usedTime = (System.currentTimeMillis() - baseTime.getTime()) / 1000;
        return intervalSeconds - usedTime;
    }

在这里插入图片描述

🐬系统变量


详见官网
在这里插入图片描述

  • 日常调度实例定时的定时时间前一天:${system.biz.date} ,格式为 yyyyMMdd
  • 日常调度实例定时的定时时间:${system.biz.curdate} ,格式为 yyyyMMdd
  • 日常调度实例定时的定时时间:${system.datetime} ,格式为 yyyyMMddHHmmss
  • 后 N 年:$[add_months(yyyyMMdd,12*N)]
  • 前 N 年:$[add_months(yyyyMMdd,-12*N)]
  • 后 N 月:$[add_months(yyyyMMdd,N)]
  • 前 N 月:$[add_months(yyyyMMdd,-N)]
  • 后 N 周:$[yyyyMMdd+7*N]
  • 前 N 周:$[yyyyMMdd-7*N]
  • 后 N 天:$[yyyyMMdd+N]
  • 前 N 天:$[yyyyMMdd-N]
  • 后 N 小时:$[HHmmss+N/24]
  • 前 N 小时:$[HHmmss-N/24]
  • 后 N 分钟:$[HHmmss+N/24/60]
  • 前 N 分钟:$[HHmmss-N/24/60]

🐠第N周扩展


调度本身支持当前是第几周(小写w):$[w],假如现在是第48周,需要前一周,即47;参照add_months方法增加week_pre方法,参数直接复用现有的方法,详情如下:

org.apache.dolphinscheduler.spi.task.paramparser.TimePlaceholderUtils

在这里插入图片描述
在这里插入图片描述

  • 定义常量,前第几周方法week_pre(2.0.5版本)
    public static final String WEEK_PRE = "week_pre";
    
    • TimePlaceholderUtils(2.0.5版本)
    /*
     * 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.
     */
    
    package org.apache.dolphinscheduler.spi.task.paramparser;
    
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.ADD_CHAR;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.ADD_MONTHS;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.ADD_STRING;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.DIVISION_CHAR;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.DIVISION_STRING;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.LEFT_BRACE_CHAR;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.LEFT_BRACE_STRING;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.MONTH_BEGIN;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.MONTH_END;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.MULTIPLY_CHAR;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.MULTIPLY_STRING;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.N;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.P;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_FORMAT_TIME;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.RIGHT_BRACE_CHAR;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.SUBTRACT_CHAR;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.SUBTRACT_STRING;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.TIMESTAMP;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.WEEK_BEGIN;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.WEEK_END;
    import static org.apache.dolphinscheduler.spi.task.TaskConstants.WEEK_PRE;
    import static org.apache.dolphinscheduler.spi.utils.DateUtils.addDays;
    import static org.apache.dolphinscheduler.spi.utils.DateUtils.addMinutes;
    import static org.apache.dolphinscheduler.spi.utils.DateUtils.addMonths;
    
    import java.util.AbstractMap;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    import java.util.Stack;
    
    import org.apache.dolphinscheduler.spi.utils.DateUtils;
    import org.apache.dolphinscheduler.spi.utils.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * time place holder utils
     */
    public class TimePlaceholderUtils {
        private static final Logger logger = LoggerFactory.getLogger(TimePlaceholderUtils.class);
    
        /**
         * Prefix of the position to be replaced
         */
        public static final String PLACEHOLDER_PREFIX = "$[";
    
        /**
         * The suffix of the position to be replaced
         */
        public static final String PLACEHOLDER_SUFFIX = "]";
    
        /**
         * Replaces all placeholders of format {@code ${name}} with the value returned
         * from the supplied {@link PropertyPlaceholderHelper.PlaceholderResolver}.
         *
         * @param value                          the value containing the placeholders to be replaced
         * @param date                           custom date
         * @param ignoreUnresolvablePlaceholders ignore unresolvable placeholders
         * @return the supplied value with placeholders replaced inline
         */
        public static String replacePlaceholders(String value, Date date, boolean ignoreUnresolvablePlaceholders) {
            PropertyPlaceholderHelper strictHelper = getPropertyPlaceholderHelper(false);
            PropertyPlaceholderHelper nonStrictHelper = getPropertyPlaceholderHelper(true);
    
            PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
            return helper.replacePlaceholders(value, new TimePlaceholderResolver(value, date));
        }
    
        /**
         * Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
         *
         * @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should
         *                                       be ignored ({@code true}) or cause an exception ({@code false})
         */
        private static PropertyPlaceholderHelper getPropertyPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
            return new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, null, ignoreUnresolvablePlaceholders);
        }
    
        /**
         * calculate expression's value
         *
         * @param expression expression
         * @return expression's value
         */
        public static Integer calculate(String expression) {
            expression = StringUtils.trim(expression);
            expression = convert(expression);
    
            List<String> result = string2List(expression);
            result = convert2SuffixList(result);
    
            return calculate(result);
        }
    
        /**
         * Change the sign in the expression to P (positive) N (negative)
         *
         * @param expression
         * @return eg. "-3+-6*(+8)-(-5) -> S3+S6*(P8)-(S5)"
         */
        private static String convert(String expression) {
            char[] arr = expression.toCharArray();
    
            for (int i = 0; i < arr.length; i++) {
                if (arr[i] == SUBTRACT_CHAR) {
                    if (i == 0) {
                        arr[i] = N;
                    } else {
                        char c = arr[i - 1];
                        if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) {
                            arr[i] = N;
                        }
                    }
                } else if (arr[i] == ADD_CHAR) {
                    if (i == 0) {
                        arr[i] = P;
                    } else {
                        char c = arr[i - 1];
                        if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) {
                            arr[i] = P;
                        }
                    }
                }
            }
    
            return new String(arr);
        }
    
        /**
         * to suffix expression
         *
         * @param srcList
         * @return
         */
        private static List<String> convert2SuffixList(List<String> srcList) {
            List<String> result = new ArrayList<>();
            Stack<String> stack = new Stack<>();
    
            for (int i = 0; i < srcList.size(); i++) {
                if (Character.isDigit(srcList.get(i).charAt(0))) {
                    result.add(srcList.get(i));
                } else {
                    switch (srcList.get(i).charAt(0)) {
                        case LEFT_BRACE_CHAR:
                            stack.push(srcList.get(i));
                            break;
                        case RIGHT_BRACE_CHAR:
                            while (!LEFT_BRACE_STRING.equals(stack.peek())) {
                                result.add(stack.pop());
                            }
                            stack.pop();
                            break;
                        default:
                            while (!stack.isEmpty() && compare(stack.peek(), srcList.get(i))) {
                                result.add(stack.pop());
                            }
                            stack.push(srcList.get(i));
                            break;
                    }
                }
            }
    
            while (!stack.isEmpty()) {
                result.add(stack.pop());
            }
    
            return result;
        }
    
        /**
         * Calculate the suffix expression
         *
         * @param result
         * @return
         */
        private static Integer calculate(List<String> result) {
            Stack<Integer> stack = new Stack<>();
            for (int i = 0; i < result.size(); i++) {
                if (Character.isDigit(result.get(i).charAt(0))) {
                    stack.push(Integer.parseInt(result.get(i)));
                } else {
                    Integer backInt = stack.pop();
                    Integer frontInt = 0;
                    char op = result.get(i).charAt(0);
    
                    if (!(op == P || op == N)) {
                        frontInt = stack.pop();
                    }
    
                    Integer res = 0;
                    switch (result.get(i).charAt(0)) {
                        case P:
                            res = frontInt + backInt;
                            break;
                        case N:
                            res = frontInt - backInt;
                            break;
                        case ADD_CHAR:
                            res = frontInt + backInt;
                            break;
                        case SUBTRACT_CHAR:
                            res = frontInt - backInt;
                            break;
                        case MULTIPLY_CHAR:
                            res = frontInt * backInt;
                            break;
                        case DIVISION_CHAR:
                            res = frontInt / backInt;
                            break;
                        default:
                            break;
                    }
                    stack.push(res);
                }
            }
    
            return stack.pop();
        }
    
        /**
         * string to list
         *
         * @param expression
         * @return list
         */
        private static List<String> string2List(String expression) {
            List<String> result = new ArrayList<>();
            String num = "";
            for (int i = 0; i < expression.length(); i++) {
                if (Character.isDigit(expression.charAt(i))) {
                    num = num + expression.charAt(i);
                } else {
                    if (!num.isEmpty()) {
                        result.add(num);
                    }
                    result.add(expression.charAt(i) + "");
                    num = "";
                }
            }
    
            if (!num.isEmpty()) {
                result.add(num);
            }
    
            return result;
        }
    
        /**
         * compare loginUser level
         *
         * @param peek
         * @param cur
         * @return true or false
         */
        private static boolean compare(String peek, String cur) {
            if (MULTIPLY_STRING.equals(peek) && (DIVISION_STRING.equals(cur) || MULTIPLY_STRING.equals(cur) || ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
                return true;
            } else if (DIVISION_STRING.equals(peek) && (DIVISION_STRING.equals(cur) || MULTIPLY_STRING.equals(cur) || ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
                return true;
            } else if (ADD_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
                return true;
            } else {
                return SUBTRACT_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur));
            }
    
        }
    
        /**
         * Placeholder replacement resolver
         */
        private static class TimePlaceholderResolver implements
            PropertyPlaceholderHelper.PlaceholderResolver {
    
            private final String value;
    
            private final Date date;
    
            public TimePlaceholderResolver(String value, Date date) {
                this.value = value;
                this.date = date;
            }
    
            @Override
            public String resolvePlaceholder(String placeholderName) {
                try {
                    return calculateTime(placeholderName, date);
                } catch (Exception ex) {
                    logger.error("resolve placeholder '{}' in [ {} ]", placeholderName, value, ex);
                    return null;
                }
            }
        }
    
        /**
         * return the formatted date according to the corresponding date format
         *
         * @param expression date expression
         * @param date       date
         * @return reformat date
         */
        public static String getPlaceHolderTime(String expression, Date date) {
            if (StringUtils.isBlank(expression)) {
                return null;
            }
            if (null == date) {
                return null;
            }
            return calculateTime(expression, date);
        }
    
        /**
         * calculate time
         *
         * @param date date
         * @return calculate time
         */
        private static String calculateTime(String expression, Date date) {
            // After N years: $[add_months(yyyyMMdd,12*N)], the first N months: $[add_months(yyyyMMdd,-N)], etc
            String value;
    
            try {
                if (expression.startsWith(TIMESTAMP)) {
                    String timeExpression = expression.substring(TIMESTAMP.length() + 1, expression.length() - 1);
    
                    Map.Entry<Date, String> entry = calcTimeExpression(timeExpression, date);
    
                    String dateStr = DateUtils.format(entry.getKey(), entry.getValue());
    
                    Date timestamp = DateUtils.parse(dateStr, PARAMETER_FORMAT_TIME);
    
                    value = String.valueOf(timestamp.getTime() / 1000);
                } else {
                    Map.Entry<Date, String> entry = calcTimeExpression(expression, date);
                    value = DateUtils.format(entry.getKey(), entry.getValue());
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw e;
            }
    
            return value;
        }
    
        /**
         * calculate time expresstion
         *
         * @param expression expresstion
         * @param date       date
         * @return map with date, date format
         */
        public static Map.Entry<Date, String> calcTimeExpression(String expression, Date date) {
            Map.Entry<Date, String> resultEntry;
    
            if (expression.startsWith(ADD_MONTHS)) {
                resultEntry = calcMonths(expression, date);
            } else if (expression.startsWith(MONTH_BEGIN)) {
                resultEntry = calcMonthBegin(expression, date);
            } else if (expression.startsWith(MONTH_END)) {
                resultEntry = calcMonthEnd(expression, date);
            } else if (expression.startsWith(WEEK_BEGIN)) {
                resultEntry = calcWeekStart(expression, date);
            } else if (expression.startsWith(WEEK_END)) {
                resultEntry = calcWeekEnd(expression, date);
            } else if (expression.startsWith(WEEK_PRE)) {
            	resultEntry = calcWeekPre(expression, date);
            } else {
                resultEntry = calcMinutes(expression, date);
            }
    
            return resultEntry;
        }
    
        /**
         * get first day of month
         *
         * @param expression expresstion
         * @param date       date
         * @return first day of month
         */
        public static Map.Entry<Date, String> calcMonthBegin(String expression, Date date) {
            String addMonthExpr = expression.substring(MONTH_BEGIN.length() + 1, expression.length() - 1);
            String[] params = addMonthExpr.split(COMMA);
    
            if (params.length == 2) {
                String dateFormat = params[0];
                String dayExpr = params[1];
                Integer day = calculate(dayExpr);
                Date targetDate = DateUtils.getFirstDayOfMonth(date);
                targetDate = addDays(targetDate, day);
    
                return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
            }
    
            throw new RuntimeException("expression not valid");
        }
    
        /**
         * get last day of month
         *
         * @param expression expresstion
         * @param date       date
         * @return last day of month
         */
        public static Map.Entry<Date, String> calcMonthEnd(String expression, Date date) {
            String addMonthExpr = expression.substring(MONTH_END.length() + 1, expression.length() - 1);
            String[] params = addMonthExpr.split(COMMA);
    
            if (params.length == 2) {
                String dateFormat = params[0];
                String dayExpr = params[1];
                Integer day = calculate(dayExpr);
                Date targetDate = DateUtils.getLastDayOfMonth(date);
                targetDate = addDays(targetDate, day);
    
                return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
            }
    
            throw new RuntimeException("expression not valid");
        }
    
        /**
         * get first day of week
         *
         * @param expression expresstion
         * @param date       date
         * @return monday
         */
        public static Map.Entry<Date, String> calcWeekStart(String expression, Date date) {
            String addMonthExpr = expression.substring(WEEK_BEGIN.length() + 1, expression.length() - 1);
            String[] params = addMonthExpr.split(COMMA);
    
            if (params.length == 2) {
                String dateFormat = params[0];
                String dayExpr = params[1];
                Integer day = calculate(dayExpr);
                Date targetDate = DateUtils.getMonday(date);
                targetDate = addDays(targetDate, day);
                return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
            }
    
            throw new RuntimeException("expression not valid");
        }
    
        /**
         * get last day of week
         *
         * @param expression expresstion
         * @param date       date
         * @return last day of week
         */
        public static Map.Entry<Date, String> calcWeekEnd(String expression, Date date) {
            String addMonthExpr = expression.substring(WEEK_END.length() + 1, expression.length() - 1);
            String[] params = addMonthExpr.split(COMMA);
    
            if (params.length == 2) {
                String dateFormat = params[0];
                String dayExpr = params[1];
                Integer day = calculate(dayExpr);
                Date targetDate = DateUtils.getSunday(date);
                targetDate = addDays(targetDate, day);
    
                return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
            }
    
            throw new RuntimeException("Expression not valid");
        }
        
        /**
         * 获取前N周. rxz 20221126
         * @param expression
         * @param date
         * @return
         */
        public static Map.Entry<Date, String> calcWeekPre(String expression, Date date) {
        	String calcWeekPre = expression.substring(WEEK_PRE.length() + 1, expression.length() - 1);
            String[] params = calcWeekPre.split(COMMA);
            if (params.length == 2) {
                String dateFormat = params[0];
                String dayExpr = params[1];
                return calcMinutes(dateFormat, calcMinutes("yyyyMMdd-7*"+dayExpr,date).getKey());
            }
            throw new RuntimeException("Expression not valid:" + expression);
        }
    
        /**
         * calc months expression
         *
         * @param expression expresstion
         * @param date       date
         * @return calc months
         */
        public static Map.Entry<Date, String> calcMonths(String expression, Date date) {
            String addMonthExpr = expression.substring(ADD_MONTHS.length() + 1, expression.length() - 1);
            String[] params = addMonthExpr.split(COMMA);
    
            if (params.length == 2) {
                String dateFormat = params[0];
                String monthExpr = params[1];
                Integer addMonth = calculate(monthExpr);
                Date targetDate = addMonths(date, addMonth);
    
                return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
            }
    
            throw new RuntimeException("expression not valid");
        }
    
        /**
         * calculate time expression
         *
         * @param expression expresstion
         * @param date       date
         * @return calculate time expression with date,format
         */
        public static Map.Entry<Date, String> calcMinutes(String expression, Date date) {
            if (expression.contains("+")) {
                int index = expression.lastIndexOf('+');
    
                if (Character.isDigit(expression.charAt(index + 1))) {
                    String addMinuteExpr = expression.substring(index + 1);
                    Date targetDate = addMinutes(date, calcMinutes(addMinuteExpr));
                    String dateFormat = expression.substring(0, index);
    
                    return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
                }
            } else if (expression.contains("-")) {
                int index = expression.lastIndexOf('-');
    
                if (Character.isDigit(expression.charAt(index + 1))) {
                    String addMinuteExpr = expression.substring(index + 1);
                    Date targetDate = addMinutes(date, 0 - calcMinutes(addMinuteExpr));
                    String dateFormat = expression.substring(0, index);
    
                    return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
                }
    
                // yyyy-MM-dd/HH:mm:ss
                return new AbstractMap.SimpleImmutableEntry<>(date, expression);
            }
    
            // $[HHmmss]
            return new AbstractMap.SimpleImmutableEntry<>(date, expression);
        }
    
        /**
         * calculate need minutes
         *
         * @param minuteExpression minute expression
         * @return calculate need minutes
         */
        public static Integer calcMinutes(String minuteExpression) {
            int index = minuteExpression.indexOf('/');
    
            String calcExpression;
    
            if (index == -1) {
                calcExpression = String.format("60*24*(%s)", minuteExpression);
            } else {
    
                calcExpression = String.format("60*24*(%s)%s", minuteExpression.substring(0, index),
                    minuteExpression.substring(index));
            }
    
            return calculate(calcExpression);
        }
    
    }
    
  • 使用,例如前一周:$[week_pre(w,1)],2则是前两周,改成负数应该是后第几周,这个未测试,应该也是没问题的
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/37564.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kettle:跨库(SQLServer-PostgreSQL)同步多张表数据的详细设计过程

〇、参考地址 1、多个Excel实现同步 https://www.wangt.cc/2021/05/kettle%E5%A4%9A%E4%B8%AA%E8%A1%A8%E4%B8%80%E8%B5%B7%E8%BF%81%E7%A7%BB-%E9%80%9A%E8%BF%87%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E9%85%8D%E7%BD%AE%E9%9C%80%E8%A6%81%E5%90%8C%E6%AD%A5%E7%9A%84%E5%AD…

Java搭建实战基于若依springboot二次开发WMS带移动端管理系统vue源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 有个朋友发了一套基于若依开发的springboot源码给我&#xff0c;让我帮忙看一下&#xff0c;录制一期视频教程出来&#xff0c;我看了一下&#xff0c;系统是前后端分离的架构&#xff0c;前端使用Vue2&#xff0…

Ubuntu20.04安装graph-tool

目录step1&#xff1a;查看系统发行版本step2: 在 /etc/apt/sources.list文件中添加一行step3: 下载密钥step4: 更新apt-getstep5: 下载graph-toolstep6&#xff1a;移动graph-tool包到anaconda下step7: 测试是否安装成功链接: 官方安装教程注&#xff1a;如果下列过程中出现权…

cesium在地形上贴地添加各种entity

目录 添加带标签的点 添加billboard 添加corridor 添加面polygon 添加带图片的面polygon 添加矩形 添加glb模型 被遮挡的线用其他颜色标注 添加贴地线 官方示例&#xff1a;Cesium Sandcastlehttps://sandcastle.cesium.com/?srcClamp%20to%20Terrain.html&labelTutor…

都已过35+程序员高危高龄,我为什么还要学习python?

前言 首先声明一点&#xff1a;学习PYTHON&#xff0c;绝不是要去当一名“憔悴的”程序猿~ &#xff08;文末送读者福利&#xff09; 去互联网大厂&#xff1f;则更是谈不上。就算我想去&#xff0c;大厂也是看不上。 年龄看不上&#xff08;已过程序员35岁之高龄&#xff0…

学生个人网页设计作品 学生个人网页模板 简单个人主页成品 个人网页制作 HTML学生个人网站作业设计代做

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

LaTex常用技巧6:矩阵编写总结

本文记录和总结了LaTex编写矩阵的一些要点&#xff0c;具体参考这位博主半个冯博士的知乎文章如何用latex编写矩阵&#xff08;包括各类复杂、大型矩阵&#xff09;&#xff1f; 无括号矩阵圆括号矩阵方括号矩阵大括号矩阵行列式范数分块矩阵竖实线竖虚线横实线横虚线其他要点横…

redis的下载和安装详解

一、下载redis安装包 进入redis官网查看当前稳定版本&#xff1a; https://redis.io/download/发现此时的稳定版本是6.2.4&#xff0c; 此时可以去这个网站下载6.2.4稳定版本的tar包。 暂时不考虑不在windows上使用redis&#xff0c;那样将无法发挥redis的性能 二、上传tar…

智能疾病查询接口

一、接口介绍 最全的疾病大全&#xff0c;收集了数万种常见疾病&#xff0c;任何常见疾病都可查询。 二、功能体验 三、API文档 3.1 查询疾病科目 3.1.1接入点说明 查询疾病的类别。 3.1.2接口地址 http[s]&#x1f615;/www.idmayi.com/546-1?idmayi_appid替换自己的值&…

spring复习02,xml配置管理bean

spring复习02,xml配置管理bean获取bean的几种方式1. 通过id获取bean2. 通过class获取bean3. id和class结合来获取bean依赖注入的两种方式setter注入有参构造器注入依赖注入时一些特殊值的处理1.字面量2.null值3.xml实体4.CDATA节为类类属性赋值1.引入已经声明的bean的方式2.内部…

在springboot工程中修改使用quartz创建的定时任务

Quratz是什么: Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。 Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。 Quartz 允许程序开发人员根据时间的间隔来调度作业。 Quartz 实现了作业和触发器的…

CTF-misc练习(https://buuoj.cn)之第二页

目录 一、被劫持的神秘礼物 二、刷新过的图片 三、[BTF2020]认真你就输了 四、[BJDCTF2020]藏藏藏 五、被偷走的流量 九、菜刀666 十、秘密文件 十一、[BJDCTF2020]just_a_rar 十二、[BJDCTF2020]鸡你太美 十三、[BJDCTF2020]一叶障目 十四、神奇的二维码 十五、梅…

mysql必知必会

名词 数据库软件 &#xff1a; DBMS(database manager system) 数据库 &#xff1a;database, 通过DBMS创建和操作的容器, 保存有组织的数据的容器&#xff0c;&#xff0c;&#xff0c;通常是一个文件或者一组文件 表&#xff1a; 是一种结构化文件&#xff0c;&#xff0c;…

安科瑞水电预付费平台,远程控制,高校宿舍、员工宿舍、商场等多场合适用

安科瑞 司红霞 一、引言 预付费水表是一种为了适应“先付费后用水”的管理原则和系统而开发的水表产品其设计是在水表基表上加装了电子附加装置和控制阀&#xff0c;要求用户先预付&#xff0c;一定的费用或购置一定数量的水量&#xff0c;将预付费的信息输入水表后才可正常用…

四轴斜转魔方

目录 四轴斜转魔方 1&#xff0c;魔方三要素 2&#xff0c;公式推导 &#xff08;1&#xff09;调整8个角块位置 &#xff08;2&#xff09;调整6个中心块位置 &#xff08;3&#xff09;调整角块方向 四轴斜转魔方 1&#xff0c;魔方三要素 &#xff08;1&#xff09;组…

Sentinel实现服务降级并与api解耦

Sentinel怎样实现熔断降级 熔断降级介绍 sentinel支持服务的熔断降级 熔断类似于保险丝&#xff0c;在超出了阈值的情况下&#xff0c;在一定的时间内不会执行业务逻辑&#xff0c;直接执行服务降级的方法。服务降级利用本地fallback方法&#xff0c;返回一个有好的提示给客…

Scala配置和Spark配置以及Scala一些函数的用法(附带词频统计实例)

文章目录配置Spark配置Scala生成RDDfilter过滤器map方法flatMap方法reduceByKeyspark下wordcount程序参考先给出spark和Scala的下载地址&#xff0c;这是我用的版本https://pan.baidu.com/s/1rcG1xckk3zmp9BLmf74hsg?pwd1111也可以自己去官网下载。配置Spark 解压文件到softw…

public,private,protected,default的区别

public public&#xff08;公开&#xff09;表示任何人都可以访问和使用该元素&#xff1b; public class Test {public static void main(String[] args) {Person pnew Person();System.out.println(p.name);//输出小明} } class Person{public String name"小明"…

Go 开发环境安装之Goland和vscode

一、前言 Go语言或将成为新的主力开发语言&#xff0c;Go是google开发的一种静态强类型、编译型、并发型&#xff0c;并具有垃圾回收功能的编程语言&#xff0c;所以我们有必要学习并掌握它。第一件事情&#xff0c;就是把环境搭建起来&#xff0c;大家可以跟着步骤一起将Go语…

【计算机网络】数据链路层:点对点协议PPP

对于点对点链路&#xff0c;目前使用最为广泛的数据链路层协议是点对点协议PPP。 简单&#xff08;首要要求&#xff09; 封装成帧&#xff1a;保证数据传输的透明性 多种网络层协议&#xff1a;能够在同一条物理链路上同时支持多种网络层协议。 多种类型链路&#xff1a;能…