一步一步理解 Java 企业级应用的可扩展性

摘要:本文主要介绍如何理解 Java 应用的扩展方式以及不一样类型的扩展技术和具体技巧,介绍一些有关 Java 企业级应用的通常扩展策略。html

老实说,“可扩展性”是个全面且详尽的话题,并且每每得不到充分理解。人们一般认为可扩展性等同于高可用性,笔者见过编程新手和架构师“老手”都建议将集群做为可扩展性和高可用性的解决方案。建议确实没错,但问题是,人们一般是经过互联网搜索,而非实际理解应用自己的状况来实现集群。java

笔者并未自称“专家”,只想经过这篇文章介绍一些有关 Java 企业级应用的通常扩展策略。web

##问题算法

可扩展性并不是 Java 企业级平台规范内的标准组件。相关技术一般因供应商(应用服务器)而异,而且每每须要使用不止一款产品(应用服务器自己除外)。正因如此,设计可扩展的 Java 企业级应用才会有些棘手,要完成任务,每每不只没有能够参照的实例,并且要求咱们必须不折不扣地理解应用。数据库

##扩展类型编程

笔者确信大家不是第一次看到这些内容。扩展通常分为两大类:纵向扩展,和横向扩展。缓存

扩展的第一个天然阶段是纵向扩展。服务器

  • 纵向扩展:包括给服务器增长更多资源,例如内存 (RAM)、磁盘空间、处理器等。这在某些方案中具有实用价值,但通过特定时间点后就会发现,这种扩展费用高昂,不如借助横向扩展。session

  • 横向扩展:在这个过程当中会增长更多机器或额外的服务器实例/节点,这也叫作集群(Clustering),由于全部服务器是做为一个集体或集群一块儿运行的。架构

##高可用性不等于可扩展性

系统高度可用(拥有多个服务器节点以方便故障转移),并不表示系统可扩展。高可用性只是意味着,若是当前处理节点崩溃,请求会传递或转移到集群中的另外一个节点,以便从开始处继续。可扩展性则是经过增长可用资源(内存、处理器等)而提高系统特定性能(例如用户数量、吞吐量、响应时间)的能力,即便将失败请求传递到另外一个节点,也没法保证应用会在这种场景中正确运行(缘由咱们会在下面揭晓)。

下面咱们来了解一些关于可扩展性的观点和相关讨论。

##让横向扩展的集群达到负载均衡

假设您已经纵向扩展至最大容量,如今又用多个节点造成集群,将系统进行了横向扩展。接下来您要作的多是在集群基础架构前放置一台负载均衡器,让负载分散在集群各部分之间(若是要详细了解负载均衡,你们能够参考其余方面的资料,在这里咱们重点仍是说扩展问题)。

一步一步理解 Java 企业级应用的可扩展性

##应用有状态仍是无状态?

如今你已经横向扩展了,这就够了吗?若是你的应用无状态,即应用逻辑在处理请求时不依靠现有服务器状态,则横向扩展已经足够。

但若是应用具备 HTTP 会话对象、有状态 EJB、会话域 bean (CDI、JSF) 等组件时,又会怎样?这取决于具体客户(具体来讲,即调用线程),存储特定状态并依靠当前显示的状态来执行请求(例如,HTTP 会话对象可能会存储用户的身份验证状态、购物车信息等)。

在横向扩展或集群式应用中,节点的任何集群均可能为后续请求提供服务。若是首个请求的 JVM 实例处的状态数据没有被接收,其余节点会如何处理请求?

一步一步理解 Java 企业级应用的可扩展性

一步一步理解 Java 企业级应用的可扩展性

会话保持

会话保持配置可在负载均衡器层面上完成,确保来自特定客户/终端用户的请求始终被转发到同一个实例/应用服务器节点,即维持服务器亲和力。这样,咱们就缓解了所需状态没法显示的问题。但这里有个陷阱 – 若是节点崩溃怎么办?状态会被破坏,用户会被转至服务器请求处理所依赖的、但不具有现有状态的实例。

一步一步理解 Java 企业级应用的可扩展性

一步一步理解 Java 企业级应用的可扩展性

##集群复制

为解决上述问题,您可对应用服务器集群机制进行配置,以支持有状态组件的复制,借此可确保 HTTP 会话数据(和其余有状态对象)显示在全部服务器实例上。如此一来,终端用户请求即可转至任何服务器节点,即便某个服务器实例崩溃或不可用,集群中的其余任何节点都可以处理请求。如今您的集群就不是通常集群了,而是复制集群。

一步一步理解 Java 企业级应用的可扩展性

集群复制特定于 Java 企业级容器/应用服务器,最好查阅相关文档,了解如何复制集群。通常而言,大多数应用服务都支持 Java 企业级组件(若有状态和无状态的 EJB、HTTP 会话、JMS 队列等)集群。

然而这形成了另外一个问题 – 应用服务器中的每个节点都处理会话数据,致使 JVM 堆内存愈来愈多,所以垃圾回收也愈来愈频繁,另外,复制集群时还会消耗必定的处理能力。

##有状态组件的外部存储

在另外一层存储会话数据和有状态的对象,这能够借助 RDBMS 实现,大多数应用服务器自己就支持这一功能。

一步一步理解 Java 企业级应用的可扩展性

你可能已经注意到了,咱们已经将存储从内存层转移到持久层 - 一天工做结束时,你可能会遇到由数据库致使的扩展问题。不是说这必定会发生,但数据库确实可能由于应用而过载,然后逐渐延时(例如在故障转移时)。设想一下,从数据库中再现整个用户会话状态以便用在另外一个集群实例中,不只耗费大量时间,还会影响峰值负载下的终端用户体验。

##最后的边界:分布式内存中缓存

这是最后的边界,至少在我看来如此,由于它把咱们带回了内存方法。没有比这更好的办法了!Oracle Coherence、Hazelcast 这类产品或其余任何分布式缓存/内存网格产品可用于清理有状态的状态存储和复制/分布 - 这就是缓存层。好的一面是这些产品大多默认支持 HTTP 会话存储。

一步一步理解 Java 企业级应用的可扩展性

这种结构设置意味着,应用服务器的重启不会影响现有用户会话 - 给系统打补丁而不形成宕机和终端用户断电(虽然并不像听上去那么容易,但显然是个办法!),这始终是好事。总的来讲,其理念是:应用层和 web 会话缓存层可独立运行和扩展,彼此不受干扰。

##分布式不等于重复式

这两个词之间存在巨大差别,就缓存层而言,理解其中的差别是极为关键的。二者各有长短:

  • 分布式:缓存共享数据的各个部分,即数据集被分在各缓存集群节点之间(利用与产品特定的算法)。

  • 重复式:全部缓存节点都拥有全部数据,即每一个缓存服务器都包含整个数据集的一份复本。

##延伸阅读(主要关于 Weblogic)

##结束语

  • 高度可扩展性可能不是全部 Java 企业级应用的必要条件。但若是你打算构建互联网/面向大众的应用,将高可扩展性归入设计因素显然很是实用。

  • 对于但愿充分利用自动灵活性(经济可行!)和高可用性等云平台(主要是PaaS)特色的应用而言,可扩展的设计是必要的。

  • 不难发现,有状态的应用一般更难以扩展。彻底「无状态」或许没法实现,但咱们应当朝这方面努力。

你用哪些技巧和方法来扩展 Java 企业级应用,快来和你们分享吧。

(编译自:https://dzone.com/articles/the-basics-of-scaling-java-ee-applications)

OneAPM 为您提供端到端的 Java 应用性能解决方案,咱们支持全部常见的 Java 框架及应用服务器,助您快速发现系统瓶颈,定位异常根本缘由。分钟级部署,即刻体验,Java 监控历来没有如此简单。想阅读更多技术文章,请访问 OneAPM 官方技术博客

本文转自 OneAPM 官方博客

相关文章
相关标签/搜索