Pipe Comet

PipeComet是一个基于Jetty Continuation的代码框架,旨在解决开放平台的问题。它支持四种业务场景,包括普通管道模式、异步模式、并行模式和条件模式,通过事件驱动模型降低对外部系统的依赖,提高资源利用率。本文详细介绍了设计细节、组件(LazyParser、PipeManager、Event Keeper和Virtual ThreadPool)以及压测场景,强调了线程资源的有效管理和异步处理的重要性。
摘要由CSDN通过智能技术生成

Authorfangweng (文初)

Emailfangweng@taobao.com

Blog: http://blog.csdn.net/cenwenchu79/

Mblog: http://weibo.com/fangweng

 

 

概述

         PipeComet 是在解决开放平台一系列问题的过程中不断演化的基于Jetty ContinuationServlet 3容器也适用)的代码框架。先看看下面一张图中四个场景的演变:

 

 

 

1.  Servlet 3以前,一次http请求就由一个容器线程完成全部处理,容器线程的生命周期取决于整个业务处理的时间(如果后端有依赖系统,例如DB,集中式缓存,外部系统service),由此可见,并发处理请求的数量在容器线程池有限的条件下,直接用容器线程数量/rt(响应时间)即可得到。而容器线程是否真的需要有那么久的生命周期?在整个事务处理过程中是否可以被回收,等到需要时在申请?

2.  第一部分描述中,最根本的原因就是一次http请求的资源及它的生命周期完全交由容器管理,并且和容器线程一对一绑定。如果可以将请求资源和其状态与处理线程分开,生命周期不完全由容器管理,那么问题就可以得到解决。因此有了类似于Servlet3Jetty Continuation的模式(和DB的非Auto commit很类似),期间可以引入外部线程池来接管后端业务处理,而让前端容器线程池生命周期缩短,更专注于处理连接请求和简单的请求预处理。此时可以看到,其实是将业务处理线程池与容器线程池分离,而业务线程池中可以有更灵活和轻量的处理方式。

3.  第二部分中做到的是将业务处理的线程池后移,但并没有从更本上解决本系统如何不受制于后端依赖系统的稳定性及处理能力的高低的约束。因此需要引入事件驱动模型,真正的将多种异步模式引入来解决各种场景的处理,直接或者间接的降低系统资源消耗。事件驱动模型更加彻底的将状态外移,让线程资源生命周期按需申请,大大提高了本系统的资源利用率,降低对外部系统的依赖。带来的负面效应就是逻辑复杂,容错处理要求高,响应时间变慢。

4.  最后引入了虚拟线程池,用于在多种任务执行时共享资源,同时也通过规则设置保证在竞争的情况优先级高并且重要的任务可以优先获得资源。这样也使得业务线程池有更大的业务定制化能力在其中。

 

 

 

下图其实是从四个角度说明了TOP的问题如何被解决,同时也简单了描述了三个组件一个模型的作用:

 

                                                                                   

 

 

 

         每一个特性上面的黄色小框框除了Condition mode不是组件,其他都是组件,后面具体的会谈到,几个点上都有他们各自的优势,其实也就解决了TOP的基本问题,接下去就仔细的谈谈这些设计点的细节和特性。

设计与实现的细节

         首先还是要提前说明一下,参看前面的解决问题的目标,这个框架绝对不是提高并发和降低处理时间的“良药”,解耦带来的负面效果就是系统复杂度增加,响应时间可能会加长,优势在于系统之间的依赖减弱,自身的处理能力决定因素自封闭(瓶颈可以直接根据自身业务处理资源消耗情况估计出来)。

 

四种场景

整个PipeComet框架主要支持下面四种业务场景:

 

                                        

 

 

1.  第一种模式就是最普通的Pipe管道链模式,用管道化切割原本串行的业务逻辑,目标就是让开发者能够最小单元模块化业务逻辑,便于逻辑隔离,为服务降级,Beta发布等打好基础。(最挫的就是代码只有一个pipe,一大坨揉在了一起)

2.  第二种模式就是将业务线程池和容器线程池切割开来,但业务线程池的线程将会负责将后续业务阻塞式的处理完。(也许有人会说,为什么不搞成全异步模式呢,后端也通过事件回调模式来完成,这样当前业务线程池线程也可以被释放,其实这种做法在4中会说明,同时2的存在也因为很多时候后端无法做到异步化,那么往往需要采用半异步的模式,效果在于业务线程池可以做更灵活的控制,特别是加入了虚拟隔离线程池)

3.  第三种模式中,容器线程负责将主流程逻辑执行完毕,而并行管道将会被业务线程并行执行,执行过程中支持部分结果回写给客户端,实现并行处理的目的。容器将在最后一个业务线程处理完毕后关闭请求管道。

4.  第四种模式为纯粹事件驱动模式,某一个管道可以设置为条件激发的管道,此管道可以被外部事件激发(一次或者多次),最后交由外部提交结束事件的请求,结束整个请求处理。(事件如果被激发和执行一次,就是用于后端依赖系统也使可以支持异步化的场景,事件如果被激发多次执行,那么就适用于实现类似于Comet长连接Push推送结果的场景,也可以称作类RSS的数据订阅推送的长连模式)

 

接下来看看提到的四种场景的具体流程交互图:

1.  Common Request(Pipe Mode)

 

                                                                           

 

 

补充:PipeManager负责管道的注册管理和执行,pipe之间相互隔离(互不知道对方存在),pipe之间通过context来交互数据,同时也可以根据上一个管道执行的结果判断是否需要跳过执行当前管道的业务逻辑。总的来说,Pipe化的目的就是为了从框架结构上要求开发者细粒度切割串行的业务逻辑,同时做好逻辑隔离,便于维护和控制。

 

2.  Asyn Request

 

                                                                              

 

补充说明:这种模式下会发现与前面最大的差异就是当执行到asyn类型的pipe以后,后续的管道将会交由业务线程池去执行,于此同时容器线程就被回收(生命周期缩短),业务线程池执行结束后,主动将结果回刷给客户端,并且提示框架结束请求会话,释放资源。

 

3.  Parallel Request

 

                                                                              

 

补充说明:第三种模式与第一种差别在于,首先容器线程将会负责主干pipe的执行,而分支pipe将会交给业务线程池并行执行,主干执行结果和分支执行结果都会回写给客户端,当框架发现主干和所有的分支线程任务都执行完毕后,则主动关闭连接,释放资源。

 

4.  Condition Request

 

 

                                                                                        

 

         补充说明:Condition类型的管道,最大特点就是完全由外部事件激发管道的重复执行或者继续执行,使得传统意义上的无状态阻塞式Http请求可以转变成为较长时效性,数据可不定时回复的模式,适用于消息订阅和接收的逆向设计。(这里的逆向指的是接收端和发送端角色的设置)。

 

         上面四个场景,如果从Http请求响应上来看,有这么一种转变:即时性要求很高à即时性要求一般à即时性要求很低。从系统对后端服务提供者依赖来看,转变为:强依赖à较强依赖à弱依赖。其实最终在设计角度上来看,还是在系统的可用性和效率上寻找折中和权衡,不同场景的需求不同,是否适用取决于当前系统的瓶颈及风险可承受点的差别上。

 

 

 

四个组件

         上面流程中已经反复提到了几个起到关键作用的组件,下面就逐一的介绍这些组件的设计和实现:

 

                                                                                      

                                                                                         

                                            

 

 

         四部分组件有前后关系,同时也会相互串联,实现整体协同。

Container Patch暂时分成3部分:Lazy Parser(通过解析请求字节流来按需解析参数,节省错误请求所带来的无谓资源解析消耗),NIO Connector(当前Jetty是采用模拟阻塞模式使用非阻塞套接字处理的,在性能上还有提升空间),Request&Response Wrapper是为了支持多线程并发操作RequestResponse而作的WrapperContainer Patch是处理流程中最早使用到,且比较底层的组件。(当前Lazy Parser已经正式适用,NIO Connector的优化尚未做,Wrapper做了最简单的处理)

PipeManager是管道框架的核心管理者,它所控制的对象即为PipePipe是无状态的,每一个请求执行时Pipe会被传入PipeInput(包含了request,response),PipeResultPipeContext,同时PipeContext通过ThreadLocal可以在管道之间交互信息。从原数据角度讲,Pipe体系框架中最重要的就是Pipe的三个要素:PipeInput,PipeResult,PipeContext

EventKeeper是事件驱动模型的简单实现,在管道框架之后被使用,承担着管道化体系的多种异步模式事件支持,同时也可以独立成为一个事件驱动模型,内部主要处理event,其中由于和管道框架结合比较紧密,因此event中包含了pipe data和需要外部线程执行的tasks

JobDispatcher

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值