摘要:本文主要介绍如何理解 Java 应用的扩展方式以及不同类型的扩展技术和具体技巧,介绍一些有关 Java 企业级应用的一般扩展策略。
老实说,“可扩展性”是个全面且详尽的话题,而且往往得不到充分理解。人们通常认为可扩展性等同于高可用性,笔者见过编程新手和架构师“老手”都建议将集群作为可扩展性和高可用性的解决方案。建议确实没错,但问题是,人们通常是通过互联网搜索,而非实际理解应用本身的情况来实现集群。
笔者并未自称“专家”,只想通过这篇文章介绍一些有关 Java 企业级应用的一般扩展策略。
问题
可扩展性并非 Java 企业级平台规范内的标准组件。相关技术通常因供应商(应用服务器)而异,并且往往需要使用不止一款产品(应用服务器本身除外)。正因如此,设计可扩展的 Java 企业级应用才会有些棘手,要完成任务,往往不仅没有可以参照的实例,而且要求我们必须彻彻底底地理解应用。
扩展类型
笔者确信你们不是第一次看到这些内容。扩展一般分为两大类:纵向扩展,和横向扩展。
扩展的第一个自然阶段是纵向扩展。
-
纵向扩展:包括给服务器增加更多资源,例如内存 (RAM)、磁盘空间、处理器等。这在某些方案中具备实用价值,但经过特定时间点后就会发现,这种扩展费用高昂,不如借助横向扩展。
-
横向扩展:在这个过程中会增加更多机器或额外的服务器实例/节点,这也叫做集群(Clustering),因为所有服务器是作为一个集体或集群一起运行的。
高可用性不等于可扩展性
系统高度可用(拥有多个服务器节点以方便故障转移),并不表示系统可扩展。高可用性只是意味着,如果当前处理节点崩溃,请求会传递或转移到集群中的另一个节点,以便从开始处继续。可扩展性则是通过增加可用资源(内存、处理器等)而提升系统特定性能(例如用户数量、吞吐量、响应时间)的能力,即使将失败请求传递到另一个节点,也无法保证应用会在这种场景中正确运行(原因我们会在下面揭晓)。
下面我们来了解一些关于可扩展性的观点和相关讨论。
让横向扩展的集群达到负载均衡
假设您已经纵向扩展至最大容量,现在又用多个节点形成集群,将系统进行了横向扩展。接下来您要做的可能是在集群基础架构前放置一台负载均衡器,让负载分散在集群各部分之间(如果要详细了解负载均衡,大家可以参考其他方面的资料,在这里我们重点还是说扩展问题)。
应用有状态还是无状态?
现在你已经横向扩展了,这就够了吗?如果你的应用无状态,即应用逻辑在处理请求时不依靠现有服务器状态,则横向扩展已经足够。
但如果应用具有 HTTP 会话对象、有状态 EJB、会话域 bean (CDI、JSF) 等组件时,又会怎样?这取决于具体客户(具体来说,即调用线程),存储特定状态并依靠当前显示的状态来执行请求(例如,HTTP 会话对象可能会存储用户的身份验证状态、购物车信息等)。
在横向扩展或集群式应用中,节点的任何集群都可能为后续请求提供服务。如果首个请求的 JVM 实例处的状态数据没有被接收,其他节点会如何处理请求?
会话保持
会话保持配置可在负载均衡器层面上完成,确保来自特定客户/终端用户的请求始终被转发到同一个实例/应用服务器节点,即维持服务器亲和力。这样,我们就缓解了所需状态无法显示的问题。但这里有个陷阱 – 如果节点崩溃怎么办?状态会被破坏,用户会被转至服务器请求处理所依赖的、但不具备现有状态的实例。
集群复制
为解决上述问题,您可对应用服务器集群机制进行配置,以支持有状态组件的复制,借此可确保 HTTP 会话数据(和其他有状态对象)显示在所有服务器实例上。如此一来,终端用户请求便可转至任何服务器节点,即使某个服务器实例崩溃或不可用,集群中的其他任何节点都能够处理请求。现在您的集群就不是一般集群了,而是复制集群。
集群复制特定于 Java 企业级容器/应用服务器,最好查阅相关文档,了解如何复制集群。一般而言,大多数应用服务都支持 Java 企业级组件(如有状态和无状态的 EJB、HTTP 会话、JMS 队列等)集群。
然而这造成了另一个问题 – 应用服务器中的每一个节点都处理会话数据,导致 JVM 堆内存越来越多,因此垃圾回收也越来越频繁,另外,复制集群时还会消耗一定的处理能力。
有状态组件的外部存储
在另一层存储会话数据和有状态的对象,这可以借助 RDBMS 实现,大多数应用服务器本身就支持这一功能。
你可能已经注意到了,我们已经将存储从内存层转移到持久层 - 一天工作结束时,你可能会遇到由数据库导致的扩展问题。不是说这一定会发生,但数据库确实可能因为应用而过载,而后逐渐延时(例如在故障转移时)。设想一下,从数据库中再现整个用户会话状态以便用在另一个集群实例中,不仅耗费大量时间,还会影响峰值负载下的终端用户体验。
最后的边界:分布式内存中缓存
这是最后的边界,至少在我看来如此,因为它把我们带回了内存方法。没有比这更好的办法了!Oracle Coherence、Hazelcast 这类产品或其他任何分布式缓存/内存网格产品可用于清理有状态的状态存储和复制/分布 - 这就是缓存层。好的一面是这些产品大多默认支持 HTTP 会话存储。
这种结构设置意味着,应用服务器的重启不会影响现有用户会话 - 给系统打补丁而不造成宕机和终端用户断电(虽然并不像听上去那么容易,但显然是个办法!),这始终是好事。总的来说,其理念是:应用层和 web 会话缓存层可独立运行和扩展,彼此不受干扰。
分布式不等于重复式
这两个词之间存在巨大差异,就缓存层而言,理解其中的差异是极为关键的。两者各有长短:
-
分布式:缓存共享数据的各个部分,即数据集被分在各缓存集群节点之间(利用与产品特定的算法)。
-
重复式:所有缓存节点都拥有所有数据,即每个缓存服务器都包含整个数据集的一份复本。
延伸阅读(主要关于 Weblogic)
- 聚类配置
- 用于会话持久性的 RDBMS 配置
- 分布式 Web 会话复制 – Oracle Coherence, Hazelcast
- 高可扩展性 – 非常好的资源!
结束语
-
高度可扩展性可能不是所有 Java 企业级应用的必要条件。但如果你打算构建互联网/面向大众的应用,将高可扩展性纳入设计因素显然非常实用。
-
对于希望充分利用自动灵活性(经济可行!)和高可用性等云平台(主要是PaaS)特点的应用而言,可扩展的设计是必要的。
-
不难发现,有状态的应用通常更难以扩展。完全「无状态」或许无法实现,但我们应当朝这方面努力。
你用哪些技巧和方法来扩展 Java 企业级应用,快来和大家分享吧。
(编译自:https://dzone.com/articles/the-basics-of-scaling-java-ee-applications)
OneAPM 为您提供端到端的 Java 应用性能解决方案,我们支持所有常见的 Java 框架及应用服务器,助您快速发现系统瓶颈,定位异常根本原因。分钟级部署,即刻体验,Java 监控从来没有如此简单。想阅读更多技术文章,请访问 OneAPM 官方技术博客。
本文转自 OneAPM 官方博客
相关推荐
【企业级应用】是IT行业中一个广泛的概念,它通常指的是那些设计用于支持大规模业务操作、具有高可用性、可扩展性和安全性的软件系统。这些应用不仅满足企业的日常运营需求,还能适应复杂的业务流程,处理海量数据,...
这些框架降低了企业级应用的复杂性,使得开发者可以更加专注于业务逻辑。 【描述】"轻量级JAVA EE企业应用实战\codes\07" 暗示了这是一个学习过程中的实践环节,特别是针对第七章的学习者。这一章可能涉及了某个...
在企业级软件开发中,J2EE(Java 2 Platform, Enterprise Edition)是一个至关重要的平台,它为构建可扩展、安全且高度分布式的企业应用程序提供了框架和API。《J2EE企业级应用测试实践》这本书深入探讨了在这个复杂...
这份文档名为《Java EE 框架整合开发入门到实战——Spring+Spring MVC+MyBatis(微课版)课后习题答案.pdf》,它...掌握这些知识点,有助于提升对Spring框架的理解和应用,为开发出高质量的企业级应用打下坚实的基础。
这种模式允许开发者独立地修改各个组件,提高了代码的可维护性和可扩展性。在MVC模式中: - **Model(模型)**:代表数据模型,负责业务逻辑和数据处理。它与数据库或其他数据存储交互,更新或获取数据。 - **View...
Struts在早期的Java EE开发中占据着重要地位,帮助开发者将业务逻辑、表示层和控制逻辑分离,提高代码的可维护性和可扩展性。Struts的核心组件包括Action、Form Beans、Tiles、Interceptor等,其中Action负责处理...
### JAVA从基础到高级 #### 1. Java的起源与发展历程 Java作为一种现代编程语言,其...通过继承前人的智慧并不断创新,Java语言成为了当今最流行的编程语言之一,广泛应用于企业级应用开发、移动应用开发等多个领域。
这些组件共同构成了一个强大的生态系统,支持从桌面应用到企业级服务的开发。 - **Java Media APIs**:用于处理音频、视频和其他媒体类型的数据流。 - **Security APIs**:提供加密、身份验证和授权等功能,增强...
Java API,JDK(Java Development Kit)和J2EE(Java 2 Platform, Enterprise Edition)是Java编程领域中的核心组成部分,对于理解Java企业级开发至关重要。让我们深入探讨这些概念及其在实际开发中的应用。 首先,...
- **面向对象:** Java完全支持面向对象编程,允许开发者创建可复用的代码块,提高了代码的可维护性和扩展性。 - **与平台无关:** Java程序编译后生成的是字节码(Bytecode),可以在任何安装了Java虚拟机(JVM)的...
在Java学习过程中,掌握Jakarta EE是非常重要的一步,因为它允许开发者创建高效、可扩展且具有高可用性的系统。 在Java EE中,核心组件包括Servlet、JSP(JavaServer Pages)、EJB(Enterprise JavaBeans)、JMS...
Spring框架是Java企业级应用开发的基石,涵盖了依赖注入(DI)、面向切面编程(AOP)、数据源管理(DataSource)等核心功能。掌握Spring框架可以帮助开发者构建模块化、易于测试和扩展的应用程序,同时也支持JPA...
总的来说,Java的学习是一个逐步深入的过程,从基础的语法和面向对象编程,到复杂的并发处理和企业级应用开发,每一步都需要扎实的理解和实践。只有这样,才能在IT行业中立足,并随着Java技术的不断发展,持续提升...
本系统采用模块化设计,易于维护和扩展,是学习Java企业级应用开发的优秀案例。 一、系统架构 1. 前端界面:通常使用JavaFX或Swing进行图形用户界面(GUI)的设计,提供友好的交互体验,包括预订、查询、修改等...
Java S2SH框架是Java开发中的经典组合,由Struts2、Hibernate4和Spring3三个组件构成,用于构建高效、可扩展的企业级应用。...通过学习和分析这个系统,开发者能够深入理解Java企业级应用开发的关键技术和最佳实践。
#### 三、应用服务器(App Server) —— 企业级Java组件的舞台 **应用服务器**是运行Java企业组件的平台,如BEA的Weblogic Server,IBM的Websphere以及开源的JBoss。其中,Weblogic因其简洁的体系结构和便捷的开发与...
在了解了进销存管理系统开发的全过程后,初学者可以更深入地理解Java在企业级应用开发中的应用,以及如何结合数据库技术来实现复杂的业务逻辑。通过阅读相关的教程和案例,初学者可以逐步掌握如何使用Java Swing进行...
企业进销存(Inventory Management System,IMS)管理系统是企业日常运营中不可或缺的一部分,它涵盖了采购、销售、库存等核心业务流程。...对于学习和理解企业级Java应用开发,这是一个非常有价值的实践案例。
Java提供了许多工具和框架,如Spring Boot、Hibernate,这些可以帮助快速构建和管理复杂的企业级应用。此外,Java的JDBC(Java Database Connectivity)接口使得与各种数据库的交互变得简单。 在压缩包的"第6章 ...
BEA公司的Weblogic Server和IBM的Websphere是目前企业级应用中的主流选择,而免费的Jboss也为开发者提供了良好的开发环境。其中,Weblogic以其清晰的体系结构和便捷的开发部署流程,成为众多Java企业软件开发者的...