`
lee79
  • 浏览: 106213 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Middleware remoting protocol migration

阅读更多

At Nominet we have successfully migrated the remoting protocol governing communication between our client applications and the software running in the middleware layer. We have moved from SOAP to Hessian, refactoring the base code on the way. This post explains why we migrated, the advantages of the migration and how we tested different protocols to decide the move.

Starting point

Due to not relevant reasons at the moment, Nominet middleware services were being exposed to client applications internally using Glue, a privative SOAP implementation. Middleware code was quite tied to the use of this library, fact that was not convenient at all because it made difficult to introduce a different protocol.

SOAP protocol is good when you need to expose services in an environment where you do not control the client side and want to provide hight compatibility. SOAP it is also good if you expose small stateless services with fast processing and small amount of data transfer in and out. However, due to the heavy process of XML, SOAP is not appropriate for services which can require a significant amount of information going in and out. Additionally, in an environment where you control server and client code, there are better communication protocol options.

In our environment, client–middleware communication required huge amounts of data going back and forth and using SOAP was doing more harm than good. We were not comfortable with this situation and started to study the possibility to move to an open source light protocol, taking the opportunity of refactoring the code in order to reduce dependency on the chosen communication protocol.

Protocol testing and comparison

In order to decide which protocol we would like to implement we first researched a bit on the available options and after pin picking a small group we tested them in our environment. The tests were done in two phases, first we tested all the initially considered protocols with a light load and compared them. With the first phase test results in hand, we discussed the convenience of using a Java only protocol or one that allowed a mixture of client platforms. Then we decided to test further the best protocol within each category. Therefore, in the second phase we tested just two protocols, a Java only one and another allowing multiple types of client to see how they behaved on heavy loads.

We initially looked at the following protocols:

  • Hessian

Lightweight binary protocol from Caucho, HTTP-based, Custom binary serialization mechanism. Support for several platforms PHP / Python / C++ / C# / Objective C / Ruby / Java.

  • Burlap

XML-based lightweight protocol from Caucho, HTTP-based, Custom XML based serialization mechanism, Do not know support different than for Java

  • Spring HttpInvoker

Spring Java-to-Java remoting, HTTP-based, Java serialization just like RMI, easy to set up.

  • RMI JRMP Protocol

Java remoting standard, each method needs to throw a checked RemoteException and need to generate stubs and skeletons.

  • Glue SOAP

Web-Methods HTTP-based web services (was the current implementation). Support many different platforms.

Burlap was discarted before testing in favour of hessian and the resulting set was tested and compared.

First phase of protocol testing

It was intended to achieve a performance comparison within the current infrastructure just changing the wire protocol so each protocol could be compared with the current implementation using GLUE.

GLUE tests measurements were performed using the current code at the same repository release version in which the code was branched to perform necessary changes to introduce protocol independence.

For the other protocols the same test was run with the additional infrastructure to support protocol independence. Therefore the tests of the rest of the protocols were in the same conditions as the Glue test or even with a slightly overhead due to the additional layer of code.

The server and client for the test run into two JVMs on the same host to avoid network perturbations. JIT and GC are activated in order to obtain the best performance and to evaluate the common case.

The test consisted on repeated calls to the middleware services passing a structure with increasing complexity. The called method just replicates the structure and returns the copy.

The structure passed in each call is a 4 elements arraylist in which the first element is a 50 char fixed string, the second is an n-element integer arraylist, the third is an n-element UserDetails objects arraylist and the last is an n-element TestStructureBean objects arraylist. The array length shown in the data are the number of elements on the arraylists, so for a 200 array length the structure will have:

  • 1 String
  • 200 Integer

Once the structure is built for each iteration, the service is then called repeatedly using the same structure in each call. The service is called for an initial amount of times before taking any time measure to allow caching and afterwards, the elapsed time for 100 calls is measured.

Test results

Then resulting time of 100 iterations for increasing lengths of the structure is shown in the table below and also in two charts, the first one plotting the data for all protocols and the second one plotting the same data but with Glue protocol removed.

.

Protocol Response Time Table per array length (milliseconds)
Protocol Response Time

.

Protocol Response Time Chart
Protocol Response Time Chart

.

Protocol Response Time Chart Without Glue protocol
Protocol Response Time Chart Without Glue

.

Conclusion

As can be read from the data and the first chart, Glue has a strong processing overhead. When the transferred data increases on size, its response time grows much faster than the rest of protocols. The other protocols response time have a moderated grow accompanying the data size increase.

Within the other three protocols, the fastest one is the HTTPInvoker in all cases except with tiny data sizes. Hessian has a good performance rating for small and medium data sizes, performing even better than RMI but its response time degrades when the data size increases.

HTTPInvoker is then a good choice to implement Java to Java remoting and Hessian is adequate if there are other languages involved in the client side.

Second phase of protocol testing

With the results from the first testing round in hand, we decided to focus on the best two suitable options for our purposes, therefore we chose HTTP invoker and Hessian and tested them further with heavier loads.

Two different tests were performed in this phase, the first one is the same performed in the first testing phase but involving longer arrays (thousands of elements) but fewer call iterations for each array length. The second test consists in calling a method with a big String as a parameter and receiving the same String back as a result. For this test we used Strings ranging from 100k characters to 550k characters. In both cases the tests performed 10 call iterations.

Test Results

Then resulting measured time of 10 iterations for different structure lengths and document sizes are shown in the tables below. Data is also shown graphically in two bar charts and for the benefit of comparison two more charts are provided, displaying the response time ratio between Hessian and HTTP Invoker for the heavy structure and big documents tests.

.

Protocol Response Time Table
per array length (milliseconds)
Heavy load response time

.

Protocol Response Time Table
per document size (milliseconds)
Big docs response time

.

Response Time Chart for Large Structures
Heavy load response time chart

.

Response Time for big documents
Big docs response time chart

.

Response time ratio (Hessian to HTTPInvoker) Chart Large Structures
Hessian to HTTPInvoker Ratio heavy load

.

Response time ratio (Hessian to HTTPInvoker) Chart Big Documents
Hessian to HTTPInvoker Ratio big documents

.

Conclusion

HTTPInvoker was, as expected, faster than Hessian, however the idea of this tests was to check how both protocols compare for big data chunks from two points of view: A big structure formed by many small objects or a big chunk of data like a String of thousands of characters.

As can be seen in the ratio charts, Hessian performs better when transferring data in one single piece. Despite the fact that the two ratio charts are not directly comparable, it is worth noting that for structures of many small objects the ratio is almost alway over 1.6 while for single big objects the ratio is mainly below 1.6.

We finally decided to use Hessian because it allows a range of client platforms and we have a small percentage of non Java applications supported by Hessian which will access the middleware services. We could actually expose our middleware services with both protocols at the same time, but the performance gain would not compensate the system over complication that this would represent. Despite the fact that Hessian is in average a 50% slower than Http Invoker it will be for sure a huge improvement when compared to Glue.

<!---->

8 Responses

  1. Johan Says:
    <!---->

    Very nice report.

    I didn’t expect HTTP Invoker to be faster than RMI!

    Johan.

  2. Jan Says:
    <!---->

    This is indeed a nice and helpfull report. A supplemental measure which still has to be added is network latency. I presume the test is done on LAN. Recent experience is that impact on using long distance WAN-connections is also important.

  3. Miquel Says:
    <!---->

    Network latency did not affect the results as the server and client for the test run into two JVMs on the same host to avoid network perturbations. Obviously there is always some amount of latency but it certainly is not of significance for the size of the samples.

  4. Francesco Iadanza Says:
    <!---->

    Really useful report, it confirms the good work of HttpInvoker in using Java serialization algorithm, as in RMI.

  5. Chee Sang Says:
    <!---->

    Very good for reference but if you could post your source code done for this test would be best

  6. Java Remoting: Protocol Benchmarks « A Public Scratchpad Says:
    <!---->

    […] Nominet’s Protocol Benchmarks: Interesting benchmark of many of the protocols here considered. Intriguingly, HttpInvoker is found to have consistently better performance than RMI/JRMP, a finding which contradicts our results. […]

  7. techblog » Blog Archive » Using hessiancpp to call Java servlets from C++ Says:
    <!---->

    […] is a binary web service protocol. It’s quite efficient (see Daniel Gredler’s and Miquel’s benchmarks) and it’s dynamically […]

  8. Cache’s Blog » Using hessiancpp to call Java servlets from C++ Says:
    <!---->

    […] is a binary web service protocol. It’s quite efficient (see Daniel Gredler’s and Miquel’s benchmarks) and it’s dynamically […]

分享到:
评论

相关推荐

    Laravel开发-laravel-middleware-protocol

    "Laravel开发-laravel-middleware-protocol"这个主题专门关注的是Laravel 5中的协议中间件,特别是与HTTPS安全协议相关的部分。 Laravel的中间件可以实现多种功能,如身份验证、日志记录、会话管理等。在处理HTTPS...

    STM32 Pack Keil.MDK-Middleware

    这个"STM32 Pack Keil.MDK-Middleware"文件包是专门为STM32微控制器系列设计的,确保了在Keil MDK(Microcontroller Development Kit)中进行高效且便捷的开发。 STM32 Pack的主要作用在于提供固件库,这些库包括...

    SAP Middleware 官方培训教材

    根据给定文件的信息,我们可以提炼出关于"SAP Middleware"的相关知识点。下面将对这些知识点进行详细阐述。 ### SAP Middleware 概览 SAP Middleware(中间件)是SAP AG为支持企业级应用集成与交互而设计的一系列...

    Middleware-Middleware.zip

    Middleware(中间件)是ASP.NET Core中的一个核心概念,它在请求处理管道中扮演着重要角色。Middleware允许开发者自定义HTTP请求和响应的处理流程,实现诸如日志记录、身份验证、响应缓存等特性。 在ASP.NET Core中...

    Node.js-http-proxy-middleware用于把请求代理转发到其他服务器的中间件

    在 Node.js 开发中,`http-proxy-middleware` 是一款非常实用的中间件,主要用于将 HTTP 请求代理转发到其他服务器,这在构建 API 网关、微服务架构或者需要跨域访问时非常有用。这个中间件简化了配置过程,使得...

    Laravel开发-entrust-middleware

    **Laravel 开发 - Entrust Middleware** 在 Laravel 开发中,Entrust 是一个非常流行的权限管理包,它为 Laravel 应用程序提供了角色、权限和角色分配的解决方案。`Laravel开发-entrust-middleware` 提供了一种利用...

    Middleware

    ### 中间件技术详解 #### 一、分布式计算技术发展背景 随着计算机技术的飞速发展,特别是20世纪80年代以来,分布式计算技术逐渐成为解决大规模计算问题的重要手段。这一时期,分布式计算技术的发展受到了多种因素...

    Laravel开发-laravel-etag-middleware

    `Laravel Etag Middleware` 是一个专为提升响应时间和优化资源缓存策略而设计的组件。本文将深入探讨Etag的概念,以及如何在Laravel中利用这个中间件来实现更优秀的性能优化。 Etag,全称Entity Tag,是一种HTTP...

    前端开源库-composable-middleware

    "composable-middleware" 是一个专为前端设计的开源库,它引入了一种可组合的中间件机制,使得处理复杂应用逻辑变得更加灵活和模块化。本文将深入探讨这个库的核心概念、工作原理以及如何在实际项目中应用。 ### ...

    redux-promise-middleware例子

    在本文中,我们将深入探讨如何使用`redux-promise-middleware`在React应用中实现异步操作,特别是针对登录验证功能。`redux-promise-middleware`是Redux生态系统中的一个中间件,它允许我们处理Promise,使得在Redux...

    Oracle_Fusion_Middleware_11g_介绍

    Oracle Fusion Middleware 11g是Oracle公司推出的融合中间件的11g版本,它是一个全面集成的中间件套件,为开发和部署企业级应用提供了丰富的产品和功能。Oracle Fusion Middleware 11g不仅支持现有企业信息化解决...

    Node.js代理中间件http-proxy-middleware.zip

    http-proxy-middleware 是一套 Node.js 代理中间件 for connect, express 和 browser-sync。安装$ npm install --save-dev http-proxy-middleware配置var proxyMiddleware = require('http-proxy-middleware'...

    前端开源库-rollup-middleware

    前端开源库-rollup-middleware总成型中间件,简单的总成型中间件,可以重建捆绑包。

    webpack-使用webpack-dev-middleware.rar

    `webpack-dev-middleware` 是 Webpack 提供的一个中间件,用于集成到 Node.js 的服务器环境中,实现快速、热更新的开发环境。 在 Web 开发过程中,频繁地手动刷新浏览器来查看代码改动既耗时又低效。`webpack-dev-...

    Laravel开发-laravel-middleware-request-id

    **Laravel 开发中的 Middleware 和 Request ID** 在 Laravel 框架中,Middleware(中间件)扮演着关键的角色,它们是处理 HTTP 请求和响应的重要组件。Middleware 可以看作是请求进入应用前和响应离开应用后的一个...

    Laravel开发-laravel-xml-middleware

    本教程将专注于`laravel-xml-middleware`,一个专为Laravel设计的中间件,允许应用接收并处理XML格式的请求。这个中间件是扩展Laravel功能的一个优秀实践,它使你的API能够更灵活地服务于各种客户端需求。 首先,让...

    Keil.MDK-Middleware.7.12.0.pack

    电脑需先安装Keil MDK5。此固件库为Keil官方提供,直接双击安装即可,安装成功后在MDK5工程的Device中验证,或者在PACK安装页面选择File-&gt;Import 官网下载比较慢,为方便大家提供分享

    Python库 | oslo.middleware-2.5.0-py2.py3-none-any.whl

    "Python库 | oslo.middleware-2.5.0-py2.py3-none-any.whl" 是一个针对Python开发的中间件库,版本为2.5.0。这个库是开源的,专为Python后端开发设计,它包含了多个实用的中间件组件,用于构建和增强Web服务应用程序...

    middleware server

    "middleware server",正如其名,是一种软件平台,它提供服务来连接和协调不同的应用程序,使其能够相互通信和交换数据。在这个特定的场景中,"irs trading system"(可能是Internal Revenue Service的交易系统)与...

Global site tag (gtag.js) - Google Analytics