前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Quick-Task 动态脚本支持框架之使用介绍篇

Quick-Task 动态脚本支持框架之使用介绍篇

作者头像
一灰灰blog
发布于 2018-07-29 09:21:06
发布于 2018-07-29 09:21:06
3950
举报
文章被收录于专栏:小灰灰小灰灰
logo
logo

文章链接:https://liuyueyi.github.io/hexblog/2018/07/19/180719-Quick-Task-动态脚本支持框架之使用介绍篇/

Quick-Task 动态脚本支持框架之使用介绍篇

相关博文:

QuickTask这个项目主要就是为了解决数据订正和接口验证不方便的场景,设计的一个及其简单的动态脚本调度框架,前面一篇整体介绍篇博文,主要介绍了这是个什么东西,整体的运行原理,以及一些简单的使用demo

本篇博文将主要放在应用场景的探讨上,在实际的项目环境中,可以怎么用

<!-- more -->

I. 框架使用姿势

支目前来说,有两种简单的使用方式,一是以独立的jar包来运行,二是集成在已有的项目中运行;下面分别给出介绍

1. 独立jar包运行

独立jar包下载,首先下载原始工程,然后打出一个可执行的jar包即可

代码语言:txt
AI代码解释
复制
git clone https://github.com/liuyueyi/quick-task
cd quick-task/task-core
mvn clean package -Dmaven.test.skip
cd target
java -jar task-core-0.0.1.jar --task /tmp/script

注意上面的jar包执行中,传入的--task参数,这个就是制定监听动态脚本的目录,如上面的脚本,表示框架会自动加载 /tmp/script 目录下的Groovy脚本,并执行

当脚本发生变动时,同样会重新加载更新后的groovy并执行,且会停掉原来的脚本

2. 项目依赖使用

作为一个依赖来使用也是可以的,首先是添加pom依赖

代码语言:txt
AI代码解释
复制
<repositories>
    <repository>
        <id>yihui-maven-repo</id>
        <url>https://raw.githubusercontent.com/liuyueyi/maven-repository/master/repository</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.git.hui</groupId>
    <artifactId>task-core</artifactId>
    <version>0.0.1</version>
</dependency>

然后在自己的代码中,显示的调用下面一行代码即可,其中run方法的参数为动态脚本的目录

代码语言:txt
AI代码解释
复制
new ScriptExecuteEngine().run("/tmp/script");

对于SpringBoot项目而言,可以在入口Application类的run方法中调用,一个demo如下

代码语言:txt
AI代码解释
复制
@SpringBootApplication
public class Application implements CommandLineRunner {
    public static void main(String[] args) throws Exception {
        SpringApplication app = new SpringApplication(Application.class);
        app.run(args);
    }

    @Override
    public void run(String... strings) throws Exception {
        new ScriptExecuteEngine().run("/tmp/script");
    }
}

对于传统的Spring项目而言,可以新建一个Listener, 监听所有的bean初始化完成之后,开始注册任务引擎,一个可参考的使用case如下

代码语言:txt
AI代码解释
复制
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class RegisterTaskEngineListener implements SmartApplicationListener {
    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) {
        return aClass == ContextRefreshedEvent.class;
    }

    @Override
    public boolean supportsSourceType(Class<?> aClass) {
        return true;
    }

    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        new ScriptExecuteEngine().run("/tmp/script");
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

3. 对比小结

两种使用方式,从个人角度出发,并没有什么优劣之别,主要还是看具体的业务场景,当希望部署一个独立的任务脚本支持时,可能独立的部署更加的方便,可以在内部进行资源隔离,减少对线上生产环境的影响;

若是单纯的把这个作为一个检测项目运行的辅助工具时,如回调线上的服务接口,判断输出,获取运行项目中的内部参数等,集成在已有的项目中也是比较简单的

II. 实际场景演示

使用了这个框架,到底有什么用处呢?或者说是否有一些适用的经典case呢?

1. 数据查看

这种场景比较常见,但一般配套设施齐全的公司,也不会出现这个问题,我们最常见的查看数据有以下几类

  • DB数据查看
  • 缓存数据查看
  • 内存数据查看

对于DB查看,一般没啥问题,要么可以直连查询要么就是有查询工具;而缓存数据的查询,主要是我们通过序列化后存入的数据,直接从缓存中获取可能并不太友好;对于运行时内存中的数据,就不太好获取了,特别是我们使用Guava缓存的数据,如何在项目运行中判断缓存中的数据是否有问题呢?

一个查看内存的伪代码

代码语言:txt
AI代码解释
复制
class DemoScript implements ITask {
    @Override
    void run() {
        // 获取目标对象
        xxxBean = ApplicationContextHolder.getBean(xxx.class);
        xxxBean.getXXX();
    }
}

上面的脚本中,关键就是在于获取目标对象,拿到目标对象之后,再获取内部的局部变量或者内存数据就比较简单了(不能直接访问的局部变量可以通过反射获取)

所以关键就是获取目标对象,有下面几种思路可供参考:

  • 目标对象时单例或者静态类,则可以直接访问
  • 如果项目运行在Spring容器中,且目标对象为Bean,则可以通过 ApplicationContext#getBean 方式获取

2. 接口调用

在问题复现的场景下,比较常用了,传入相同的参数,判断接口的返回结果是否ok,用于定位数据异常

代码语言:txt
AI代码解释
复制
class DemoScript implements ITask {
    @Override
    void run() {
        // 获取目标对象
        xxxService = ApplicationContextHolder.getBean(xxx.class);
        
        req = buildRequest();
        result = xxxService.execute(req);
        log.info("result: {}", result);
    }
}

其实实际使用起来和前面没什么区别,无非是线获取到对应的Service,然后执行接口,当然在Spring的生态体系中,一个可展望的点就是支持自动注入依赖的bean

3. 定时任务

首先明确一点,在我们的框架中,所有的任务都是隔离的,独立的线程中调度的,当我们希望一个新的任务每隔多久执行一次,可以怎么做?

一个简单的伪代码如下

代码语言:txt
AI代码解释
复制
class DemoScript implements ITask {
    private volatile boolean run = false;
    @Override
    void run() {
        run = true;
        while(true) {
          doXXX();
          
          try {
            Thread.sleep(1000);
          } catch(Exception e) {
          }
          
          if(!run) break;
        }
    }
    
    @Override
    void interrupt() {
        run = false;
    }
}

注意下上面的实现,在run方法中,有一个死循环,一直在重复的调用 doxxx() 方法,在内部通过 Thread.sleep() 来控制频率

在脚本改变或删除之后,框架会回调 interrupt 方法,因此会将上面的run变量设置为false,从而结束死循环

注意:

  • 对于定时任务而言,后续会扩展一个对应ScheduleTask抽象类出来,将循环和中断的逻辑封装一下,对于使用方而言,只需要写业务逻辑即可,不需要关心这些重复的逻辑

4. mq消息消费

这种更多的是把这个框架作为一个调度来用,我们接收mq的消息,然后在动态脚本中进行处理,再传给第三方(如果集成在自己的项目中时,一个demo就是可以直接调用项目中的Dao保存数据)

一个RabbitMq的消费任务,对应的伪代码如下

代码语言:txt
AI代码解释
复制
class DemoScript implements ITask {
    @Override
    void run() {
      ConnectionFactory fac = new CachingConnectionFactory();
      fac.setHost("127.0.0.1");
      fac.setPort(5672);
      fac.setUsername("admin")
      fac.setPassword("admin")
      fac.setVirtualHost("/")
      
      //创建连接
      Connection connection = factory.newConnection();

      //创建消息信道
      final Channel channel = connection.createChannel();

      //消息队列
      channel.queueDeclare(queue, true, false, false, null);
      //绑定队列到交换机
      channel.queueBind(queue, exchange, routingKey);
     
      Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                    byte[] body) throws IOException {
                String message = new String(body, "UTF-8");

                try {
                    System.out.println(" [" + queue + "] Received '" + message);
                } finally {
                    channel.basicAck(envelope.getDeliveryTag(), false);
                }
            }
        };

        // 取消自动ack
        channel.basicConsume(queue, false, consumer);   
    }
}

注意:

  • 对于RabbitMQ的任务,后续计划封装一个抽象的任务脚本,使业务方只需要关注自己的消息处理即可,上面只是一个业务场景的使用演示

III. 其他

0. 相关

博文:

项目:

1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

2. 声明

尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

3. 扫描关注

小灰灰Blog&公众号

QrCode
QrCode

知识星球

zhishi
zhishi

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
QuickTask动态脚本支持框架整体介绍篇
一个简单的动态脚本调度框架,支持运行时,实时增加,删除和修改动态脚本,可用于后端的进行接口验证、数据订正,执行定时任务或校验脚本
一灰灰blog
2018/07/29
6440
QuickTask动态脚本支持框架整体介绍篇
Quick-Task 动态脚本支持框架之结构设计篇
文章链接:https://liuyueyi.github.io/hexblog/2018/07/23/180723-Quick-Task-动态脚本支持框架之结构设计篇/
一灰灰blog
2018/07/29
6360
Quick-Task 动态脚本支持框架之结构设计篇
180723-Quick-Task 动态脚本支持框架之结构设计篇
文章链接:https://liuyueyi.github.io/hexblog/2018/07/23/180723-Quick-Task-动态脚本支持框架之结构设计篇/
一灰灰blog
2022/01/17
2680
180723-Quick-Task 动态脚本支持框架之结构设计篇
Quick-Task 动态脚本支持框架之任务动态加载
前面几篇博文分别介绍了整个项目的基本架构,使用说明,以及整体框架的设计与实现初稿,接下来则进入更细节的实现篇,将整个工程中核心实现捞出来,从为什么这么设计到最终的实现给予说明
一灰灰blog
2018/07/29
5040
Quick-Task 动态脚本支持框架之任务动态加载
Quick-Task 动态脚本支持框架之Groovy脚本加载执行
上一篇简答说了如何判断有任务动态添加、删除或更新,归于一点就是监听文件的变化,判断目录下的Groovy文件是否有新增删除和改变,从而判定是否有任务的变更;
一灰灰blog
2018/08/07
1.2K0
Quick-Task 动态脚本支持框架之Groovy脚本加载执行
SpringBoot+MySQL实现动态定时任务
一个极简的基于springboot的动态定时任务demo,spring-context模块有对任务调度进行支持,本demo也是基于这个模块进行开发,功能相对简单,用户可以按需改造,比如添加运维界面,在界面上更加灵活的控制任务执行与更新。
科技新语
2025/05/09
1450
SpringBoot+MySQL实现动态定时任务
【SpringBoot 基础系列】事件机制的两种消费姿势
本项目借助SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA进行开发
一灰灰blog
2021/06/09
3680
Java反射机制与动态代理
Java 反射机制与动态代理我们平时写代码可能用得比较少,但在各种常见的框架(Spring、MyBatis 等)中却屡见不鲜。有句话叫“无反射,不框架;无代理,不框架”。
WriteOnRead
2019/12/27
7720
【SpringBoot 基础系列】实现一个自定义配置加载器(应用篇)
Spring 中提供了@Value注解,用来绑定配置,可以实现从配置文件中,读取对应的配置并赋值给成员变量;某些时候,我们的配置可能并不是在配置文件中,如存在 db/redis/其他文件/第三方配置服务,本文将手把手教你实现一个自定义的配置加载器,并支持@Value的使用姿势
一灰灰blog
2020/05/09
1K0
【SpringBoot 基础系列】实现一个自定义配置加载器(应用篇)
【SpringBoot 基础系列】接口上注解 AOP 拦截不到场景兼容实例演示
在 Java 的开发过程中,面向接口的编程可能是大家的常态,切面也是各位大佬使用 Spring 时,或多或少会使用的一项基本技能;结果这两个碰到一起,有意思的事情就发生了,接口方法上添加注解,面向注解的切面拦截,居然不生效
一灰灰blog
2021/06/08
3.1K0
【SpringBoot 基础系列】接口上注解 AOP 拦截不到场景兼容实例演示
SPI框架实现之旅一:背景介绍
SPI框架实现之旅一:背景介绍 SPI的全名为Service Provider Interface,简单的总结下java spi机制的思想。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 java sp
一灰灰blog
2018/02/06
1.4K0
SPI框架实现之旅一:背景介绍
SpringBoot实战基于异常日志的邮件报警
相信所有奋斗在一线的小伙伴,会很关心自己的系统的运行情况,一般来说,基础设施齐全一点的公司都会有完善的报警方案,那么如果我们是一个小公司呢,不能因为基础设施没有,就失去对象的感知能力吧;如果我们的系统大量异常却不能实时的触达给我们,那么也就只会有一个结果--杀个程序猿祭天
一灰灰blog
2021/08/09
1.4K0
SpringBoot实战基于异常日志的邮件报警
RabbitMQ基础教程之使用进阶篇
RabbitMQ基础教程之使用进阶篇 相关博文,推荐查看: RabbitMq基础教程之安装与测试 RabbitMq基础教程之基本概念 RabbitMQ基础教程之基本使用篇 I. 背景 前一篇基本使用篇的博文中,介绍了rabbitmq的三种使用姿势,可以知道如何向RabbitMQ发送消息以及如何消费,但遗留下几个疑问,本篇则主要希望弄清楚这几点 Exchange声明的问题(是否必须声明,如果不声明会怎样) Exchange声明的几个参数(durable, autoDelete)有啥区别 当没有队列和Excha
一灰灰blog
2018/06/04
1.2K0
【SpringBoot 基础系列】事件机制的两种消费姿势
借助Spring可以非常简单的实现事件监听机制,本文简单介绍下面向接口与注解监听的两种姿势
一灰灰blog
2021/06/03
5510
【SpringBoot 基础系列】事件机制的两种消费姿势
动手实现MVC: 3. AOP实现准备篇动态代理
背景 在实现AOP功能时,必然扰不开代理模式,所以在此之前,先准备下代理模式相关知识点 代理 关于代理,主要需要注意以下几个点 什么是代理模式 为什么要用代理 怎么用代理 静态代理怎么玩 动态代理怎么玩 jdk方式 cglib方式(同时可以了解下asm字节码框架) 简单记录 关于代理的博文实在是太多,而且大部分内容差不多,这里将主要记录一下个人的理解 1. 什么是代理模式 其实在现实生活中代理模式还是非常多得,这里引入一个代理商的概念来加以描述,本来一个水果园直接卖水果就好了,现在中间来了一个水果超市
一灰灰blog
2018/02/06
5260
【SpringBoot 基础系列】接口上注解 AOP 拦截不到场景兼容实例演示
在 Java 的开发过程中,面向接口的编程可能是大家的常态,切面也是各位大佬使用 Spring 时,或多或少会使用的一项基本技能;结果这两个碰到一起,有意思的事情就发生了,接口方法上添加注解,面向注解的切面拦截,居然不生效
一灰灰blog
2021/06/11
8040
【SpringBoot 基础系列】接口上注解 AOP 拦截不到场景兼容实例演示
Spring整合ZooKeeper基础使用介绍
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,广泛应用于分布式系统中,比如有用它做配置中心,注册中心,也有使用它来实现分布式锁的,作为高并发技术栈中不可或缺的一个基础组件,接下来我们将看一下,zk应该怎么玩,可以怎么玩
一灰灰blog
2021/04/28
1.4K0
Spring整合ZooKeeper基础使用介绍
SpringBoot应用篇之FactoryBean及代理实现SPI机制的实例
FactoryBean在Spring中算是一个比较有意思的存在了,虽然在日常的业务开发中,基本上不怎么会用到,但在某些场景下,如果用得好,却可以实现很多有意思的东西
一灰灰blog
2019/03/14
1.8K0
SpringBoot应用篇之FactoryBean及代理实现SPI机制的实例
RabbitMQ基础教程之基本使用篇
RabbitMQ基础教程之基本使用篇 最近因为工作原因使用到RabbitMQ,之前也接触过其他的mq消息中间件,从实际使用感觉来看,却不太一样,正好趁着周末,可以好好看一下RabbitMQ的相关知识点;希望可以通过一些学习,可以搞清楚以下几点 基础环境搭建 可以怎么使用 实现原理是怎样的 实际工程中的使用(比如结合SpringBoot可以怎么玩) <!-- more --> 相关博文,欢迎查看: 《RabbitMq基础教程之安装与测试》 《RabbitMq基础教程之基本概念》 I. 前提准备 在开始之前,先
一灰灰blog
2018/06/04
6250
【SpringBoot WEB 系列】AsyncRestTemplate 之异步非阻塞网络请求介绍篇
AsyncRestTemplate 发起异步网络请求,由 Spring4.0 引入,但是在 5.0 就被表上了删除注解,官方推荐使用基于 React 的 WebClient 来代替。
一灰灰blog
2020/07/07
6.3K0
【SpringBoot WEB 系列】AsyncRestTemplate 之异步非阻塞网络请求介绍篇
推荐阅读
相关推荐
QuickTask动态脚本支持框架整体介绍篇
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档