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

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

相关博文:

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

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

I. 框架使用姿势

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

1. 独立jar包运行

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

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依赖

<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方法的参数为动态脚本的目录

new ScriptExecuteEngine().run("/tmp/script");

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

@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如下

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缓存的数据,如何在项目运行中判断缓存中的数据是否有问题呢?

一个查看内存的伪代码

class DemoScript implements ITask {
@Override
void run() {
// 获取目标对象
xxxBean = ApplicationContextHolder.getBean(xxx.class);
xxxBean.getXXX();
}
}

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

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

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

2. 接口调用

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

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. 定时任务

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

一个简单的伪代码如下

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的消费任务,对应的伪代码如下

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. 扫描关注

180719-Quick-Task 动态脚本支持框架之使用介绍篇的更多相关文章

  1. 180723-Quick-Task 动态脚本支持框架之结构设计篇

    文章链接:https://liuyueyi.github.io/hexblog/2018/07/23/180723-Quick-Task-动态脚本支持框架之结构设计篇/ Quick-Task 动态脚本 ...

  2. 180729-Quick-Task 动态脚本支持框架之任务动态加载

    Quick-Task 动态脚本支持框架之任务动态加载 前面几篇博文分别介绍了整个项目的基本架构,使用说明,以及整体框架的设计与实现初稿,接下来则进入更细节的实现篇,将整个工程中核心实现捞出来,从为什么 ...

  3. 180807-Quick-Task 动态脚本支持框架之Groovy脚本加载执行

    Quick-Task 动态脚本支持框架之Groovy脚本加载执行 上一篇简答说了如何判断有任务动态添加.删除或更新,归于一点就是监听文件的变化,判断目录下的Groovy文件是否有新增删除和改变,从而判 ...

  4. 【ABP框架系列学习】介绍篇(1)

      0.引言 该系列博文主要在[官方文档]及[tkbSimplest]ABP框架理论研究系列博文的基础上进行总结的,或许大家会质问,别人都已经翻译过了,这不是多此一举吗?原因如下: 1.[tkbSim ...

  5. 【前端基础】动态脚本与JSONP

    博主入职两个月了,越来越感受到打好基础对于前端工程师的重要性,在向着狂拽酷炫的框架&构建工具高速狂奔之前,必须有一个坚实的基础打底,才不至于轻易翻车.所以博主最近一直在恶补<JS高级程序 ...

  6. 携程Android App的插件化和动态加载框架

    携程Android App的插件化和动态加载框架已上线半年,经历了初期的探索和持续的打磨优化,新框架和工程配置经受住了生产实践的考验.本文将详细介绍Android平台插件式开发和动态加载技术的原理和实 ...

  7. atitit.bsh BeanShell 的动态脚本使用java

    atitit.bsh BeanShell 的动态脚本使用java 1.1. BeanShell是一个小巧免费的JAVA源码解释器 ,支持对象式的脚本语言特性,亦可嵌入到JAVA源代码中. 亦可嵌入到J ...

  8. JVM中的动态语言支持简介

    抽丝剥茧 细说架构那些事——[优锐课] 从版本6开始,JVM已扩展为支持现代动态语言(也称为脚本语言).Java8的发行为这一领域提供了更多动力.感到这种支持的必要性是因为Java作为一种语言固有地是 ...

  9. AICompiler动态shape编译框架

    AICompiler动态shape编译框架 移动互联网的兴起,不仅产生了海量数据,也对人机交互有了新的定义.企业如何动态处理不同规格图片数据,如何更灵活处理不同长度的对话语料等等,提升企业运营效率,争 ...

随机推荐

  1. map详解<一>

    首先了解下pair工具类: 这个类在头文件<utility>,功能:将俩个类型可能不一样的值组合在一起.,通过first和second来访问这两个值.还定义了operator == 和op ...

  2. Angular动态表单生成(一)

    好久不写博客了,手都生了,趁着最近老大让我研究动态表单生成的时机,撸一发博客~~ 开源项目比较 老大丢给我了两个比较不错的开源的动态表单生成工具,这两个项目在github上的star数量基本持平: h ...

  3. vue04-动画、组件

    一.vue中使用动画 文档:https://cn.vuejs.org/v2/guide/transitions.html 1. Vue 中的过渡动画 <!DOCTYPE html> < ...

  4. G1 GC日志:Application time: 0.8766273 seconds

    启动日志一直循环: 1.159: Application time: 0.8766273 seconds 1.160: Total time for which application threads ...

  5. SpringBoot 动态打包

    配置pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...

  6. java 网站源码 六套模版 兼容手机平板PC freemaker 静态引擎 在线编辑模版

    官网 http://www.fhadmin.org/ 系统介绍: 1.网站后台采用主流的 SSM 框架 jsp JSTL,网站后台采用freemaker静态化模版引擎生成html 2.因为是生成的ht ...

  7. HP-Socket国产优秀socket通信组件推荐

    来源:http://blog.csdn.net/clb929/article/details/51085983 * HP-Socket 官方网站:http://www.jessma.org * HP- ...

  8. mariadb或者mysql查看某个库相关的用户授权信息

    mariadb或者mysql查看某个库相关的授权信息 SELECT * FROM mysql.Db WHERE Db='DB_NAME';

  9. mkdir 的详细使用说明

    mkdir 是make directory [dɪˈrɛktəri, daɪ-]的缩写,directory--目录的意思 mkdir在linux中是指新建文件目录 例如:mkdir test3 如果要 ...

  10. 基于visual studio 2017 以及cubemx 搭建stm32的开发环境(1)

    参考如下文档: 传送门:http://www.stm32cube.com/article/128 如果链接不存在的话,下载我截屏好的图: 传送门:https://pan.baidu.com/s/1NC ...