`
youxinrencwx
  • 浏览: 67481 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Web服务请求异步化介绍(概念篇)

 
阅读更多

Author:放翁(文初)

Date: 2010/6/28

Email:fangweng@taobao.com

围脖: http://t.sina.com.cn/fangweng

前话

在前面的文章中,先给出了Web服务请求异步处理的压力测试报告,从数据角度描述了支持Web请求异步化的容器在不同并发用户下的处理能力及性能消耗。本文从概念的角度对于应用系统异步化,Web服务请求异步化和Web请求异步化规范及实现三方面做一个介绍,为系统异步化改造做好基础准备。(同样,文中大部分都是个人意见和想法,非完全正确,欢迎讨论)

应用系统异步化

Web服务请求异步化也是应用系统异步化的一种,因此首先谈一下对于应用系统异步化的一些看法和认识。

随着系统不断积累和发展,系统模块化是必然趋势,而模块之间的耦合性和依赖会直接影响系统的稳定性和可用性,因此系统异步化概念就产生了。异步化和其他技术一样,不是“万能药”,在适合的场景扬长避短才能够体现它的优势,提升系统的可用性和效率。

异步化要素:

1. 会话。

异步模式下,请求和结果不在一次交互中,因此需要通过会话的设计方式(增加会话码)来保证请求和结果的一一对应。另一种方式可以不需要会话,但是要求请求和结果是保证顺序的。(这种设计方式会使得系统的资源复用受到限制,同时容错很难保证,容易“串”,早先用NIO去实现低版本的Memcached客户端协议就存在没有会话号的问题)

2. Callback or Stateful Result。结果产生如何通知请求方,有两种手段:a. Callback,通过服务方主动推送的方式将结果推送给服务调用者。(如果是进程内,可以通过实现定义的回调接口方式,如果是进程外,可以通过注册URL或者WebService等方式来实现)。b. Stateful Result,是通过调用方不断轮询执行结果,当服务提供者服务处理完毕后,修改Result的状态。优劣不在此赘述。

异步化特点:

1. 系统间可用性和处理能力松耦合。

AàBA系统依赖于B系统)

A的可用性最差情况是sumA系统自身可用性,B系统可用性)。

A系统的处理能力是min(A系统处理能力,B系统处理能力)

作用:差别化系统设计,A系统可能是前端系统要求高处理能力,B系统是后段系统,要求高一致性,此时两个系统如果异步方式依赖,A可以设计的较为轻量化,在高并发下有很好的吞吐量。B系统可以设计的有足够的容错和备份机制,在效率上适当放低要求。(我们时常在设计系统的时候谈CAP原则,不同系统和流程不同阶段对于这三个因素的要求都是不同的,因此通过异步的方式防止由于对于其他系统的依赖导致本系统的CAP无法有效的权衡)

2. 资源的有效利用。

异步模式天生就需要事件驱动模型支持,而事件驱动模型在高并发情况下对资源管理和使用十分有效。NIO设计就是典型的异步模式,基于对信道事件的监听和分发,最大程度上复用信道,复用接收和发送缓存等相关资源,提高资源利用率,增强系统的服务能力。

3. 系统复杂度增加。

错误暴露及时性降低。当B系统出现问题时,A系统知晓情况被动,整个流程问题暴露及时性降低。因此要求B系统和A系统作好更多地容错,异常检查工作。(例如流程超时处理机制等)

4. 整体业务流程处理时间增大。

由于B反馈给A的结果是异步化,因此A就有了上述两种方式去获取结果:PullPushPush就是B主动回调A的服务(及时性较强,不过仍有部分时间消耗),Pull的间隔时间决定了A获得结果可能存在的延时性。

异步化场景:

1. 模块间依赖,系统间依赖。

这里描述的是粒度,异步化最终是对一个流程中的部分环节的弱化:一种就是弱化非关键路径来保证关键路径的可用性和效率。另一种就是弱化整体流程的及时性和一致性,提高部分环节的处理能力和可用性。但不论哪一类弱化都是基于一定的业务粒度,模块应该说是最小的业务粒度,在模块内部设计就要求紧耦合。

2. 资源决定一切

异步的使用场景往往是为了节省资源,但是节省带来的成本就是复杂度,当资源本身就不是问题(并发不高,资源足够)的情况下,无需要选择异步方式来增加复杂度,同时反而降低了可用性和稳定性。

3. 整体观与局部观

AàBA依赖于B,此时采取异步化的方式,A的处理能力得到提高,大量的请求被提交到B上,B由于请求堆积,导致性能下降甚至崩溃,那么其实对于整体处理流程来说并没有随着A处理能力曲线上升而上升,因此此类优化没有协调好局部和整体。

AàB AàCA依赖于BA依赖于C,异步改造AB之间的关系,但是A还是受限于C,那么此类优化未必有效果,同时增加了复杂度。(这里就要关注整体流程的关键路径,关键路径的优化才是有效的优化)

Web服务请求异步化

随着Servlet3.0的日趋成熟和各个Web容器厂商的支持,Web服务请求异步化在很多领域开始慢慢被使用和熟悉。

Web服务请求异步化与NIO的概念是不同的(Web服务请求异步化可以基于BIO的底层交互也可以基于NIO的底层交互),Web服务请求异步化是业务层的异步设计,与普通的应用系统异步化差别在于Web请求有固定的规范,请求流程和接口较为固定,同时请求底层的资源管理交由Web容器处理,因此在第一部分中所谈到的异步的优势劣势,适用场景同样适合Web服务请求的异步化。

这里也顺带谈一下为什么NIOWeb领域里面被没有像后台系统一样被得到广泛使用:

a. 信道复用的投入产出比例。Http请求是无状态的请求应答模式,信道复用概率不像内部后台系统那么高,再加之业务时间占整体流程时间绝对大的比例,那么投入产出不成比例。

b. Web请求受限于Servlet规范的生命周期管理,导致前段无论如何异步,在服务处理过程中都是同步阻塞模式,因此异步不彻底,无法体现NIO的优势。

三种Web请求模型的演进:

1. Thread Per Connection。在BIO的模型下,每次连接都会被分配一个线程,线程负责底层数据接收发送,业务处理。

2. Thread Per Request。在NIO的模型下,将不再为连接单独分配线程,而为每一次请求事件发生创建线程,处理业务,对于底层的数据发送和接收资源做到了共享,同时数据通道得到了共享。

3. Thread Per Service Event。在Web请求异步处理模型下,底层数据处理可以依赖于第二个处理模型,上层业务处理将业务状态对象独立于业务处理流程,通过事件驱动模式来分阶段触发业务各阶段处理,为每一次事件处理创建线程和资源(通常是资源池),最终提高资源利用率。

介绍一下四种场景下的Web请求处理:

角色介绍:(在下面的场景中会涉及到一些角色,有些隶属于容器,有些是外部服务和资源)

:并发用户。T代表有T个并发用户。

Conn Thread Pool :连接线程池,属于Web容器的一部分,作为响应和处理请求的线程资源获取来源。

Conn Thread:线程连接,从线程连接池中获取到的线程。

Service Provider:业务实现者。可以是本系统的业务实现,也可以是其他系统的业务实现,可以是异步方式的返回也可以是同步方式返回结果。(N)代表本身业务处理需要N个时间单位。

Worker Thread Pool:外部工作线程池,可以接收处理“耗时”的业务流程。

1. 非异步化Web请求处理

从这个场景可以看出,在非异步化Web请求的容器中,不论后端服务是否采取异步化,由于请求本身需要在一次阻塞式交互中返回,那么连接线程池中的线程在后端服务异步化的同时依然Hold没有被释放,当前端并发量增加的时候,容器的吞吐量就会成为瓶颈(就算后端服务能力还有很大的剩余)。

Resource表示消耗的资源:在T个并发用户下,需要消耗T个连接线程资源。

Response表示响应处理时间:N个时间单位。

2. 异步化Web请求处理,后端服务提供者为阻塞模式。

这种模式下,增加了一个工作者线程池,在做后端服务处理的时候,工作线程池的线程取代了连接线程池的线程,在工作者线程获得了挂起的异步上下文以后, 释放了连接线程池的线程,当业务执行完毕以后,工作者线程通过异步上下文,提交返回结果,最后释放自身资源。

Resource:少量ConnThread + TWorkThread

ResponseN + workerThead消耗(创建,异步调用等)

可以看到,对于后端没有支持异步化的情况下,仅仅前端容器异步化能够起到效果的前提是:1. WorkThread很轻量化,消耗资源远小于连接池线程资源。2.WorkerThread消耗占整体消耗的很小一部分,甚至可以忽略。此时通过用轻量级线程池替换容器连接线程池可以较好的提高效率和资源利用率。

3. 异步化Web请求处理,后端服务提供者为非阻塞模式。(Push & complete mode

Push & complete mode指的是对于后端服务结果的反馈是Service Provider主动push给服务调用者,在Web请求异步化过程中,返回请求结果是直接通过调用异步上下文的complete事件来触发commite的。(想对于resume的唤醒重入方式)

此场景服务提供者支持异步化处理业务请求,因此连接线程池的线程负责处理最轻量一些操作,然后将业务请求转交给服务提供者,同时将异步上下文传给服务提供者的处理线程,就此连接池连接资源释放。当服务完成后,服务端线程通过异步上下文获取到输出对象,将处理结果直接返回给客户。

Resource:少量Conn Thread

ResponseN个时间单位。

可以看到容器请求异步化结合后端服务体系异步化能够起到最好的效果,但有一点是要注意的,前端线程池在没有异步化以前吞吐量取决于它的线程池大小和后端服务处理速度,而当异步化后,吞吐量取决于它的线程池大小和异步化带来的消耗,明显并发服务能力得到了很大的提升(特别是后端服务耗时严重的时候),这样就意味着会有更多的服务请求流向后端,当后端处理能力无法支撑的时候,那么N那个时间单位就会上升,同时稳定性也会产生问题,因此反而会起副作用,因此这种模式需要评估后端服务能力,保证异步化后服务质量依旧。

4. 异步化Web请求处理,后端服务提供者为非阻塞模式。(Pull & Complete mode

Pull & complete mode指的是对于后端服务结果的反馈是Service Provider被动的等待其他监控线程定时pull结果对象并比对结果状态确定是否完成,在Web请求异步化过程中,返回请求结果是直接通过调用异步上下文的complete事件来触发commite的。(想对于resume的唤醒重入方式)

这个场景和前一个场景差别在于对于结果的获取方式,同样对于后台服务来说,前端系统的业务处理不会侵入到它的业务代码(Push方式会要求Service Provider回调或者直接提交结果到客户端)。这种场景需要增加一个结果队列,连接线程池中的线程责任就是调用后端服务,然后将Future结果和异步上下文作为服务结果放入队列。由一个小的工作者线程池定时检查任务执行情况,当执行通过时,直接取出结果集,将结果通过异步上下文输出到客户端。

Resource:少量的Conn Thread + 部分worker Thread

ResponseN + 异步化消耗的时间(结果轮询消耗的时间)

就系统本身来说,稳定性和可用性有所“折扣”,增加了对于队列和工作者线程的依赖。

5. 异步化Web请求处理,后端服务提供者为非阻塞模式。(Push & resume mode

Push & resume mode指的是对于后端服务结果的反馈是Service Provider主动push给服务调用者,在Web请求异步化过程中,在业务处理结束后,重入当前同样的Servlet中(带上结果),由Servlet在新的请求中返回结果给客户端。(在Servlet3.0中是允许dispatch到不同的Servlet中,这样带来的灵活性就比较高了,在jettycontinuation中只允许重入当前请求的Servlet

重入机制会给容器带来一定的压力,一次请求在容器这边变成了两次或者多次请求,同时对于Servlet中的业务代码需要去关注是否是原始请求还是被模拟的重入的请求,区别化对待。

Resource:部分的Conn Thread

ResponseN + redispatch time

连接线程消耗要比普通的complete来的多,同时消耗时间也比complete模式来的大。

Web请求异步化规范及实现

当前实现Web请求异步化的容器有Jetty6,Jetty7,Tomcat7.其中Jetty6支持他特有的Continuation机制,jetty7支持ContinuationServlet3.0Tomcat7支持Servlet3.0.后面就从Jetty的角度去介绍Continuation机制,再比较ContinuationServlet3.0的差异。

Continuation

Jetty可以使用BIO或者NIO的底层来支持Continuation,不过就效果来说肯定是NIO的效果好,这里给出两个图(JettyNIO的类结构图和Continuation的交互图),从中可以看到这两块设计的实现。

Jetty NIO 类图

Jetty作为外部容器或者嵌入式容器入口都是ServerServer中包含了Connector(这块实现的不同就决定了是用BIO还是NIO的模式,这里描述的是NIO模式,因此ConnectorSelectorChannelConnector),ThreadPool成为整个系统中的线程资源池,用来完成事件驱动模型的各种需求。为了提高性能,NIO模式下的Connector包含多个Selector(即SelectSet)和Acceptor,通过Acceptor循环检测来触发多个Selector检查IO事件,当有请求产生的时候创建SelectChannelEndPoint来分配必要的资源处理请求(与前面描述的Thread Pre Request是一致的,确切的说是One Resource Pre Request)。

Continuation 交互图

图片看不清楚可以去flickr上看(http://www.flickr.com/photos/33194437@N03/4746678724/sizes/l/

1. 用户发起请求。

2. NIOSelector接收到了IO事件创建了Endpoint分配了相应的资源。

3. 同时将Endpoint作为一个任务封装后插入到线程池队列中,等待工作线程执行请求处理。(IO事件处理到此结束)

4. 工作线程池中线程执行请求处理。

5. 先读取请求数据。

同步模式:

6.1 -6.4调用内部的handler串行化处理请求,最后返回处理结果。

异步模式:

7.1 执行Handler的业务逻辑。

7.2 挂起请求,进入异步模式。

7.3 创建异步事件置入到Request中。(一来用于容器后续判断当前请求是否处于同步模式,是否需要提交response,另一方面用于异步事件的超时检测)

7.4 Servlet的原生命周期的方法中(servicedoget,dopost …)创建新的线程去执行业务操作,并且将Continuation传递给线程用于后续complete或者resume来提交业务处理结果或则重新分发进入Servlet

7.5 结束常规的Servlet生命周期。

7.6 容器判断,如果是异步模式,则将异步事件放入到timeoutTasks这个链状超时事件队列中,如果没有启动异步模式,则提交结果,回收请求处理资源。

7.7.1 工作线程执行业务处理。

7.7.2 执行完毕业务处理以后调用Continuationcomplete或者resume方法来提交处理结果。

7.7.3 complete或者resume方法调用将产生事件被放入到了线程池队列中。

7.7.4 执行complete或者resume事件,调用事件宿主Endpoint的分发请求的处理。(可以理解为重新模拟执行了一次服务端的dispatch,也就是重新执行一次handler链,不过中间结果数据已经完全不同)

7.7.5 如果没有complete则重新回到7.7.1

7.7.6 如果complete 则返回结果,回收资源。

7.8.1 Endpoint会循环检查异步事件是否已经超时(查看timeoutTasks)。

7.8.2 如果出现超时,则封装超时事件放入线程池队列等待执行。

7.8.3 线程池执行超时处理,返回结果,回收资源。

Servlet3.0 Continuation的差异

可以说Jetty团队在Servlet3.0没有成为正式规范之前就参考了它的设计理念,因此本质上来说两者没有太大的区别,唯一的几个区别点在于:

1. ContinuationAsynContext分别是两个体系的异步上下文载体。

2. Continuation resume机制没有Servlet3灵活,Servlet3可以支持dispatch到内部任意的Service上。

异步化在客户端

前面一致介绍异步化在服务端的应用,其实在客户端的应用可以提高客户端的连接能力及容错能力(加长Timeout时间也不会导致连接耗尽),Jetty已经支持客户端异步化,使用比较简单。

后话

这些是刚开始,接下来对于应用实际的改造(TOP现有管道化流程的异步化尝试)会找到异步化的优势和软肋。如何用好异步化对于高并发的多模块或者多依赖系统来说是很关键的,是一把双刃剑,需要有足够能力的人去把控,这个人需要的不仅是教条,更多的是经验。

分享到:
评论

相关推荐

    Web服务请求异步化测试

     Web服务异步化: 包括两部分,数据传输层异步化(大家已经熟知的NIO),Http业务请求异步化(continuations,servlet3.0)。服务异步处理我将会有一个详细的说明文档(服务异步化的概念,服务异步化的几种标准实现,...

    aww:Web Workers的异步Iterables接口

    这是概念证明库,可与Web Worker进行异步迭代。 尚不支持错误处理。 npm i -S aww 异步迭代时,请勿使用包装程序的postMessage方法:请使用reply方法。 如何遍历调用者的传入数据(从工作人员角度) worker.js ...

    RUST web框架axum快速入门教程

    3. 基本概念:了解axum中的基本概念,如路由、请求处理、响应处理等。 4. 实现算法:在axum中实现算法是构建web应用的关键。本节将介绍如何在axum中实现常见的算法,如排序、查找等。 5. 难点解析:在实现算法的过程...

    Ajax的基本概念与原理

    用户在浏览网页的时候,无论是打开一段新的评论,还是填写一张调查问卷,都需要反复与服务器进行交互,但是传统的Web应用采用同步交互形式,即用户向服务器发送一个请求,然后Web服务器根据用户的请求执行相应的任务,并...

    使用.NET Remoting从服务器主动发出事件通知客户端远程广播

    的确,初接触.NET Remoting的人多半会有这样的疑问,因为大部分的文章和书籍在介绍.NET Remoting时都只介绍了通道,对象,激活和生存周期等等概念,在谈到如何进行远程通信的时候,都只告诉读者如何从客户端激活一个...

    WebFlux的项目基本案例

    Webflux是一个响应式编程框架,用于构建基于Java的异步非阻塞的Web应用程序。它是Spring Framework 5引入的一个重要组件,并且是基于Reactor库的反应式编程模型。 传统的Web应用程序模型通常使用基于线程的同步I/O...

    web大作业快递管理系统包含快递管理查询和二维码生成功能

    实验内容:设计一个前后端交互 web 系统完成前后端数据交互(用 JSON 格式),必须实现同步、异步(Ajax)提交请求;3) 使用 JDBC(或者其他后端技术)连接数据库,数据库不限,需要使用连接池(或者相似概念),不能...

    python入门到高级全栈工程师培训 第3期 附课件代码

    02 并发并行与同步异步的概念 03 GIL的概念 04 同步锁 05 递归锁 06 同步对象event 07 信号量 08 线程队列 09 生产者消费者模型 10 多进程的调用 第35章 01 进程通信 02 进程池 03 协程 04 事件驱动模型 05 IO模型...

    李兴华Java Web开发实战经典.pdf (高清版) Part1

    MLDN 李兴华 Java Web 开发实战经典.pdf (高清版) 全书分为两部分,需 要全部下载下载一起解压,此部分为第一部分 带有书签,清华大学出版社 第1章 JAVA WEB开发简介 1.1、WEB发展历程 1.2、企业开发架构 ...

    MLDN+李兴华+Java+Web开发实战经典.part3.rar )

    MLDN 李兴华 Java Web 开发实战经典.pdf (高清版) 带有书签,清华大学出版社 第1章 JAVA WEB开发简介 1.1、WEB发展历程 1.2、企业开发架构 1.3、JAVA EE架构 1.4、JAVA EE核心设计模式 1.5、Struts开发...

    李兴华Java Web开发实战经典(高清版) Part2

    MLDN 李兴华 Java Web 开发实战经典.pdf (高清版) 全书分为两部分,需 要全部下载下载一起解压,此部分为第二部分 带有书签,清华大学出版社 第1章 JAVA WEB开发简介 1.1、WEB发展历程 1.2、企业开发架构 ...

    ASP.NET4高级程序设计第4版 带目录PDF 分卷压缩包 part1

    另外,还专门介绍了ASP.NET4 新增的功能,如MVC 和动态数据等。  《ASP.NET 4高级程序设计(第4版)》适合各层次的ASP.NET程序员阅读。 =================== 第一部分 核心概念 第1章 ASP.NET简介 1.1 ASP.NET的...

    Python网络编程(第3版).[美]Brandon Rhodes(带详细书签)

    从应用开发角度介绍网络编程基本概念 模块...具体内容包括:全面介绍Python3中最新提供的SSL支持,异步I/O循环的编写,用Flask框架在Python代码中配置URL,跨站脚本以及跨站请求伪造攻击网站的原理及保护方法,等等。

    2.ASP.NET.2.0.高级编程(第4版) [1/7]

    14.8.1 为本地化构建Web.sitemap文件 502 14.8.2 修改Web.config文件 503 14.8.3 创建程序集资源(.resx)文件 504 14.8.4 测试结果 505 14.9 小结 506 第15章 个性化 507 15.1 个性化模型 507 15.2 创建个性化...

    李兴华 Java Web 开发实战经典_带源码_高清pdf 带书签 上

    第1章 JAVA WEB开发简介 1.1、WEB发展历程 1.2、企业开发架构 1.3、JAVA EE架构 1.4、JAVA EE核心设计模式 1.5、Struts开发框架 1.6、本章摘要 1.7、开发实战讲解 第2章 HTML、JavaScript简介 2.1、服务器...

    Head First Ajax (中文版)+源码

    这本书专门针对你的大脑而制作,涵盖JavaScript、XHTML、异步和同步请求、DOM以及扩展和提升你的Web应用开发能力所需的所有内容。你要做的不只是记住其他人所写框架中的某些方法,也不再只是从某个工具包向应用拖放...

    ChatGPT的使用之学习node爬虫框架Cheerio.pdf

    在教程中,作者首先介绍了Web Scraping的概念和用途,以及Node.js在这方面的优势。接着,作者详细讲解了Cheerio这个爬虫框架的基本用法,包括如何安装和使用Cheerio,如何选择和操作HTML元素,如何处理异步请求等等...

    《RxJava响应式编程》_李衍顺.zip 提取码: 2bsV75

    在开发手机 App、 Web App 时, 要想保证对用户 请求的实时响应,给用户带来流畅的体验,响应式编程是一个不错的选择, RxJava 则是这种编程模式的 Java 实现。本书主要介绍如何使用 RxJava 进行响应式编程 。全书...

    Ajax详解.rar

    第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求 11 1.1 XMLHttpRequest 简介 12 1.2 用 XMLHttpRequest 发送请求 18 1.3 处理服务器响应 22 第 3 部分: Ajax 中的高级请求和响应 28 1.1 深入了解 HTTP 就绪...

    task4

    前面几期全是概念学习爬虫,今天来一篇实战文章。 首先了解ajax加载 ajax加载 一、什么是Ajax Ajax(Asynchronous JavaScript and XML的缩写)是一种异步请求数据的web开发技术,对于改善用户的体验和页面性能很有...

Global site tag (gtag.js) - Google Analytics