java paas_Java PaaS决战

PaaS年?

2010年12月,salesforce.com以2.12亿美元的现金收购了基于Ruby的PaaS平台供应商Heroku,这恰好结束了PaaS的快速增长和大肆宣传的一年。 从那以后,围绕PaaS的讨论只增加了。 行业研究公司Gartner宣布2011年为“平台即服务之年”,Gartner分析师Yefim Natis预测,“到2015年,云平台经验将成为IT软件项目大多数招聘决策中必不可少的技能”(请参阅参考资料 )。

PaaS是一种云服务,其中提供商不但提供按需硬件和操作系统服务,而且还提供应用程序平台和解决方案堆栈。 PaaS服务使与应用程序部署相关的大多数IT管理方面实现自动化,包括资源分配,分段和测试,负载平衡,数据库访问以及对平台库的访问。 PaaS的一个关键功能是多租户体系结构 :多个不相关的应用程序可以在相同的硬件和软件基础结构上运行,从而节省了成本并更有效地利用了计算资源。 开发人员可以专注于应用程序本身,而不是部署和IT问题。

Java开发人员可以很好地学习和利用PaaS开发模型。 毕竟,PaaS概念在服务器端Java的早期就已根深蒂固。 当时,出售IT组织的愿景是将应用程序服务器用作“容器”,然后放入应用程序归档文件以在共享资源环境中运行(请参阅PaaS前身侧边栏)。 这种愿景与我们今天看到的PaaS服务非常相似。

但是,早期的PaaS对Java企业应用程序的愿景并未实现。 Java应用程序服务器从未变得足够稳定,无法随意部署和取消部署多个不相关的应用程序。 归档结构最终增加了Java应用程序开发周期的开销:尽管PHP和Ruby on Rails开发人员可以更改一行代码并重新加载浏览器以查看差异,但是Java开发人员必须重新编译,重新打包和重新部署他们的应用程序,甚至经常重新启动应用程序服务器。

PaaS前身:独立的Java EE部署单元

当Java Servlet技术出现时,将Java Web应用程序与CGI或PHP应用程序区分开的主要特征之一是,Java应用程序应该独立存在于“编写一次,在任何地方运行” WAR文件中。 WAR文件包括应用程序所需的所有代码,配置,媒体和其他文件。 在运行时,WAR应用程序也应该是自包含的-应用程序只能“查看”其自己的WAR文件中的类和资源,以免干扰其他WAR文件中的类和文件。 应用程序存档格式后来被扩展为包括其他类型的自包含企业应用程序模块。 这些独立的应用程序部署单元很自然地适用于PaaS。

事实证明,只有通过比JVM先进得多的新一代虚拟化技术的出现,才可以实现PaaS愿景。 在Google App Engine的引领下,新一代Java PaaS服务实现了Java EE的古老承诺。 他们提供随需应变的IT基础架构,可随您的需求而增长,而无需您预先投资昂贵的硬件和系统管理功能。

在本文中,我将研究三种领先的Java公共PaaS产品,以比较它们的方法,优点和缺点。 这三个都提供相同的基本功能集,包括:

  • 上载和部署应用程序WAR
  • 版本化已部署的应用程序
  • 测试和暂存环境
  • 在线访问日志文件
  • 自动化监控和使用情况报告

但是,除了这些共同的特征之外,还有一些重要的区别。 根据我在使用这些新兴技术方面的经验,我将提供一个比较它们的框架,并讨论可能的解决方法,以帮助您避免在使用它们时遇到的问题。

Google App引擎

Google App Engine(GAE)是第一个被广泛采用的Java PaaS平台。 (Java版本有时被称为GAE / J,以使其与GAE的基于Python的PaaS产品区分开。)它也可能是市场上“最纯正的” PaaS产品-从某种意义上说,它几乎完全从开发人员那里提取了基础架构。 。

Java,但不是完全Java

自2009年以来,GAE就一直将Java平台作为开发和部署环境提供支持。但是,GAE对Java的支持是有限的,并且不符合标准。 由于存在许多限制,因此它对应用程序施加了限制-其中许多是出于保持可伸缩性的充分理由-GAE不支持某些Java平台API:最明显的是,文件写入I / O(因为GAE不提供可访问的文件系统应用程序)和许多网络I / O API(因为GAE对源自应用程序的网络操作施加了严格的限制)。 请参阅相关的主题为“白名单” Java平台通过GAE支持的API的完整列表。

通过支持其自己的有限网络I / O API,GAE限制了应用程序连接到其他服务的能力。 GAE名义上允许应用程序与其他服务器建立出站连接。 但是,为了使系统中的线程数受到控制,GAE会在5到10秒后强制关闭任何应用程序启动的连接。 这使得GAE成为混搭类型应用程序的不可靠平台。 对于使用第三方Web服务API的越来越多的应用程序,这是GAE的主要限制。

此外,当您需要使用现有应用程序框架或将现有应用程序迁移到GAE时,这些API限制会带来挑战。 经过多年的发展,企业Java开发在很大程度上依赖于框架。 尽管某些流行的框架(例如Spring和Struts)在GAE上是开箱即用的,但是许多其他框架要么不起作用,要么需要对其源代码进行补丁。 手动修改框架源代码以使其在GAE上运行从来都不是一个好主意,因为本质上是在创建破坏上游兼容性的fork,并且可能将难以调试的错误引入框架中。 JavaServer Faces(JSF)Web框架就是一个很好的例子:它需要在GAE环境中运行源代码级别的黑客攻击,即使如此,JSF之上的许多UI库也与GAE不兼容。 (请参阅相关的主题为GAE支持的Java框架的列表。)

同样,已经开发的大型企业应用程序可能会使用GAE禁止的API。 将这些应用程序迁移到GAE可能会花费很多,因为您不仅需要确定问题并创建变通办法,而且还要对整个应用程序进行质量保证。

通过不支持Java平台API的一部分,GAE打破了Java的“一次编写,随处运行”的承诺。 对于许多人来说,这不是一个破坏交易的事情,但这是潜在用户需要注意的事情。

云计算和IBM的PaaS

在对IBM WebSphere CTO Jerry Cuomo的采访中 ,了解IBM在云中的发展。 Cuomo讨论了IBM对公共,私有和混合云计算的愿景,详细介绍了IBM针对基于WebSphere,DB2和MQ构建的PaaS产品的计划,以及对云标准化的需求。

可扩展性和性能

GAE承诺并提供可伸缩性,但不一定具有原始性能。 Web应用程序的原始性能是通过对Web请求的响应时间来衡量的。 可伸缩性是指平台有能力保持一致的响应时间,而不管有多少用户正在访问系统。 例如,对于100个并发用户具有3秒响应的可伸缩系统,对于100万并发用户应具有3秒响应时间。

通过一致的响应时间,GAE提供了出色的可伸缩性。 但是它的原始性能通常很慢。 以我自己的轶事经验,GAE通常需要1-3秒来响应与数据库相关的请求。

该特性对应用程序开发人员具有明显的意义。 对于大多数时间处于空闲状态的Web应用程序(即,大多数小型Web应用程序),即使在低端虚拟专用服务器上,在GAE基础架构上进行部署也不会产生性能优势。 当您需要大规模扩展应用程序,远远超出低端服务器硬件的能力时,真正的性能优势就会显现。

低流量网站的另一个性能问题是GAE会将不活动的JVM交换出内存,以针对系统上的高流量Web应用程序进行优化。 如果您的JVM的内存不足,则GAE必须在下次请求进入时花额外的时间来启动整个应用程序。对于低流量的Web应用程序,这可能会导致性能降低(第一次等待时间超过5秒)请求)。 GAE为开发人员提供了一种选择,使其可以选择付款并将不活动的JVM保留在内存中,以获得更一致的性能。 提示:在GAE内设置一个cron作业,每2至3分钟加载一次您自己的网站,以保持JVM处于活动状态。

BigTable的优点和局限性

GAE的一项关键创新是使用了真正可扩展的数据存储:Google BigTable。 大多数Web应用程序使用关系数据库作为数据后端。 但是众所周知,关系数据库很难扩展。 为了解决这个问题,Google的研究人员开发了另一种称为BigTable的数据存储解决方案,它是NoSQL数据库领域中的一种数据存储解决方案。

与在关系数据库中一样,BigTable中的数据可以组织成具有行和列的表,并且每一行都有唯一的索引ID。 与关系数据库不同,BigTable表没有固定的架构,通常是非规范化的。 表格中的每一行可以有不同的列。 最佳做法是在一行中有许多列,而不是通过键列在不同表之间链接不同的行。 这对数据模型的设计有很大的影响。 鼓励应用程序开发人员不要设计标准化的关系模型,而是将冗余信息放入每一行中,以便于检索。 想想Web服务器的访问日志,其中IP地址和浏览器代理在每一行中重复出现,这会占用空间但简化了批量处理。

BigTable的好处是可伸缩性。 Google工程师声称,BigTable中数据查询的响应时间仅取决于结果数据集的大小。 无论查询是针对1000行表还是1000万行表,只要结果限制为1,000行,您都可以获得相同的性能。 就GAE而言,它会将每个查询的返回数据集限制为1,000行。

适应NoSQL范式,尽管这对于来自SQL背景的开发人员来说可能是一个挑战,但随着越来越多的IT组织面临大数据挑战,这是一项重要技能。 我发现GAE是Java开发人员开始学习NoSQL的最佳和最容易的地方之一。

但是,尽管BigTable是GAE大规模可扩展性的关键,但它的当前实现对Java开发人员而言仍有很多不足之处。 BigTable的特定缺点(以及一些潜在的解决方法)包括:

  • 对数据查询的支持不足 :用Google查询语言(GQL)编写的查询用于从BigTable检索数据。 GAE要求对查询中涉及的所有数据列建立索引,并且索引不能包含BLOB或text列。 没关系,除了GAE每个表只允许100个索引。 对于标准SQL数据库而言,这可能就足够了,但是像BigTable这样的非规范化NoSQL数据库可能具有数千个列,因此对于许多应用程序而言,限制100个索引。 更糟糕的是,GAE没有提供简便的方法来删除不再使用的索引。

    决定要创建哪个索引对于GAE开发人员来说是沉重的负担。 如果查询使用未索引的列的组合,则GAE仅在执行查询时在运行时抛出异常。 尽管SDK提供了在本地计算机上测试应用程序时自动生成索引配置文件的工具,但是,如果您没有详尽地手动测试所有执行路径,您仍然可能会错过索引。 将自动生成的索引合并到已经部署的应用程序中也是一个潜在的容易出错的过程,直到Web应用程序用户点击配置错误的索引之前,才会出现错误指示。

    最后,令人震惊的是-考虑到BigTable是Google的产品-它不支持数据库中的自由文本搜索。 您可以将诸如Apache Lucene之类的搜索引擎实现嵌入到您的应用程序中,以对文本列进行索引和搜索(请参阅参考资料 )。 但这对于较小的网站来说是个很大的麻烦,对于这些网站而言,标准SQL LIKE语句足以进行简单的文本搜索。

  • 难以导入和导出数据 :BigTable的另一个主要问题是无法导入和导出数据。 由于没有直接访问BigTable的标准API,因此必须将数据导入和数据导出逻辑写入自己的应用程序内的servlet中,并使用自己的Web界面来导入或导出数据。

    由于GAE在30秒后终止了任何Web请求线程,因此不可能通过持久连接将大量数据上传到BigTable中。 常见的解决方法是将数据导入分为多个部分,每个部分所需的上传和处理时间少于30秒。 然后,您可以使用自动HTTP驱动程序(例如JMeter或Grinder)逐个运行这些任务,直到导入所有数据。 不用说,这是一个乏味的过程。

    从BigTable导出数据更成问题。 因为API将每个数据查询限制为1,000个结果,所以导出数据必须以比30秒处理超时约束所允许的更小的块进行管理。

认识到BigTable对于大多数开发人员的局限性,GAE通过其付费业务产品提供对托管MySQL服务的访问。

与其他服务整合

GAE提供了与其他Google服务的出色集成。 值得注意的是,该应用程序可以与Google帐户集成,以便用户可以使用Google用户名和密码登录到您的应用程序。 鉴于构建用户管理系统是每个网站必须做的重复工作,因此这可能会节省大量时间。 但是,不利的一面是,并非所有用户都拥有Google帐户,并且将您的网站与Google帐户绑定会使以后很难转移到其他PaaS提供商。

GAE应用程序还可以使用简单的API通过GMail服务器发送电子邮件。 与不安全的SMTP服务器相比,GMail服务器受收件人ISP阻止的可能性要小得多。

如果您将域托管在Google Apps上,则还可以通过将Google Apps帐户与GAE帐户相关联,将应用程序配置为可通过您控制的任何子域访问。 例如,如果mydomain.com由Google Apps托管,则可以从www.mydomain.com而不是mydomain.appspot.com访问您的应用程序。

判决

总体而言,GAE提供了设计良好且可扩展的PaaS。 它为小型网站提供的大量免费配额也很吸引人。 但是,缺乏对完整Java平台的支持可能会破坏交易,并且GAE中的某些组件仍处于试验阶段,而不是准备投入生产。

亚马逊Elastic Beanstalk

Amazon Elastic Beanstalk是Amazon Web Services的一项相对较新的产品,它提供了基于Amazon Elastic Computing Cloud(EC2)基础架构的托管Apache Tomcat运行时环境。 EC2是一种基础架构即服务(IaaS)产品,因此它比GAE提供了更多的灵活性。 但作为权衡,这也需要开发人员付出更多努力来管理和扩展应用程序。

纯Java Tomcat

Beanstalk环境支持在EC2虚拟服务器上运行的完整Tomcat服务器。 它是一个纯Java环境,可以访问基础文件系统。 由于Tomcat的流行,几乎所有企业Java框架都支持Tomcat部署。 这些框架可以从Tomcat WAR文件启动或引导,从而为您提供多种选择的框架和库。

普通的Tomcat运行时对线程和文件或网络I / O没有限制。 只要需要,网络I / O线程就可以保持打开状态。 您仅受基础虚拟机容量的限制。

按比例缩放

Beanstalk通过自动启动新的EC2实例并将WAR文件部署到新实例来扩展您的应用程序。 您的所有Beanstalk EC2实例都在负载均衡器后面运行。 您可以使用基于Web的管理控制台监视每个EC2实例上可用的资源,并设置规则,以在现有服务器负载超过预设限制时自动启动负载均衡器后面的新服务器实例。

负载平衡的Web群集中的一个常见问题是如何处理HTTP会话。 每个Tomcat服务器节点都为其客户端创建和管理会话对象。 如果Web请求跨多个服务器节点进行负载平衡,则需要确保为请求提供服务的服务器节点具有正确的会话对象。 一种简单的存档方法是在负载均衡器中启用“粘性会话”,要求负载均衡器记住由其背后的每个服务器维护的会话cookie,并根据传入的cookie将请求转发到正确的服务器。 可以在Beanstalk负载平衡器管理控制台中打开“粘性会话”。 更加有效和故障安全的解决方案包括在服务器节点之间设置共享内存,或仅将会话对象保存到中央数据库中。 这些选项允许负载均衡器将请求转发到随机或最不繁忙的服务器节点,因为每个服务器节点都具有相同的会话状态信息。 但是所有这些选项都需要应用程序开发人员的努力。 与自动将会话数据保存到BigTable中的GAE不同,Beanstalk要求您完成所有工作。

Beanstalk的最大缺点之一可能是价格,特别是对于可以在其他地方免费托管的小型网站。 尽管Amazon EC2为新注册提供了“一年免费”计划,但Beanstalk的标准价格每月甚至接近40美元,即使是单节点设置也是如此。 对于可在需要时在几分钟内自动扩展的支持集群的基础架构来说,这是很便宜的价格,但如果您的应用程序大部分时间处于闲置状态且偶尔出现流量激增,则与GAE之类的相比,这是昂贵的。

灵活的数据库选择

Elastic Beanstalk平台的优势之一是选择数据库技术时的灵活性。 它提供了几种选择:

  • 关系数据库 :通过Amazon自己的关系数据库服务(RDS),您可以部署各种关系数据库。 这些数据库服务器由Amazon管理和监视,很容易将数据导入到它们中或从中导出。 在您的应用程序内部,您所需要做的就是将数据源指向RDS服务器。 但是请注意,每个RDS实例都是运行您的数据库的另一个专用服务器实例-并且数据库实例的价格比同类EC2实例高30%。 成本可能会增加,并且许多应用程序不需要专用的数据库服务器。
  • NoSQL :RDS服务器的一个问题是它是一个很难扩展的关系数据库。 如果您喜欢类似于Google BigTable的NoSQL方法,那么Amazon SimpleDB也可以使用它。 SimpleDB的Java API使您的应用程序可以轻松访问数据。
  • 您自己的数据库服务器 :因为EC2提供对原始虚拟服务器的访问,所以您可以在单独的EC2实例上设置自己的数据库或NoSQL数据源(例如Apache Cassandra),只需将Beanstalk应用程序指向您自己的数据库服务器即可。

数据库选择的灵活性,特别是使用Amazon托管关系数据库的能力,很可能会吸引企业开发人员。

与其他服务整合

除了Amazon RDS和SimpleDB,Beanstalk服务器还可以访问其他Amazon服务,例如简单队列服务,S3存储,简单电子邮件服务(SES)和付款API。 SES特别有趣,并且可以与GAE中的GMail API进行比较。

SES有一个简单的API,它使您可以使用Amazon的SMTP服务器发送电子邮件。 与在您自己的EC2实例上设置不安全的SMTP服务器相比,使用Amazon SMTP服务器的好处在于,Amazon服务器不太可能被主要ISP的垃圾邮件过滤器阻止。 为此,SES提供了一组丰富的工具来控制电子邮件数量的增长并接收来自ISP垃圾邮件过滤器的反馈。 所有这些功能都可用于Beanstalk应用程序,以便您可以监视广告系列并优化电子邮件内容以更有效地进行传递。

判决

总体而言,Amazon Elastic Beanstalk大大简化了Tomcat应用程序的部署和扩展。 但是,它仍然提供了基础EC2基础架构的灵活性,这使其非常适合企业应用程序。 然而,对于低流量的网站或业余爱好者而言,成本很高。

CloudBees RUN @ Cloud

CloudBees是Java PaaS领域的新成员。 它可能是一家初创企业,但背后的人都是企业Java资深人士。 (它是由JBoss前CTO Sacha Labourey创立的,并聘用了JBoss成名的开源Java重量级人物Adrian Brock和Hudson成名的开源Kokouke Kawaguchi。)其PaaS技术是从Stax Networks收购的,该公司一直在为Stax Networks提供托管Java应用程序服务。企业客户已有十年以上。 CloudBees RUN @ Cloud服务基于健壮的Stax平台,并且可以通过自助式Web门户供个人开发人员使用。

与大型企业相比,RUN @ Cloud旨在在托管可扩展性(如GAE)和灵活性(如亚马逊的PaaS服务)之间找到适当的平衡,同时通过以下方式添加端到端的开发生命周期支持该平台。

强大的Java运行时

RUN @ Cloud服务当前基于EC2基础结构,可以将其视为Beanstalk + RDS的自动化版本。 像Beanstalk一样,RUN @ Cloud还为每个Web应用程序提供了在EC2虚拟服务器上运行的专用Tomcat实例。 它提供了纯Java环境,对文件系统访问,网络I / O和线程没有人为限制。

RUN @ Cloud作为一家小型独立公司的优势之一是,它不需要与Amazon捆绑在一起。 它计划在不久的将来向其他基础设施提供商提供补充EC2的服务。

免费的可扩展基础架构

与Beanstalk相似,RUN @ Cloud提供了可扩展的基础结构,其中包含负载平衡器和服务器实例,可按需启动以满足流量激增的需求。 但是RUN @ Cloud比Beanstalk提供了更多的自动化功能。 例如,RUN @ Cloud已经配置了Tomcat服务器以将会话保存到其管理下的数据库中,而不是使用“粘性会话”。 此托管会话对象数据库对开发人员是透明的,就像GAE一样。

由于RUN @ Cloud可以使用共享的负载平衡器来管理在单个EC2实例上运行的多个Tomcat服务器,因此它不需要每个Tomcat实例一个EC2实例。 因此,它可以以比Beanstalk低得多的成本运行低流量的网站。 实际上,RUN @ Cloud具有免费使用层,非常适合低流量应用程序或业余开发人员和学生。

但是,也像GAE一样,如果您的应用程序长时间处于非活动状态,则RUN @ Cloud可以将JVM的内存换出以节省资源。 当应用程序“预热”时,这可能导致对第一个请求的响应变慢。

托管的MySQL关系数据库

RUN @ Cloud服务与Tomcat服务一起本地支持托管MySQL服务。 您可以通过基于Web的管理控制台创建和管理数据库。 而且,您可以直接通过MySQL客户端连接到数据库服务器,以便管理数据。

与Amazon RDS不同,RUN @ Cloud服务跨多个应用程序部署共享数据库服务器。 每个应用程序可以有自己的数据库,但不一定是专用服务器。 PaaS平台会自动部署数据库,以最大程度地利用数据库服务器池。 与RDS相比,共享数据库服务器可能会更有效地使用虚拟服务器,从而降低成本。

与其他服务整合

RUN @ Cloud提供对由其基础架构提供程序支持的平台API和服务的访问。 专门针对在Amazon EC2上部署的RUN @ Cloud应用程序,这些应用程序可以从应用程序内部完全访问所有Amazon Web服务API(例如S3,SQS和SES)。

但是RUN @ Cloud真正令人瞩目的地方是它与基于云的持续集成平台DEV @ Cloud的紧密集成。 DEV @ Cloud提供源代码,版本控制系统(Subversion和GIT); 构建库(Apache Maven); 和构建服务器(jenkins,以前称为Hudson)。 它使您可以在云中而不是在自己的计算机上运行应用程序的自动构建和测试。 敏捷软件团队广泛采用这种集中式构建系统,以确保存储库中的源代码始终经过测试且处于可发布状态。

通过将RUN @ Cloud与DEV @ Cloud集成,CloudBees提供了一套引人注目的PaaS服务,可以管理企业Java Web应用程序的整个开发,测试和部署周期。 您只需要在自己的计算机上编辑源代码,其他所有内容都可以委派给云中的自动化系统,而所需的IT开销却最小。

判决

CloudBees RUN @ Cloud是Amazon Elastic Beanstalk和RDS的低成本(甚至免费)替代产品。 它与连续构建系统的集成使其吸引了希望在开发过程中实现所有IT功能自动化的敏捷软件开发团队。

结论

经过多年的失望之后,Java PaaS服务终于到了黄金时间。 本文中回顾和比较的三种服务各有其独特的方法,因此,它们具有独特的优势和劣势。

如果您正在开发新的应用程序并且可以承受GAE的限制,那么GAE是一个绝佳的免费选择。 RUN @ Cloud和Elastic Beanstalk在应用程序级别是可互换的运行时。 标准Java EE应用程序可以在未修改的任何一个平台上运行。 RUN @ Cloud入门较便宜且易于配置,并且为持续集成的开发流程提供了出色的支持。 我建议免费开始使用RUN @ Cloud,因为如果您对CloudBees的服务不满意,可以轻松地迁移到Elastic Beanstalk。


翻译自: https://www.ibm.com/developerworks/java/library/j-paasshootout/index.html