Java EE和 ASP.NET 核心技术在Web API开发中的性能比较
作者: Kristiāns Kronis; Marina Uhanova
出处: [J]Applied Computer SystemsVolume 2018
Java EE开发由Oracle提供, ASP.NET由微软开发,两者都是提供基于Web 的应用程序创建功能。然而在最近的历史中Java EE有更好的跨平台支持-可以安装 JVM(Java Virtual )的 HotSpot 实现,在 Windows 和 GNU/Linux 操作系统由 Oracle支持。但是,在处理时完整的.NET框架不能在GNU/Linux上运行必须使用Mono,它最初是开源的项目直到2016年才被微软收购。不提供对WPF(Windows Presentation Foundation)的支持。
本文描述了一个web系统的实现,用于运行有现实世界测试并收集结果,提供即时视觉效果对用户的反馈。基准测试的主要目标是获得两种技术性能的近似值堆栈在 GNU/Linux 操作系统上并突出显示等任何明显的差异。还列出了一般准则软件架构和实施实践,以确保生成数百个并发请求的能力 并有效地处理它们,以及处理任何错误。通过 REST(具象状态传输)API (应用程序编程接口),使用 JSON (JavaScript Object Notation)用于数据传输和在两种技术中实现并部署在相同技术上的服务器。一个单独的应用程序由测试的前端组成 用 Angular 5 编写的配置,以及用于测试执行和结果处理,用 Express 和 Node.js,使用 Redis 进行临时存储和 MySQL 对于结果日志记录,还会创建该系统设计模块化实现测试 API 的服务器除了配置之外还在前端界面中配置了 Redis 和 MySQL 日志记录。该系统应作为起点,允许可扩展性 – 添加更多服务器,这些服务器可以运行不同的语言和软件或硬件配置。
Java EE(Java Platform,Enterprise Edition)是 Java SE延伸Java API 提供的功能,它们在企业环境中很有用,例如依赖关系注入(CDI,EJB)事务管理(JTA)和动态网页功能(JSP,JSF),以及同时创建Web服务(JAX-RS、JAX-WS)还缩短了开发时间和软件复杂性。该开发项目由 Java Community Process(JCP)和基于Java 规范请求(JSR)。 本文描述了一个使用 Java EE 7 的设置,于2013年发布。Java EE 7 平台可以是进一步分为完整平台和网络配置文件,其目的是提供一组更有限的功能,这更容易支持开发的接口实现利用了Servlets,JSON,CDI和 JAX-RS,因此使用了完整平台规范的元素。选择Java EE 7,因为在撰写本文时,Java EE 8 采用仍然有限,只有 Glassfish 5.0 和 Payara 5 支持该规范,两者都不像 Apache Tomcat,Apache TomEE的基础。
ASP.NET(Active Server Pages .NET)是一个Web应用程序 由微软开发并利用CLR的框架提供的功能类似于Java EE,例如, Web窗口允许在类似的风格到JSP和JSF和许多组件,特别是 ASP.NET 的Web API,ASP.NET AJAX ASP.NET MVC提供各种功能。通常运行 ASP.NET 在 IIS(互联网信息服务)上,不支持在微软的GNU/Linux上;因此,必须使用mono。
ASP.NET 核心是下一代 ASP.NET 由微软和社区贡献者开发和可以在完整的.NET框架和.NET Core上运行的平台。这是一个重写,旨在提供一个更苗条, 但更多最新的功能集,以及新的轻量级 Web服务器,Kestrel(尽管仍然可以在窗口)。它支持多个组件 - 实体框架核心,MVC核心和剃刀核心,其中其他的,作为 ASP.NET 中发现的替代品.
测试要求:为了确保最佳结果,不会受到所用操作系统的配置,一些准则是为系统设计定义:
1. API 的实现将放在单独的服务器在这种情况下,VPS(虚拟专用服务器)使用。
2. 两台服务器应具有相同的类型和版本 操作系统在这种情况下,Ubuntu 16.04.4 LTS 是选择。
3. 为了确保服务器的性能相同它们应通过综合基准测试。两者都要受到相同类型的基准。在这里系统组0.4.12 被使用了。
4. 服务器应使用相同的软件运行更新并仅在所需的软件包中有所不同运行实现 - 在这种情况下OpenJDK 和 .NET Core.
5.测试特定技术的Web服务器的性能 堆栈执行(Apache TomEE 和 Kestrel),没有反向 将使用代理(例如Apache httpd或Nginx)。 还列出了如何测试的要求应该 进行以防止内存泄漏和错误引起的 测试系统本身的实现:
1. 调用基准的服务不应超过其负载能力。这是由每个确保的按顺序测试的 API,以防止服务不受负载的影响,而它仍然可以并行运行单个测试的多个迭代。
2.应该可以轻松添加和删除要成为 运行,使用调度程序 – 这是在前端实现的,因此不会将测试服务限制为顺序 执行,但只能以这种方式使用它。这 允许面向未来,如果有的话 多个 API 并发测试的要求。
3. 交换不相关的数据 应尽量减少系统的层(API、测试服务和前端)。在这里,内容 测试请求是在测试服务本身上生成的 并且仅与 API 交换,这些 API 将 测试。前端仅接收结果。
4. 测试结果应分块并提供给 前端根据要求,在完成所有 但是,计划的测试迭代也应过期 在设定的时间量后(如果未检索)。
5. 网页界面应该是轻量级的。这是实现的 通过对结果进行分组并在 运行超过 100 次迭代时的组,以防止 图表框架不会对性能产生负面影响。MySQL数据库可用于对结果进行更精细的分析。
该系统由几个组件组成,每个组件使用重新创建配置的通用技术,可以在实际使用中找到。 A. Java API 实现 Java API 是使用 Java EE 特性和 避免使用第三方框架,例如 Spring,其中 可能。它运行在Apache TomEE Web Profile 7.0.2上, 它提供了Java EE 7 Web Profile的功能,使用起来 开源组件(OpenEJB,Apache CXF等. 基于Apache Tomcat - 一个流行的应用程序容器 [15]它通过OpenJDK版本1.8.0_151运行。 B. ASP.NET 核心 API 实现 ASP.NET 核心 API 是使用 ASP.NET 实现的 核心功能和避免第三方框架,其中 可能。它运行在 Kestrel Web 服务器 2.0.1 上。这 分发通过 .NET Core 版本 2.1.3 运行。 C. 节点.js+快速测试服务 测试服务运行在 Node.js v9.2.1 上,基于 快递 4.15.5。它使用 cors、redis、express-redis 和 requestpromise-native 包(通过 npm 安装),其中 其他,以提供必要的功能。 D. 角度网页界面 前端是用 Angular 5.0.0、TypeScript 2.5.3 创建的 和 Bootstrap 4,用于提供样式和 用户界面的行为,结合jQuery 3.2.1. 用作桥梁 在 Angular 和 Chart.js 之间,一个提供 基于HTML5的图形显示功能。
前端用作系统其余部分的门面允许配置要使用的 Redis 和 MySQL 实例,如 以及要进行测试的服务器。它不处理 生成测试请求 contents,但制定时间表 在后端调用测试服务。 应用程序结构基于单个 Angular 模块, 它具有用于存储有关设置和测试的数据的服务, 后者包含两个测试条目本身 - 与 有关测试类型、迭代和其他参数的数据 – 以及 要使用的服务器,每个测试都引用了 服务器对象之一。 应用的其余部分由实用程序类组成(例如 枚举或通知组件)和组件 显示数据并组织输入和输出 - 选项卡,菜单 和图表组件。 该界面以选项卡形式显示仅显示以下信息 在任何给定时刻与用户相关 - 有选项卡 运行测试并显示其结果,以及 配置服务器本身,并更改系统设置Web 界面,其中打开了测试选项卡,其中列出了可用的测试 类型。Web界面,其中打开了服务器配置选项卡,其中列出了 当前服务器。 最后,基准测试过程还试图将 请求运行时到其组件中,这些组件也会显示 图中不同– 请求花费的时间 在网络上以及处理它所花费的时间。这水平轴显示迭代或迭代范围(如果 运行超过 100 次迭代),而垂直轴显示执行时间(以毫秒为单位)。Web界面的一部分,显示测试和控件的结果 用于更改其参数。 这是通过系统的自我报告来实现的,并且 以堆叠条形图的形式显示,其中底部 条形显示 API 上报告的测试执行时间,而 顶部栏显示剩余的时间,它花费了 到达测试服务的请求(计算公式为 从总时间中减去执行时间)。
前端之间的通信以及和后端系统各层使用 HTTP 进行通信请求,由 HttpClient 类在 与 Angular 上的 JavaScript JSON 类组合 端,以及后端带有正文解析器的快速路由。 选择这种格式是因为它允许轻松的信息 图层之间的交换,因为它们将内容用作任何 其他 JavaScript 对象。 图 6.网络请求图,其中 Redis 显示为 后端作为可能的配置。 测试服务公开了两条路径:/schedule 和 /results,前者允许为 执行,而后者可以由前端轮询到 定期接收并清除存储在 Redis 中的结果列表,如 以及检查执行是否已完成。两者都利用 用于临时存储数据的 Redis,选择它是因为 性能,因为它使用 RAM(随机存取存储器)用于 临时键值存储。它通过 expressredis 库访问,该库镜像官方 API 并允许原子访问。唯一的例外是设置 TTL 值 对于列表,这是在单独的调用中完成的,以生成值 如果在一定时间内未请求它们,则过期。 出于调试目的,所有通信之间的 系统的层可以在浏览器控制台中记录 或 Node.js 输出,该输出将重定向到文件。 在测试服务上启动测试时,所有相关 数据执行必须在第一个请求中传递:它的种类,要运行的迭代、其唯一标识符、有关 要使用的测试 API,以及 的配置数据 Redis和MySQL。 对测试结果请求的响应包含信息 关于它是否完成,以及结果的数组。 结果包括内容以及响应 请求,条目描述的特定迭代,以及作为有关错误的信息,如果发生任何错误(在 所用语言的堆栈跟踪内容的形式)。 还包括用于测量执行时间的时间戳。 收到的时间戳成对出现,源时间戳是 由 Node.js 服务器生成,而目标服务器是由测试 API 生成。因此它们不必匹配从而允许服务器时间配置不同,而不影响功能。查看数据后出现了一些兴趣点这需要进一步解释。 ASP.NET 核心测试成功百分比 虽然Java能够为100%的请求提供服务 在各个级别的并行化和测试类型中,这 ASP.NET核心的情况并非如此。虽然在大多数测试中 类型它的成功率是相同的它无法服务于所有生成大型静态文本响应时的请求 (大小超过 1 兆字节)并在生成 SHA256 时散列。 这可以通过硬件约束(服务器可用的RAM量)导致 API 操作系统将在以下时间后终止的运行时耗尽所有可用资源。运行ASP.NET 核心实现的服务器上的 htop 输出,虽然StringBuilder概念的实现由标准库提供,用于实现对于Java和 ASP.NET Core,它出现了 ASP.NET 核心的内存使用量略低;因此,它无法成功运行测试提供的资源。这种行为也是可重复的对于其他测试类型,对数据大小的请求增加。B. ASP.NET核心静态文本基准测试结果看来ASP.NET核心文本生成基准测试不仅成功率更低,而且成功率也差得多更长的测试执行时间,这可以归因于结果的网络时间部分–ASP.NET 核心平均 2096 毫秒来接收和发送响应,与Java的平均679毫秒相比,差异很大,大约是 3 倍。一种可能的解释是网络服务器ASP.NET Core的使用目前优化较差与Apache Tomcat和Apache TomEE相比因为它是相对较新的。这不仅体现在以下事实中:特定测试涉及发送和接收最大数据包,而且还受网络时间的事实 ASP.NET API 实现在 15 个中的 13 个中更高。Java JSON 写入基准测试结果另一个可能引起注意的数据点是平均值 JSON 写入的请求处理时间基准测试,其中在Java上运行。这个平均 4727 毫秒不仅是比ASP.NET 核心实现要长得多—— 64毫秒,但也是其中最长的基准测试适用于所有测试类型和技术使用。 这可以解释为对于这两种语言,测试请求和响应的 JSON 都是动态生成和解析,与更多生成静态实体的传统方法。虽然这 在一定程度上牺牲了类型安全性,它允许更大的灵活性和更快的开发时间,这就是为什么选择了方法。 这就是语言之间的差异体现的地方本身 – C#,这是 ASP.NET 核心的语言编写了实现,支持动态数据类型, 而Java没有提供这样的功能。 在Java中使用了Json类,它提供了对创建对象和数组构建器,以及读取 JSON 数据。然而,这确实带来了一个缺点: 需要为每个项目创建的对象,该对象必须是 序列化。这在使用 深嵌套结构,因此性能降级,即使它没有导致故障。 例如,C# 中的代码如下所示列表生成List<dynamic> generatedObjectsArray=new List<dynamic>();在Java中必须执行以下操作 JsonArrayBuilder generated ObjectsArray = Json.createArrayBuilder(); 来返回生成对象数组;
在检查结果后可以得出一些结论以及改进测试过程的建议和所使用的方法。 A. 测试 API 实现同时使用动态数据类型功能规避必须为每个不同的基准测试可以节省时间,它可能导致次优结果因为它是在遇到不稳定的情况下还应该进行测试,同时遵循以下方法将来定义实体类以查看Java是否性能能够得到改善。 此外,所用技术的性能也可以在运行 Windows 的服务器上进行比较,其中 IIS 是也可以使用,并且可以提供与以下方面相关的不同结果。为了获得更深入的见解,记录 服务器资源使用情况和尝试在更强大的功能上进行测试 硬件配置,以实现更大的并行化和查看多核处理器利用率有何不同。 B. 运行时虽然 ASP.NET 核心内存管理存在问题。但是,两种技术的整体性能都是主观上相似和可比——两者都没有明显在所有测试类型中,比其他测试更慢或更快。 按理说,由于这个结果,选择用于解决问题的算法,进而是代码包含在库中,这些库可用于发展进程可能会产生更大的影响,而不是 选择其中一种技术,因为性能差异不大。 过去进行的科学研究,以及更现代的基准测试尝试似乎表示Java 的性能,以及 C#( ASP.NET 和 ASP.NET 核心)依赖于它们应用于的特定任务。 虽然 ASP.NET Core 处理请求的速度更快, 但是似乎网络服务器需要更长的时间才能交付几乎所有情况下的响应都是如此。还应该注意的是在没有阻塞进程的情况下, 例如等待数据库返回结果或读取数据 从磁盘来看,一个请求似乎会花费大部分时间 通过网络行进的时间,作为平均值处理时间明显小于网络。 得出的结果是,ASP.NET 核心是一项新技术并且正在积极开发中。因此虽然它不如JavaEE成熟,但是在未来可能会发生变化。