文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

基于Java的同步异步统一处理框架

2023-06-02 19:00

关注
DActor框架可同时支持同步和异步代码,简化在线异步代码的开发,用同步代码的思维来开发异步代码,兼顾异步代码的高并发、无阻塞和同步代码的易读性,可维护性。基于协程思想设计最大程度的降低阻塞,提高单个线程的处理能力,并可有效的降低线程数。GitHub:https://github.com/allon2/dactor   GitEE:https://gitee.com/handyun/dactor  目前开发过程中的几个常见模型同步编程    所有步骤都在一个主线程中完成,调用一个方法,等待其响应返回。一个请求占用一个线程,在有数据库操作、TCP和Http通讯时因为有阻塞情况,会导致占用线程占用而无法及时释放      ,因此在同步交易中引入了线程池概念,提高系统的吞吐量异步编程    所有步骤都可在不同线程中完成,调用一个方法,不等待响应既返回,典型交易如NodeJs。    目前市面上的异步框架都比较复杂,市面的通用解决方案是CallBack和Promise/Deferred模式模式。  为了保留异步的高性能,简化异步的开发模式,同时使得程序更容易被程序员理解,在性能和代码可阅读性中间取得平衡,设计了此框架。    处理步骤:将请求封装为消息,丢入消息队列,寻找合适步骤处理消息,上述过程不断循环,直到所有可用步骤都执行完毕。    因为是对消息队列进行处理,对于同步交易,处理完毕即可丢入消息队列。对于异步交易,等待回调完毕再丢入消息队列。    两种情况对于框架来说是无差别的。同时因为通过异步交易避免了阻塞情况的发生,所以可在不大幅度提高线程数的情况下,提高吞吐量,    同时也可在一定程度避免流量突增的情况发生。  消息队列采用Disruptor的的高性能队列RingBuffer。以Actor协程并发模型为基础设计框架。 1、集成Netty2、集成HttpClient3、集成HttpServlet4、支持多层父子结构5、支持责任链模式  6、J2EE支持json,csv,pdf,xml,html格式输出7、J2EE支持数据流输出,动态文件下载、动态图片输出、跳转和可根据配置动态输出 环境要求    JDK 1.8    Spring FrameWork 4.3.22.RELEASE +    Servlet 3.0+(因为需要使用Servlet的异步功能)   注意事项    请求的完整逻辑是分散在不同的线程中执行的,所以尽量避免使用ThreadLocal1.0.7版本       修正Step中所有条件不为真时,报错问题  1.0.6版本       通过设置async=true的方式,便捷的增加旁路交易       移除对javax.mail-api的依赖  1.0.5版本       ServletMessage的用户对象直接从会话中取得   1.0.4版本       优化程序逻辑   1.0.3版本      Message增加setUser和getUser对象   1.0.2版本初始化版本example是J2EE程序,下载后,可直接运行,其中集成了若干例子      默认使用.do提交相关交易,但如果是.json将会返回json数据   启动后,在浏览器中输入http://localhost:8080/example/randomTxt2.json     输出的是json格式的字符串     randomTxt2:只有一级父子关系     randomTxt1:有二级父子关系    chaintest1:只使用责任链     chaintest2:同时使用责任链和一级父子关系     exceptionTest:子交易抛出错误,框架对错误的处理     httptest演示的是通过httpclient异步方式访问百度网站           访问URL:http://localhost:8080/example/ httptest.do       http://localhost:8080/example/np.randomTxt2.json为使用命名空间的例子,相关配置在conf/namespace.xml中。     启动后,可在控制台看到内部调用结果        执行过程为chain->grandfather->parent->Selft。依次调用执行责任链中逻辑,grandfather中的逻辑,parent的逻辑和自身逻辑。chain,grandfather,parent都可为空,不设置在grandfather和parent中的Steps中至少有一个为placeholderActor交易,以调用子逻辑整个过程中,需要先设置全局占位符      <actor:global id="actorglobal">             <actor:param name="beginBeanId" value="beginActor"/>             <actor:param name="endBeanId" value="endActor"/>         </actor:global>  交易中如果未填写beginBeanId或者endBeanId时,系统默认使用全局中配置的beginBeanId或者endBeanId  condtion可为空,空字符串,或者是ognl表达式  placeholderActor的作用是在暂存当前环境,并调用子交易,待子交易执行完毕后,再恢复当前环境继续执行  如果在Step中未找到toBeanIdActor,会直接调用endBeanId方法,认为自身交易已执行结束。  交易的请求和流转信息都保存在Message中  如果指定handleException=false或者使用默认设置,直接返回父中执行,如果父中也未捕获,则继续返回上一级执行,    一般来说至少有要有一个actor中指定handleException=true<bean id="MessageRingBufferDispatcher" class="cn.ymotel.dactor.core.disruptor.MessageRingBufferDispatcher"></bean>启动框架接收和执行请求通过在xml中的Step实现内部Actor之间的流程跳转 在配置文件中包含 Actor、chain、和global配置 。 程序整个执行顺序为根据交易码找到对应的Actor,然后执行按照chain->parent->selft的顺序进行执行。   chain执行到placeholder处,调用parent交易继续执行,在parent交易中执行到placeholder交易后,调用selft自身交易继续执行。 自身交易执行完毕,弹出parent的placeholder处交易继续执行.parent执行完毕,弹出chain中代码继续执行。 global配置如下beginBeanId为默认的开始Actor,value中的值是在Spring中对应的beanName,程序初始化时将会取得此值,对未指定beginBeanId或者endBeanId的Actor初始化全局配置。  beginActor和endActor都需要继承Actor接口。actor配置如下属性handleException如果不设置的话,遇到异常,程序将会认为子类中已经执行完毕,跳到parent中PlaceHolder处执行。设置为true,将不会直接跳转到parent中,由子类进行自我处理。   parent和chain为调用具体交易前需要调用的公共交易,由于大部分交易都有通用的前置交易和统一的后置交易。通过设置parent或者chain,可提高代码复用度。   fromBeanId和toBeanId配置的是Actor或者实现Actor接口的beanId。 parent和chain中的ref都需要是Actor.   results中可定义返回的state和需要处理的viewActor   async标记是否是旁路交易,默认值为false,为true值时,会将上下文内容设置复制一份,重新生成一份Message,进行执行,不影响主流程。chain配置chain可直观展现Actor调用顺序.    在chain中可顺序并列多个parent类。每个parent中的Step都需要有placeHolderActor,以调用子类。      依次执行list中的交易,再执行自身交易。自身交易执行完毕,再依次回溯责任链中的每个交易,直到无可用交易。 命名空间在actor中可增加命名空间,简化代码开发。在actor中配置namespace=np,则实例中的actor的id会自动拼装为np.randomTxt2       http://localhost:8080/example/np.randomTxt2.json为使用命名空间的例子,相关配置在conf/namespace.xml中。  cn.ymotel.dactor.core.MessageDispatcher是交易流转的核心接口类       public void startMessage(Message message, ActorTransactionCfg actorcfg, boolean blocked) throws Exception  方法,用于开始整个流程,其中message需要在执行前进行构造,actorcfg可通过spring的getBean方法得到为Actor对象,如下  sendMessage方法内部调用,用于将处理完毕的Message重新放入队列,继续下一步流程。 cn.ymotel.dactor.core.disruptor.MessageRingBufferDispatcher是MessageDispatcher的接口实现类。,在启动Spring是需要在配置中加上MessageRingBufferDispatcher的strategy、bufferSize、threadNumber为三个可设置属性.正常情况下使用默认设置即可。   strategy默认使用ringBuffer的BlockingWaitStrategy策略进行调度,如果交易量比较大,可调整此策略。   bufferSize默认使用1024。    threadNumber默认使用CPU个数的线程数。    cn.ymotel.dactor.message.Message.Actor,所有需要在执行的交易都必须继承此接口。    public Object HandleMessage(Message message) throws Exception;程序通过调用HandleMessage对象,如果返回的不是message对象或者为NULL,则认为此交易是异步执行,不再自行调度。由异步交易在收到请求后,自己调用将Message再此放入队列中。   cn.ymotel.dactor.action.PlaceholderActor 交易为特殊交易,用来将当前队列暂存,并调用子交易。   cn.ymotel.dactor.action.BeginActor 为Actor中step的默认开始交易。   cn.ymotel.dactor.action.EndActor 为Actor中step的默认结束交易。 cn.ymotel.dactor.action.JsonViewResolverActor为需要返回Json的J2EE view  cn.ymotel.dactor.action.ViewResolveActor为需要返回J2EE view的统一处理Actor    cn.ymotel.dactor.action.httpclient.HttpClientActor 提供的异步调用httpClient的Actor  cn.ymotel.dactor.action.netty.aysnsocket.TcpClientActor 提供的异步调用netty的Actor  以上交易的交易流程图如下以上的完整例子都可在example中得到
阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯