摘要:文章鏈接動(dòng)態(tài)腳本支持框架之使用介紹篇?jiǎng)討B(tài)腳本支持框架之使用介紹篇相關(guān)博文動(dòng)態(tài)腳本支持框架整體介紹篇這個(gè)項(xiàng)目主要就是為了解決數(shù)據(jù)訂正和接口驗(yàn)證不方便的場(chǎng)景,設(shè)計(jì)的一個(gè)及其簡(jiǎn)單的動(dòng)態(tài)腳本調(diào)度框架,前面一篇整體介紹篇博文,主要介紹了這是
文章鏈接:https://liuyueyi.github.io/hexblog/2018/07/19/180719-Quick-Task-動(dòng)態(tài)腳本支持框架之使用介紹篇/
Quick-Task 動(dòng)態(tài)腳本支持框架之使用介紹篇相關(guān)博文:
180702-QuickTask動(dòng)態(tài)腳本支持框架整體介紹篇
QuickTask這個(gè)項(xiàng)目主要就是為了解決數(shù)據(jù)訂正和接口驗(yàn)證不方便的場(chǎng)景,設(shè)計(jì)的一個(gè)及其簡(jiǎn)單的動(dòng)態(tài)腳本調(diào)度框架,前面一篇整體介紹篇博文,主要介紹了這是個(gè)什么東西,整體的運(yùn)行原理,以及一些簡(jiǎn)單的使用demo
本篇博文將主要放在應(yīng)用場(chǎng)景的探討上,在實(shí)際的項(xiàng)目環(huán)境中,可以怎么用
I. 框架使用姿勢(shì)支目前來說,有兩種簡(jiǎn)單的使用方式,一是以獨(dú)立的jar包來運(yùn)行,二是集成在已有的項(xiàng)目中運(yùn)行;下面分別給出介紹
1. 獨(dú)立jar包運(yùn)行獨(dú)立jar包下載,首先下載原始工程,然后打出一個(gè)可執(zhí)行的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包執(zhí)行中,傳入的--task參數(shù),這個(gè)就是制定監(jiān)聽動(dòng)態(tài)腳本的目錄,如上面的腳本,表示框架會(huì)自動(dòng)加載 /tmp/script 目錄下的Groovy腳本,并執(zhí)行
當(dāng)腳本發(fā)生變動(dòng)時(shí),同樣會(huì)重新加載更新后的groovy并執(zhí)行,且會(huì)停掉原來的腳本
2. 項(xiàng)目依賴使用作為一個(gè)依賴來使用也是可以的,首先是添加pom依賴
yihui-maven-repo https://raw.githubusercontent.com/liuyueyi/maven-repository/master/repository com.git.hui task-core 0.0.1
然后在自己的代碼中,顯示的調(diào)用下面一行代碼即可,其中run方法的參數(shù)為動(dòng)態(tài)腳本的目錄
new ScriptExecuteEngine().run("/tmp/script");
對(duì)于SpringBoot項(xiàng)目而言,可以在入口Application類的run方法中調(diào)用,一個(gè)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"); } }
對(duì)于傳統(tǒng)的Spring項(xiàng)目而言,可以新建一個(gè)Listener, 監(jiān)聽所有的bean初始化完成之后,開始注冊(cè)任務(wù)引擎,一個(gè)可參考的使用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. 對(duì)比小結(jié)
兩種使用方式,從個(gè)人角度出發(fā),并沒有什么優(yōu)劣之別,主要還是看具體的業(yè)務(wù)場(chǎng)景,當(dāng)希望部署一個(gè)獨(dú)立的任務(wù)腳本支持時(shí),可能獨(dú)立的部署更加的方便,可以在內(nèi)部進(jìn)行資源隔離,減少對(duì)線上生產(chǎn)環(huán)境的影響;
若是單純的把這個(gè)作為一個(gè)檢測(cè)項(xiàng)目運(yùn)行的輔助工具時(shí),如回調(diào)線上的服務(wù)接口,判斷輸出,獲取運(yùn)行項(xiàng)目中的內(nèi)部參數(shù)等,集成在已有的項(xiàng)目中也是比較簡(jiǎn)單的
II. 實(shí)際場(chǎng)景演示使用了這個(gè)框架,到底有什么用處呢?或者說是否有一些適用的經(jīng)典case呢?
1. 數(shù)據(jù)查看這種場(chǎng)景比較常見,但一般配套設(shè)施齊全的公司,也不會(huì)出現(xiàn)這個(gè)問題,我們最常見的查看數(shù)據(jù)有以下幾類
DB數(shù)據(jù)查看
緩存數(shù)據(jù)查看
內(nèi)存數(shù)據(jù)查看
對(duì)于DB查看,一般沒啥問題,要么可以直連查詢要么就是有查詢工具;而緩存數(shù)據(jù)的查詢,主要是我們通過序列化后存入的數(shù)據(jù),直接從緩存中獲取可能并不太友好;對(duì)于運(yùn)行時(shí)內(nèi)存中的數(shù)據(jù),就不太好獲取了,特別是我們使用Guava緩存的數(shù)據(jù),如何在項(xiàng)目運(yùn)行中判斷緩存中的數(shù)據(jù)是否有問題呢?
一個(gè)查看內(nèi)存的偽代碼
class DemoScript implements ITask { @Override void run() { // 獲取目標(biāo)對(duì)象 xxxBean = ApplicationContextHolder.getBean(xxx.class); xxxBean.getXXX(); } }
上面的腳本中,關(guān)鍵就是在于獲取目標(biāo)對(duì)象,拿到目標(biāo)對(duì)象之后,再獲取內(nèi)部的局部變量或者內(nèi)存數(shù)據(jù)就比較簡(jiǎn)單了(不能直接訪問的局部變量可以通過反射獲?。?/p>
所以關(guān)鍵就是獲取目標(biāo)對(duì)象,有下面幾種思路可供參考:
目標(biāo)對(duì)象時(shí)單例或者靜態(tài)類,則可以直接訪問
如果項(xiàng)目運(yùn)行在Spring容器中,且目標(biāo)對(duì)象為Bean,則可以通過 ApplicationContext#getBean 方式獲取
2. 接口調(diào)用在問題復(fù)現(xiàn)的場(chǎng)景下,比較常用了,傳入相同的參數(shù),判斷接口的返回結(jié)果是否ok,用于定位數(shù)據(jù)異常
class DemoScript implements ITask { @Override void run() { // 獲取目標(biāo)對(duì)象 xxxService = ApplicationContextHolder.getBean(xxx.class); req = buildRequest(); result = xxxService.execute(req); log.info("result: {}", result); } }
其實(shí)實(shí)際使用起來和前面沒什么區(qū)別,無非是線獲取到對(duì)應(yīng)的Service,然后執(zhí)行接口,當(dāng)然在Spring的生態(tài)體系中,一個(gè)可展望的點(diǎn)就是支持自動(dòng)注入依賴的bean
3. 定時(shí)任務(wù)首先明確一點(diǎn),在我們的框架中,所有的任務(wù)都是隔離的,獨(dú)立的線程中調(diào)度的,當(dāng)我們希望一個(gè)新的任務(wù)每隔多久執(zhí)行一次,可以怎么做?
一個(gè)簡(jiǎn)單的偽代碼如下
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; } }
注意下上面的實(shí)現(xiàn),在run方法中,有一個(gè)死循環(huán),一直在重復(fù)的調(diào)用 doxxx() 方法,在內(nèi)部通過 Thread.sleep() 來控制頻率
在腳本改變或刪除之后,框架會(huì)回調(diào) interrupt 方法,因此會(huì)將上面的run變量設(shè)置為false,從而結(jié)束死循環(huán)
注意:
對(duì)于定時(shí)任務(wù)而言,后續(xù)會(huì)擴(kuò)展一個(gè)對(duì)應(yīng)ScheduleTask抽象類出來,將循環(huán)和中斷的邏輯封裝一下,對(duì)于使用方而言,只需要寫業(yè)務(wù)邏輯即可,不需要關(guān)心這些重復(fù)的邏輯
4. mq消息消費(fèi)這種更多的是把這個(gè)框架作為一個(gè)調(diào)度來用,我們接收mq的消息,然后在動(dòng)態(tài)腳本中進(jìn)行處理,再傳給第三方(如果集成在自己的項(xiàng)目中時(shí),一個(gè)demo就是可以直接調(diào)用項(xiàng)目中的Dao保存數(shù)據(jù))
一個(gè)RabbitMq的消費(fèi)任務(wù),對(duì)應(yīng)的偽代碼如下
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("/") //創(chuàng)建連接 Connection connection = factory.newConnection(); //創(chuàng)建消息信道 final Channel channel = connection.createChannel(); //消息隊(duì)列 channel.queueDeclare(queue, true, false, false, null); //綁定隊(duì)列到交換機(jī) 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); } } }; // 取消自動(dòng)ack channel.basicConsume(queue, false, consumer); } }
注意:
對(duì)于RabbitMQ的任務(wù),后續(xù)計(jì)劃封裝一個(gè)抽象的任務(wù)腳本,使業(yè)務(wù)方只需要關(guān)注自己的消息處理即可,上面只是一個(gè)業(yè)務(wù)場(chǎng)景的使用演示
III. 其他 0. 相關(guān)博文:
180628-動(dòng)態(tài)任務(wù)執(zhí)行框架想法篇
180702-QuickTask動(dòng)態(tài)腳本支持框架整體介紹篇
項(xiàng)目:
https://github.com/liuyueyi/quick-task
1. 一灰灰Blog: https://liuyueyi.github.io/he...一灰灰的個(gè)人博客,記錄所有學(xué)習(xí)和工作中的博文,歡迎大家前去逛逛
2. 聲明盡信書則不如,已上內(nèi)容,純屬一家之言,因個(gè)人能力有限,難免有疏漏和錯(cuò)誤之處,如發(fā)現(xiàn)bug或者有更好的建議,歡迎批評(píng)指正,不吝感激
微博地址: 小灰灰Blog
QQ: 一灰灰/3302797840
3. 掃描關(guān)注文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/71667.html
摘要:動(dòng)態(tài)腳本支持框架之任務(wù)動(dòng)態(tài)加載前面幾篇博文分別介紹了整個(gè)項(xiàng)目的基本架構(gòu),使用說明,以及整體框架的設(shè)計(jì)與實(shí)現(xiàn)初稿,接下來則進(jìn)入更細(xì)節(jié)的實(shí)現(xiàn)篇,將整個(gè)工程中核心實(shí)現(xiàn)撈出來,從為什么這么設(shè)計(jì)到最終的實(shí)現(xiàn)給予說明相關(guān)系列博文動(dòng)態(tài)腳本支持框架整體 showImg(https://segmentfault.com/img/remote/1460000015806174); Quick-Task 動(dòng)...
摘要:動(dòng)態(tài)腳本支持框架之結(jié)構(gòu)設(shè)計(jì)篇相關(guān)博文動(dòng)態(tài)腳本支持框架整體介紹篇?jiǎng)討B(tài)腳本支持框架之使用介紹篇前面兩篇博文,主要是整體介紹和如何使用接下來開始進(jìn)入正題,逐步剖析,這個(gè)項(xiàng)目是怎么一步一步搭建起來的本篇博文則主要介紹基本骨架的設(shè)計(jì),圍繞項(xiàng)目 showImg(https://segmentfault.com/img/remote/1460000015739044); Quick-Task 動(dòng)態(tài)腳...
摘要:動(dòng)態(tài)腳本支持框架之腳本加載執(zhí)行上一篇簡(jiǎn)答說了如何判斷有任務(wù)動(dòng)態(tài)添加刪除或更新,歸于一點(diǎn)就是監(jiān)聽文件的變化,判斷目錄下的文件是否有新增刪除和改變,從而判定是否有任務(wù)的變更接下來的問題就比較明顯了,當(dāng)任務(wù)變更之后,就需要重新加載任務(wù)了,即如何 showImg(https://segmentfault.com/img/remote/1460000015923148); Quick-Task ...
摘要:軟件測(cè)試江湖二神兵利器篇在上一篇文章中我們介紹了江湖上流傳的各種軟件測(cè)試的武功秘籍和心法,相信看過的小伙伴內(nèi)力得到了很大的提升。功能測(cè)試篇功能測(cè)試,是軟件測(cè)試?yán)锏娜腴T級(jí)心法,自然也有與之相對(duì)應(yīng)的兵器來發(fā)揮心法的最大功力。 軟件測(cè)試江湖(二)神兵利器篇 在上一篇文章中我們介紹了江湖上流傳的各種軟件測(cè)試的武功秘籍和心法,相信看過的小伙伴內(nèi)力得到了很大的提升。如果沒有,一定是你看的姿勢(shì)不對(duì),...
閱讀 1472·2021-09-30 09:57
閱讀 1480·2021-09-09 09:33
閱讀 2247·2021-09-04 16:40
閱讀 1812·2021-09-01 10:50
閱讀 3258·2021-09-01 10:31
閱讀 2550·2019-08-30 15:56
閱讀 2981·2019-08-30 15:44
閱讀 3485·2019-08-29 17:29