Dactor輕量級同步異步統(tǒng)一編程框架
DActor
Introduction
DActor框架可同時支持同步和異步代碼,簡化在線異步代碼的開發(fā),用同步代碼的思維來開發(fā)異步代碼,兼顧異步代碼的高并發(fā)、無阻塞和同步代碼的易讀性,可維護性。 基于協(xié)程思想設(shè)計 最大程度的降低阻塞,提高單個線程的處理能力,并可有效的降低線程數(shù)。
Overview
目前開發(fā)過程中的幾個常見模型
同步編程 所有步驟都在一個主線程中完成,調(diào)用一個方法,等待其響應(yīng)返回。一個請求占用一個線程,在有數(shù)據(jù)庫操作、TCP和Http通訊時因為有阻塞情況,會導(dǎo)致占用線程占用而無法及時釋放
,因此在同步交易中引入了線程池概念,提高系統(tǒng)的吞吐量異步編程 所有步驟都可在不同線程中完成,調(diào)用一個方法,不等待響應(yīng)既返回,典型交易如NodeJs。 目前市面上的異步框架都比較復(fù)雜,市面的通用解決方案是CallBack和Promise/Deferred模式模式。
設(shè)計思路
為了保留異步的高性能,簡化異步的開發(fā)模式,同時使得程序更容易被程序員理解,在性能和代碼可閱讀性中間取得平衡,設(shè)計了此框架。
處理步驟:將請求封裝為消息,丟入消息隊列,尋找合適步驟處理消息,上述過程不斷循環(huán),直到所有可用步驟都執(zhí)行完畢。
因為是對消息隊列進行處理,對于同步交易,處理完畢即可丟入消息隊列。對于異步交易,等待回調(diào)完畢再丟入消息隊列。
兩種情況對于框架來說是無差別的。同時因為通過異步交易避免了阻塞情況的發(fā)生,所以可在不大幅度提高線程數(shù)的情況下,提高吞吐量,
同時也可在一定程度避免流量突增的情況發(fā)生。消息隊列采用Disruptor的的高性能隊列RingBuffer。
以Actor協(xié)程并發(fā)模型為基礎(chǔ)設(shè)計框架。
Features
1、集成Netty
2、集成HttpClient
3、集成HttpServlet
4、支持多層父子結(jié)構(gòu)
5、支持責(zé)任鏈模式
6、J2EE支持json,csv,pdf,xml,html格式輸出
7、J2EE支持?jǐn)?shù)據(jù)流輸出,動態(tài)文件下載、動態(tài)圖片輸出、跳轉(zhuǎn)和可根據(jù)配置動態(tài)輸出
環(huán)境要求
JDK 1.8
Spring FrameWork 4.3.22.RELEASE +
Servlet 3.0+(因為需要使用Servlet的異步功能)
注意事項
請求的完整邏輯是分散在不同的線程中執(zhí)行的,所以盡量避免使用ThreadLocal
Getting Started
example是J2EE程序,下載后,可直接運行,其中集成了若干例子
默認(rèn)使用.do提交相關(guān)交易,但如果是.json將會返回json數(shù)據(jù) 啟動后,在瀏覽器中輸入http://localhost:8080/example/randomTxt2.json
輸出的是json格式的字符串
randomTxt2:只有一級父子關(guān)系
randomTxt1:有二級父子關(guān)系 chaintest1:只使用責(zé)任鏈
chaintest2:同時使用責(zé)任鏈和一級父子關(guān)系
exceptionTest:子交易拋出錯誤,框架對錯誤的處理
httptest演示的是通過httpclient異步方式訪問百度網(wǎng)站
訪問URL:http://localhost:8080/example/ httptest.do
啟動后,可在控制臺看到內(nèi)部調(diào)用結(jié)果
Maven dependency
<dependency> <groupId>cn.ymotel</groupId> <artifactId>dactor</artifactId> <version>1.0.6</version> </dependency>
Gradle dependency
compile group: 'cn.ymotel', name: 'dactor', version:'1.0.6'
代碼簡單講解
執(zhí)行過程為chain->grandfather->parent->Selft。 依次調(diào)用執(zhí)行責(zé)任鏈中邏輯,grandfather中的邏輯,parent的邏輯和自身邏輯。 chain,grandfather,parent都可為空,不設(shè)置 在grandfather和parent中的Steps中至少有一個為placeholderActor交易,以調(diào)用子邏輯
整個過程中,需要先設(shè)置全局占位符
<actor:global id="actorglobal">
<actor:param name="beginBeanId" value="beginActor"/>
<actor:param name="endBeanId" value="endActor"/>
</actor:global>
交易中如果未填寫beginBeanId或者endBeanId時,系統(tǒng)默認(rèn)使用全局中配置的beginBeanId或者endBeanId
<actor id="randomTxt" parent="actorhttpcore" beginBeanId="randomTxtActor"> <steps> <step fromBeanId="randomTxtActor" toBeanId="placeholderActor" conditon=""/> <step fromBeanId="placeholderActor" toBeanId="endActor" conditon=""/> </steps> </actor>
condtion可為空,空字符串,或者是ognl表達式
placeholderActor的作用是在暫存當(dāng)前環(huán)境,并調(diào)用子交易,待子交易執(zhí)行完畢后,再恢復(fù)當(dāng)前環(huán)境繼續(xù)執(zhí)行
如果在Step中未找到toBeanIdActor,會直接調(diào)用endBeanId方法,認(rèn)為自身交易已執(zhí)行結(jié)束。
交易的請求和流轉(zhuǎn)信息都保存在Message中
如果指定handleException=false或者使用默認(rèn)設(shè)置,直接返回父中執(zhí)行,如果父中也未捕獲,則繼續(xù)返回上一級執(zhí)行,一般來說至少有要有一個actor中指定handleException=true 啟動框架接收和執(zhí)行請求
