Author:文初
Email:wenchu.cenwc@alibaba-inc.com
Blog:http://blog.csdn.net/cenwenchu79
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ?>
问题凸现:
年关到了,商家忙着促销,网站忙着推广,阿里软件的服务集成平台也面临第一次多方大规模的压力考验,根据5.3版本的压力测试结果,估算了一下现有的推广会带来的压力,基本上确定了服务集成平台年底不需要扩容。SA为了保险起见还是通过请求方式来做定时的心跳检测,保证服务集成平台的可靠性。结果旺旺推广开始的第一天,SA的报警短信就在几个忙时段不停的发告警,但是察看生产环境的服务器状况以及应用状况也看不出有什么问题,开始怀疑是否告警机制不是很合理。但几日的访问记录统计报告看过以后,发现了几个问题,首先由于推广是在IM登录时段集中式的推广,因此高峰期比较集中,压力也很大,而告警发生的也是那些时候,再则,发现那些推广使用的API的处理时间比较长,同时还有一些出现了问题,这几天除了服务集成平台告警以外,那些API服务器也在告警,因此可以看出问题应该是由于API提供商响应速度慢而拖累了服务集成平台的处理能力,监控机制在高峰情况下没有得到及时的响应,就认为是服务器已经处于无效状态。其实这类问题在我们现在的应用体系架构中常常出现,现在很少有纯粹“封闭式”应用,对DB的依赖,对存储的依赖,对第三方系统的依赖等等。这也让我回忆到就是前一阵子参加的安全会议中,腾迅的安全技术团队的负责人说起关于安全现在最大的问题就在于第三方合作安全的不受控而引发安全潜在影响。Web应用未尝不是,从最基本的事务处理要小粒度,不要包含第三方依赖到事务中,到心跳检测,容错方案的制定,都已经让我们对这方面的问题有所注意。但是往往这类问题不是局部设计可以看到的,如果没有一个总体架构设计者对于全局的把握以及协调和防范,那么问题出现并且带来的影响将会很大。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" ?>
早先对于服务集成平台的压力测试主要是在ISP服务“基本正常”的情况下做的,但是这次问题的暴露就要求我们对于这种第三方依赖出现边界问题需要做出一些措施或者改进的设计。
问题分析以及解决方案:
问题原因:
1. Http请求处理的阻塞方式。
2. 后端服务处理时间过长,服务质量不稳定。
3. Web Container接受请求线程资源有限。
解决方案:
1. 改阻塞方式为非阻塞方式处理请求。
2. 设置后端超时时间,主动断开连接,回收资源。
3. 修改容器配置,增加线程池大小以及等待队列长度。
解决方案一是最难做到的,后面的篇幅讲描述对于这方面技术的探索。
解决方案二比较容易,允许各个ISP设置自己API容许的最大超时时间。
解决方案三Tomcat,JBoss在Connector中有两个参数配置(maxThreads和acceptCount)可以做调整。
第一个方案其实和Jdk1.5支持的NIO就是一种想法,只是我们在Socket中都已经采用了,而在Http请求处理中要依赖于Web Container开发商的实现所以至今还没有被广泛应用,不过在开源社区已经有用Mina实现的Http协议处理的框架,但是现在的Web应用高效的Web请求处理仅仅是很小的一方面,还有很多类似于安全,缓存,监控等等附加功能也占据着很重要的地位。
Servlet 3规范经过快一年的推广,已经被各大Web Container厂商所接受,Tomcat6、JBoss5、Jetty7都宣称自己对Servlet3作了较好的支持,而在Servlet3中最广为关注的一个特性就是异步服务处理Servlet(Async Servlet),这点也是解决我目前面临问题的最好的手段。
Servlet 3 与服务异步处理:
Servlet 3主要的新特性分成四部分:内嵌式的使用模式,Annotation的支持,Async Servlet的支持,安全提升。内嵌式的使用很早就在Jetty中被实现,也成为Jetty的优势之一,Annotation也只能说是锦上添花的部分,安全暂时没有怎么用到,最关心的还是Async Servlet部分。Async Servlet到底是什么样的概念,这里就大致描述一下在Servlet3规范中的介绍:
1. 支持 Comet(彗星)。最早期Http请求就是无状态的请求和响应,所有的数据一次性在请求后返回给客户端由客户端渲染。后来发展到AJAX,页面的请求和渲染由全局变成了局部。而Comet适合事件驱动的 Web 应用和对交互性和实时性要求很强的应用,通过建立客户端和服务端的长连接通道,在一次请求后可以主动推送服务端数据的变更情况到客户端。长连接建立的策略有两种:Http Streaming和Http Long Polling。前者客户端打开一个单一的与服务器端的 HTTP 持久连接。服务器通过此连接把数据发送过来,客户端增量的处理它们。后者由客户端向服务器端发出请求并打开一个连接。这个连接只有在收到服务器端的数据之后才会关闭。服务器端发送完数据之后,就立即关闭连接。客户端则马上再打开一个新的连接,等待下一次的数据。
2. 支持Suspending a request。通过在ServletRequest中增加suspend,resume,complete将Http请求处理的block模式转变成为not block模式,同时支持对于状态的查询(suspend,resume,timeout)。
3. 请求处理过程中支持事件机制。响应也支持状态查询。
图 异步服务请求基本流程
现实中的异步服务处理:
Tomcat 的异步服务处理
这里使用的是Tomcat 6.0.14版本。在Tomcat中对于异步处理描述在Advanced IO中作了说明,主要分成两部分:Comet的支持和异步输出。
Comet的支持作用分成两部分:请求读数据的非阻塞,响应处理的异步执行。前者可以防止在大流量数据上传时在传输过程中信道空闲等待的资源浪费,后者用于在处理请求时,依赖于第三方或者本身处理比较耗时的情况下,悬挂起请求处理线程,提高请求处理能力,完成处理后异步输出结果。
Servlet不再是原来对于几个标准的Http请求类型的方法实现,而是对于事件响应的处理。Comet定义了4个基础的事件:
1.EventType.BEGIN:客户端建立起连接时激发的事件,可以用于资源初始化。
2.EventType.READ:有数据可以被读入的事件。(熟悉NIO的事件模式应该可以了解)
3.EventType.END:请求处理结束时激发的事件,可以用于资源清理。
4.EventType.ERROR:当请求处理出现问题时激发的事件。(IO异常,超时等)
还有一些子事件类型,例如超时就属于ERROR的子事件类型,可以在事件处理中更加精确的定位事件类型。
必需的配置:在server.xml中配置如下(红色部分):
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
实际代码范例如下:
//CometProcessor接口必需被实现,一旦实现以后,则该Servlet在配置好以后不会再调用service,get,post等方法的实现。
public class SIPCometTomcatServlet extends HttpServlet implements CometProcessor
{
@Override
//事件处理响应方法实现
public void event(CometEvent event) throws IOException, ServletException
{
if (event.getEventType() == CometEvent.EventType.BEGIN)
{
//设置事件超时时间
event.setTimeout(10 * 1000);
//另起线程处理后台工作,异步返回结果,事件响应将不等待后台处理直接返回
new Handler(event.getHttpServletRequest(),event.getHttpServletResponse()).start();
}
else if (event.getEventType() == CometEvent.EventType.ERROR)
{
//结束事件,回收request,response资源
event.close();
}
else if (event.getEventType() == CometEvent.EventType.END)
{
event.close();
}
}
//另起一个线程异步处理请求。
class Handler extends java.lang.Thread
{
private HttpServletResponse response;
private HttpServletRequest request;
public Handler(HttpServletRequest request,HttpServletResponse response)
{
this.response = response;
this.request = request;
}
@Override
分享到:
相关推荐
多线程和异步处理都可以减少程序的阻塞,但多线程依赖于CPU的线程调度,而异步处理则依赖于硬件的DMA(直接内存访问)或其他低级机制,如回调函数。 1.1.1 异步处理的本质 异步处理的硬件基础在于DMA,允许硬件...
在安全方面,由于前端直接处理用户上传的文件,可能存在XSS(跨站脚本攻击)和CSRF(跨站请求伪造)的风险。因此,必须验证文件类型,限制文件大小,并且在接收数据时进行严格的校验和过滤。 总结来说,前端大数据...
在JavaScript中,异步处理广泛应用于Node.js服务器端编程和浏览器端的AJAX请求。使用`setTimeout`、`setInterval`、`fetch`、`async/await`等函数可以实现异步操作。例如,`async/await`语法使得异步代码更接近同步...
SpringMVC是Spring的一个模块,专门用于处理Web请求,它将模型、视图和控制器分离,增强了代码的组织性和可维护性。MyBatis则是一个持久层框架,简化了数据库操作,通过XML或注解的方式将SQL语句与Java代码关联。 1...
- 这个文件名可能代表了一个示例项目,它可能包含了各种Spring MVC注解的实例,用于演示如何使用Spring MVC进行Web开发,包括异步请求的处理和错误管理策略。 总的来说,这个压缩包提供了学习和实践Spring MVC注解...
总结,AJAX异步处理是现代Web开发的重要技术,它使得网页更加动态和交互性强。通过理解其工作原理和应用场景,开发者可以有效地提升网站性能和用户体验。然而,同时要注意解决可能出现的问题,如跨域限制和SEO兼容性...
在本项目中,我们关注的是一个基于HTTPUnit的Web工程实例,它包含了源码和必要的依赖包,能够处理异步数据加载。这个工程是用Java 1.8或更高版本编译并运行的,旨在帮助开发者理解如何在Web应用程序中进行HTTP请求...
在Python Web开发中,异步功能变得越来越重要,因为它们能够提高服务器处理并发请求的能力,进而提升应用程序的响应速度。 异步编程是Python 3.5及更高版本中的一个重要特性,主要通过asyncio库来实现。在Web框架中...
Java Web中的Ajax异步提交方式上传文件是一种常见且高效的用户交互技术,它允许用户在不刷新整个页面的情况下发送数据到服务器并接收响应。本项目利用Maven构建,前端使用jQuery库以及jQuery-form插件,后端则采用...
在实际项目中,可能还需要根据具体需求进行网络请求的优化和扩展,例如添加请求头、处理分页数据、使用协程进行异步处理等。"DemoRequstWebAPI"这个压缩包文件很可能包含了完整的示例代码,可以帮助你更深入地理解并...
Tokio是一个异步运行时,提供了执行异步代码的基础设施,reqwest就依赖于Tokio来实现其异步请求功能。 在使用reqwest发起异步HTTP GET或POST请求之前,需要在项目配置文件Cargo.toml中添加reqwest和Tokio的依赖项。...
异步处理器负责处理异步请求,异步处理队列负责存储异步请求,异步处理结果存储器负责存储异步处理结果。使用Springboot异步处理架构可以实现高吞吐量异步处理,并且可以提高服务器的性能和可扩展性。 技术要点3: ...
在本文中,我们将深入探讨Ajax的异步处理机制、请求处理过程以及相关开发细节。 ### 一、Ajax基础 1. **XMLHttpRequest对象**:Ajax的核心是XMLHttpRequest对象,它创建了一个到服务器的连接,并提供了发送和接收...
异步依赖图 可以遍历异步节点的依赖关系图。 关于 设计用于在Web应用程序中请求相关数据( )。 每个节点都可以包含一个承诺,该承诺可以进行一些异步操作,例如http请求。 Angular和Vue友好。 受启发 安装 npm ...
【标题】基于Python+Django的异步任务...通过学习和实践这个项目,学生不仅可以掌握Python和Django的基本使用,还能了解到Web应用的异步处理、数据库管理、任务调度等高级概念,为将来从事Web开发工作打下坚实的基础。
【Java Web开发异步机制学习】是本次学习资料的核心主题,涵盖了Java在Web开发中实现异步处理的关键技术。在现代Web应用中,为了提供更好的用户体验和更高的服务器性能,异步处理机制变得越来越重要。本资料包将带你...
原生JavaScript发送异步数据请求是Web开发中的基础技能,主要应用于向服务器获取或发送数据,而无需刷新整个页面。这种技术使得用户界面更加友好,提高了用户体验。在没有依赖任何框架的情况下,我们可以使用两种...