摘要
现在已经有不少文章在谈论各种版本的 Data Services,然而却没人能说清楚该如何从这些 Data Services 中进行选择,同时也没人对端点(end point)和管道(channel)是如何影响着应用性能这个议题进行过详细论述。
尽管 Adobe 提到 4 个不同版本的 Data Services,但实际上只有 2 个主要版本。一个是开源的 Blaze Data Services,另一个是名为 LiveCycle Data Services(LCDS)的私有版本。这两个产品都提供了一个重要特性:借助于 Message Broker Servlet 连接 Flex 和 Java。他们都可以通过二进制协议,ActionScript 消息格式(AMF)使用远程过程调用和消息与服务器端进行通 信。此外,Adobe 还在这两个核心产品之上提供了支持版本和更具扩展性的产品套件。
从我在 Gorilla Logic 的工作经历来看,我认为这两个产品之间的主要差异在于支持项与数据管理,而性能和可伸缩性之间的差异则颇具争议。LCDS 为客户端通信提供了额 外的端点和管道。Adobe 宣称这么做的主要好处在于提升了可伸缩性,然而基本的通信方式依然是通过 HTTP 上的 AMF,这样不管服务器端或客户端的配置 如何,其性能没什么差别。
LCDS 提供的另一个特性是数据管理,它通过实时的冲突调节(conflict resolution)实现 Flex 客户端和 Java 服务器端之间的数据同步,同时还提供了数据装配器和适配器以通过 JDBC、Hibernate 或其他 客户化的适配器连接 Data Services 和持久化存储。
那么这 4 个不同版本都是什么呢?
- Blaze Data Services——免费、开源的版本
- LiveCycle Data Services 社区版——Blaze DS 的一个支持版
- LiveCycle Data Service 单 CPU 协议版——商业版的一个免费版本,具有一些额外特性,但只能用在单个 CPU 上
- LiveCycle Data Services——带有支持的商业版的付费版本
同时还有一个 Adobe 称之为 ****LiveCycle Data Services Enterprise Suite的产品套件。它向核心的 Data Services 中添加了额外的产品以通过 PDF Generation、Forms 及 Digital Signatures 等工具提供内容服务和文档输出功能。
理论上来说,我们可以根据以下三点来选择产品。
- 需要支持么?这取决于应用是否需要支持,比如任务关键的应用。
- 需要数据管理服务么?这取决于应用对数据同步和管理服务的需求。
- 需要额外的 LCDS 端点和管道么?根据 Adobe 所述,如果同时有几百个并发连接,那么就需要了,然而这么说还是颇具争议的。服务器能 处理的并发连接数取决于多种因素,比如线程和 I/O 吞吐量等,同时我们还可以通过多个服务器的负载平衡来处理大量的并发连接,就像 Java 应用服务器那 样。
在本文的最后有一张比较图表概览了这 4 个不同版本。
概览不同的端点——Servlet 和 NIO
在 Data Services 中,端点就是服务器监听来自客户端连接的方式。对于 Blaze DS 和 LCDS 来说,标准的端点基于 Servlet,运行在应用服务器上。端点通过 Message Broker Servlet(配置在 web.xml 中)加入到标准的 Servlet 过滤器链中,这样我们就可以将 Blaze DS 和 LCDS 部署到现有的 Java 应用中。与 Java Servlet 端点类似,每个客户端连接都需要服务器上一个单独的线程。
与上面相比,NIO 端点的工作方式就完全不同了。NIO 表示 Java 新的输入 / 输出。NIO 端点会创建一个独立的基于 NIO 的 Socket Server。其优势在于单个线程能管理多个 I/O 流,这样就无需很多线程,同时能处理更多的客户端。
要想使用 NIO,我们面临着如下几个挑战:
- 客户端无法通过客户端代理访问 NIO 端点。
- 连接无法通过标准的 Servlet 链,因为这会打断依赖于 Servlet 的任何一部分系统。比如我们在项目中使用 Servlet 处理文件上传。
- 要想使用 NIO,我们必须利用客户化的认证,因为 Socket Server 运行在与 Servlet 容器不同的进程中。
尽管我们可以通过配置的方式让 NIO 服务器监听 80 端口,但通常它却驻留在其它端口上。这样就给网络配置带来了挑战,我们必须将网络配置成可以接收 新端口上的连接。根据服务器内部网络和各种客户端的不同,这可能会产生问题。不过这个问题还是有可能解决的:使用带有 sticky sessions 的负载平衡器。
然而 Java NIO 的这些优势却是颇具争议的。开发 Java NIO 的目的在于让单个线程处理多个连接,这是通过令单个线程遍历连接池以检查是否需要读取或写入新的数据来实现的。但由于 NIO 是在 2002 年引入的, 那时的 JDK 版本还是 1.4,而现在 JVM 和 Linux 中的线程已经得到了极大的改进,因此 Java 和 Linux 处理大量线程的能力也已经得到了巨大的提 升。
举个例子吧,Linux Kernel 2.6 引入了一个新的线程库,也就是本地的 POSIX Linux 线程库(NPTL)。测试表明,借助于 NPTL 在 IA-32 上只需 2 秒钟 1 就能启动 100,000 个线程,而如果不使用 NPTL 的话,Linux Kernel 需要花费 15 分钟才能启动这么多线程。
更有意思的是 Paul Tyma 等人发布了一篇博文说到 Java NIO 实际上是个劣势 2, 3, 4。凭借一系列基准,Paul 得出了如下一些结论:
- Java NIO 丧失了大约 20% 到 30% 的吞吐量
- 线程上下文切换的代价并不大
- 同步的代价并不大
Paul 根据这些测试得出如下结论:一个连接对应一个线程完全没问题。在使用 JDK 1.6 的情况下,JVM 可以处理 15K 到 30K 的线程数。这意味着 Servlet 端点已经不再局限于几百个线程了,相反,线程数可以更多,甚至 15K 个连 接以上。当然了,实际的限制取决于硬件配置,比如内存、CPU 等等。
概览不同类型的管道
我们可以在基本的网络连接之上使用多种不同类型的管道进行客户端与服务器端的通信。基本远程过程调用使用的是标准 AMF 管道。
另一种通信形式就是消息,这样应用就可以推送来自于服务器端的消息并进行近乎实时的通信。代表性应用就是聊天服务器、拍卖客户端及协作服务。
Data services 处理消息的主要方式就是轮询(polling)。由于 HTTP 上的标准通信并不会一直打开通信管道,这样一个轮询管道就会让客户端请求一 直等待服务器端,直到数据可用为止,其等待时间从几毫秒到几分钟不等。这么做就模拟了从服务器端推送数据的过程。
有两种基本的轮询管道:短轮询与长轮询。其主要区别在于服务器端等到客户端数据变得可用时所需时间的多少。
一种更高级的管道是流式 AMF(streaming AMF)。它会打开到服务器端的 HTTP 连接并让服务器以流的方式在该管道上传输消息(消息的数量没有限制)。这么做就无需客户端轮询了,同时还能使用标 准的网络配置。该方式最接近于实时流。流式 AMF 的挑战在于它使用了 HTTP 1.1 的持续连接,而不同的浏览器对其的实现方式却不同。
最后一种管道就是 RTMP(实时消息协议)管道了,目前只有 LiveCycle DS 对其提供了支持。Adobe 最近宣布将要发布 RTMP 规范,由此我猜想它最终将会得到其他产品的支持。
设计 RTMP 的目的是在双向管道上以流的方式处理大量多媒体和数据。RTMP 的一个主要好处是可以一直打开与客户端的连接,这样就可以推送服务器端的数据了。凭借这一点,RTMP 可用于 Comet 风格的通信和实时的数据推送。
RTMP 有三种形式。一种是基于 TCP 并使用 1935 端口,其底层实现要求在客户端浏览器上初始化连接。由于使用了非标准的端口,这样客户端防火墙经常会阻止其运行。
RTMP 的另两种形式在 HTTP 请求内封装了 RTMP 消息,这样协议就可以穿越防火墙并使用标准的端口。这两种形式分别是 RTMPT(用在标准的 HTTP 上)及 RTMPTS(用在安全的 HTTPS 上)。
在 Flex 中,所有对服务器的调用都是异步执行的,因此这些管道都不会对客户端性能造成任何影响。然而他们却对服务器端性能有一定的影响,尤其是在 同时打开多个客户端连接的情况下更是如此。例如,流式 AMF 会导致服务器端打开大量并发的客户端连接,这也就意味着会产生多个线程。但如前所述,多个线程 的影响微乎其微。
所有的客户端连接都可以配置默认管道和备选管道,如果默认管道失败则可以切换到备选管道上。根据服务器端处理的不同通信类型,我们可以指定不同的管道链。例如,可以指定 RTMP 管道,但如果该连接失败,就回到长轮询管道。
结论
相对于 Blaze DS 来说,LiveCycle DS 的真正优势在于其支持与数据管理,而额外的端点和管道所带来的优势却是颇具争议的。根据我们在 Gorilla Logic 所完成的项目来看,根本无需使用 NIO 端点或是 RTMP。但从技术角度来看,没什么是确定的。我倒是想多点项目经历。
特性比较表
关于作者
Ryan Knight 是 Gorilla Logic 的高级软件架构师,他主要从事 Flex 和 Java 咨询方面的工作,同时还是 Anvil Flex 的主要贡献者,这是一个开源的项目,用来帮助企业上手 Flex 开发。他有着 12 年的 Java 开发经验,期间经历了从开发到咨询的各种角色变迁。
资源
1 http://www.linuxjournal.com/article/6530
2 http://paultyma.blogspot.com/2008/03/writing-java-multithreaded-servers.html
3 http://www.theserverside.com/discussions/thread.tss?thread_id=26700
4 http://cometdaily.com/2008/11/21/are-raining-comets-and-threads/
来自 Adobe 的链接
LiveCycle Data Services ES FAQ
Comparison of the different LiveCycle Data Services solutions
其他资源
LiveCycle ES vs LiveCycle DS vs BlazeDS - clearing up the confusion
Why are you NOT using LiveCycle DS?
查看英文原文: Blaze Data Services or LiveCycle Data Services?
给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。
评论