阅读更多
原文:https://dzone.com/articles/the-basics-of-scaling-java-ee-applications

译文来自:OneAPM

摘要:本文主要介绍如何理解 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)

结束语
  • 高度可扩展性可能不是所有 Java 企业级应用的必要条件。但如果你打算构建互联网/面向大众的应用,将高可扩展性纳入设计因素显然非常实用。
  • 对于希望充分利用自动灵活性(经济可行!)和高可用性等云平台(主要是PaaS)特点的应用而言,可扩展的设计是必要的。
  • 不难发现,有状态的应用通常更难以扩展。完全「无状态」或许无法实现,但我们应当朝这方面努力。


你用哪些技巧和方法来扩展 Java 企业级应用,快来和大家分享吧。
  • 大小: 26.6 KB
  • 大小: 30.5 KB
  • 大小: 25.8 KB
  • 大小: 35.7 KB
  • 大小: 37.2 KB
  • 大小: 34.5 KB
  • 大小: 35.3 KB
来自: OneAPM
1
0
评论 共 3 条 请登录后发表评论
3 楼 kingking512 2018-06-04 13:31
内容本身不错。但这个属于“可伸缩性”的内容,“可扩展性”一般是指在对原有系统尽量少冲击/修改的情况下,能扩展系统的功能(注意,不是提升性能,是添加新功能)。
2 楼 yin_bp 2016-01-18 15:23
集群复制保持会话效率太低下,可以使用bboss会话共享框架来保持会话:

http://yin-bp.iteye.com/blog/2079685
1 楼 yin_bp 2016-01-18 15:22
集群复制保持会话效率太低下,可以使用bboss会话共享框架来保持会话:

http://yin-bp.iteye.com/blog/2079685

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • JAVA上百实例源码以及开源项目

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

  • CSS宽度计算calc()

    CSS宽度计算calc() 今天在项目过程中需要在fixed布局下自适应宽度,此时左边框是固定宽300px;右边的内容则是100%-300px;但是css中怎么写呢?通过研究发现这是css3的一个新增功能。 .admin_main{ position: fixed; top: 60px; left: 300px; width: calc(100% - 300px);...

  • 简单计算常用字符所占宽度

    var tester = document.createElement('div'); tester.style.display = 'inline-block'; tester.style.fontSize = '100px'; for(var i=33;i<127;i++) { tester.innerHTML = String.fromCharCode(i); document.bo...

  • 计算器

    计算器 Java import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Stack; import javax.swing.*; class MyException extends Exception{ public MyExc...

  • 掌握P5级Java面试技巧

    这些书籍包括了基础篇、进阶篇、架构篇的《Java项目实战—深入理解大型互联网企业通用技术》,以及《解密程序员的思维密码--沟通、演讲、思考的实践》。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够...

  • 一步一步学java(2):入门

    在揭开Java语言的神秘面纱之前,先来认识一下什么是计算机语言。 计算机语言(Computer Language)是人与计算机之间通信的语言,它主要由一些指令组成,这些指令包括数字、符号和语法等内容,程序员可以通过这些指令...

  • 10万字208道Java经典面试题总结(附答案)

    JDK(Java Development Kit),Java开发工具包 JRE(Java Runtime Environment),Java运行环境 JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,lib就是JVM工作所需要的类库。...

  • 深入理解Java虚拟机——笔记总结

    本文是作者在阅读《深入理解Java虚拟机(JVM_高级特性与最佳实践)》总结出的一些学习笔记,内容有部分来自网上,仅供参考 第一章 走近Java 1.Java技术体系 java程序设计语言、各种硬件平台上的Java虚拟机、Class文件...

  • 第二篇:企业级AI项目管理最佳实践

    关于企业级AI项目管理,随着人工智能(AI)技术的日益普及、应用场景的广泛拓展、公司对于AI产品开发过程中的管理能力要求越来越高等原因,企业在面对AI项目时的管理方式也会发生相应变化。企业需要将AI产品从开发...

  • 2022计算机Java二级考试四十五套题真题【收藏版】(一周裸考计划)

    当你看到这篇文章的时候,相信自己已经在考试的路上,或者即将踏入计算机二级考试的道路。先收藏为敬。再网上看了很多的java面试题,有很多都是零零碎碎的,有或者是需要付费加密????的,加个vip什么的,故而以下是...

  • Java面试题大全(2021版)

    为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路、方法、和手段通过计算机能够理解的形式告诉计算机,使得计算机能够根据人的指令一步一步去工作,完成某种特定的任务。这种人和计算机

  • Java基础知识面试题(2020最新版)

    文章目录Java概述何为编程什么是Javajdk1.5之后的三大版本JVM、JRE和JDK的关系什么是跨平台性?原理是什么Java语言有哪些特点什么是字节码?采用字节码的最大好处是什么什么是Java程序的主类?应用程序和小程序的...

  • 牛逼!Java 从入门到精通,超全汇总版

    Java 设计模式Java 进阶Java 并发编程实战Java 并发编程艺术Java 并发编程之美图解Java多线程设计模式JVM深入理解 Java 虚拟机Java 虚拟机规范HotSpot 实战自己动手写 Java 虚拟机MySQLMySQL 基础教程SQL 基础教程...

  • Java面试题大全(2020版)

    发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java ...

  • 2022年面试,整理全网初、中、高级常见 Java 面试题

    面试题答案见微信小程序 “Java 精选面试题”,3000 + 道面试题。内容持续更新中包含基础、集合、并发、JVM、Spring、Spring MVC、Spring Boot、Spring Cloud、Dubbo、MySQL、Redis、MyBaits、Zookeeper、Linux、...

  • 企业级大数据处理实践——基于 Apache Flink

    大数据领域正在经历一个百花齐放、...本文将从基础知识出发,通过Flink平台的实践案例,帮助读者搭建起真正可用的企业级大数据平台,并理解其内部运行机制,进而运用到实际工作场景中,有效提升公司效率和产出。

  • Java 全栈知识体系( PDF 可下载)

    40000 +字长文总结,民工哥已将此文整理成...基础知识点复习完了以后,我们需要深入的理解Java中的一些基础机制: Java 基础 - 泛型机制详解 Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本

  • java高级进阶面试题

    JVM 在执行 Java 程序的过程中会把它管理的内存分为若干个不同的区域,这些组成部 分有些是线程私有的,有些则是线程共享的 线程私有的:程序计数器,虚拟机栈,本地方法栈 线程共享的:方法区,堆 2.JVM 中是怎么...

  • 2022最新高级java面试题

    文章目录HashMap底层原理,扩容机制,加载因子为什么是0.75?并发修改异常解决办法?jdk8以后会使用红黑树优化?红黑树和二叉平衡树的区别,红黑树和B树,B+树的...应用场景有哪些?数据库事务隔离级别,数据库的四大属

Global site tag (gtag.js) - Google Analytics