• 1. J2EE技术平台胡晓军
  • 2. 什么是应用优化?可供程序利用的资源(内存、CPU时间、网络带宽等)是有限的,优化的目的就是让程序用尽可能少的资源完成预定的任务。 优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率。我们主要讨论的主要是如何提高代码的效率。 具体到一个特定的J2EE应用来说就是两点 在特定的硬件环境下支持尽可能多的Client 每个Client的响应时间尽可能短
  • 3. 应用性能评价通过具体使用或压力测试发现性能方面的问题,然后寻找性能瓶颈,并结合项目进度、人员安排、技术储备等因素,提出相应的优化策略 实际使用环境分析 真实 难以复制 无法事先进行 性能测试 并发测试,是一个负载测试和压力测试的过程,即逐渐增加负载,直到系 统的瓶颈或者不能接收的性能点,通过综合分析交易执行指标和资源监控指标来确定系统并发性能的过程。负载测试(Load Testing)是确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统组成部分的相应输出项,例如通过量、响应时间、CPU负载、内存使 用等来决定系统的性能。负载测试是一个分析软件应用程序和支撑架构、模拟真实环境的使用,从而来确定能够接收的性能过程。压力测试(Stress Testing)是通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大服务级别的测试。
  • 4. 并发性能测试的目的以真实的业务为依据,选择有代表性 的、关键的业务操作设计测试案例,以评价系统的当前性能 当扩展应用程序的功能或者新的应用程序将要被部署时,负载测试会帮助确定系统是否还能够处理期望 的用户负载,以预测系统的未来性能 通过模拟成百上千个用户,重复执行和运行测试,可以确认性能瓶颈并优化和调整应用,目的在于寻找到瓶颈问题
  • 5. 使用LoadRunner的并发性能测试记录一个实际业务使用过程的脚本 使用不同的参数并发执行这个脚本 分析运行结果,得出应用系统的瓶颈
  • 6. Web请求响应的分析
  • 7. J2EE应用优化的方式基于应用的优化 选择合适的应用框架 J2EE应用编程Best Practice 数据库优化 Cache管理 基于Client的代码优化 基于主机和应用服务器的优化 服务器调优 分布式应用部署
  • 8. Java技巧尽量重用对象,避免创建过多短时对象 关注内存漏洞和垃圾回收 减少大对象的复制 如用StringBuffer代替String的”+“ 减少 synchronization 如果许多类实例可以并行运行那么这就非常重要 避免过度使用诸如 Vector 和 Hashtable这样的类 实现 Externalizable ,而不是Serializable 程序员做得多,但运行是更快 对 EJB 和 RMI 很重要
  • 9. Java技巧优化大循环处的代码 慎用异常 异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为fillInStackTrace()的本地 (Native)方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM就必须调整调用堆栈,因为在处理过 程中创建了一个新的对象。 异常只能用于错误处理,不应该用来控制程序流程 尽量指定类的final修饰符 如果指定一个类为final,则该类所有的方法都是final。Java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%。
  • 10. Servlet技巧init()做尽可能多的工作 只在初始化是执行一次 尽可能少地使用 Synchronize 确保不要 synchronize 整个类 尽可能少用实例变量 将被所有在线的用户使用 不要使用SingleThreadModel 虽然是thread-safe, 但性能太差 对于非Java群体: 不要在cookies中存对象 使用 HttpSession 代替
  • 11. JSP技巧保持尽量少的Java代码 JSP中的Java代码很难维护和测试 绝对不要将业务逻辑放在JSP中 编写 helper classes 从数据生成HTML 理想情况下只使用 “<%= ... %>” tags 选择正确的包括机制 <%@ include file=“test.jsp” %>,编译时处理 ,请求时处理 前一种方法比较快一点,但包含文件经常变动就不是很合适 在每一个JSP只包含用于显示数据的简单对象 有时称之为 “view bean”, 但不用是一个真的 JavaBean 限定 JSP 只做显示工作, 抵制在其中编写的商业逻辑的诱惑 如果在页面中你要共享组件和项目, 使用如下表格 E.g. 对于菜单, 标题栏, 页脚,等等 可以使用 HTML 或者 JSP include 指令 可以包括静态 HTML, 或者其它 JSP 不要忘记在整个 JSP 中使用 try/catch 如果在 JSP 中抛出一个异常, 它不能被 servlet 捕获 作为替代, 将可能有异常的代码放在头部, 并封装在try/catch 中
  • 12. EJB技巧尽量减少使用EJB 尽量将 session bean 写成 stateless EJB container 会缓存 stateless session bean 尽可能明确删除 stateful session bean 以减少不必要的(钝化)passivation 对用户端, 不要直接存取 EJB 将它们封装在一个简单的传统的 Java 类中,用以处理诸如contexts, home and remote interfaces,等等 用基于适配器的代理 作为选择, 用JBuilder 可以向导式地创建“access beans”
  • 13. HTTP Session技巧确保放在session 中的每一个对象要实现 Serializable (or Externalizable) 不是必须的, 但在分布式应用中是一个好的方法 避免在 session 中存放大对象 手工使 session 无效,使用HttpSession.invalidate() 如果在JSP中不需要session,禁用它 <%page session=“false”%>
  • 14. JavaScript技巧如果可能,在 HTML 中尽量少用 JavaScript 使用单独的 JavaScript 文件,与 HTML 分开 可以被浏览器缓存 使 HTML 文件更小 可以被共享, 容易维护
  • 15. XML技巧不要过度使用它 分析和消息的创建非常消耗资源 (DOM trees aren’t so fun) 尽一切可能, 在系统间使用XML传递消息 没有必要在系统内使用它 只使用data objects! 尽快将XML转为 data objects 将XML中的数据转为传统的 Java 类 可以使用工具(GenX,XStream等) XML是用于传送, 不是处理!
  • 16. 数据库优化使用连接池 创建一定数量的数据库连接池,共享它们 在使用任何资源之后释放它们 PreparedStatements Statements, Connections, ResultSets… 因为“raw SQL”使用是需要重新编译,因此效率低 使用 JDBC 的 PreparedStatement 代替 Statement 如果想更快 – 尽管移植性不好 – 使用数据库的存储过程 (Stored Procedure)
  • 17. 数据库优化选择合适的第三方软件 连接池软件 商用应用服务器中的连接池 C3P0 Hibernate 使用了很多缓存,针对查询有很好的优化,对于Update操作可以结合iBatis或直接使用JDBC API操作
  • 18. 数据库连接池创建连接到数据库的若干个连接,形成一个缓冲池 应用程序从缓冲池中获取连接,使用后还给缓冲池,可以有效的降低数据库连接引起的开销 连接池的大小需要根据日常使用情况和峰值使用情况进行调优 如果没有正常释放连接到缓冲池,会造成连接泄漏 类似于内存泄漏 多次泄漏后会造成连接池耗尽,无法支持后续连接 封装连接池的使用,便于进行监控
  • 19. SQL优化SQL本身优化,这是最有效的方法,需要根据业务情况写出最优的SQL语句 合理的分表、分区策略 创建合适的Index 定时分析数据库的使用情况,优化资源占用率高的SQL,针对不同数据库可以使用一些工具软件(如针对Oracle的TOAD)
  • 20. Cache服务器Cache Web Cache 应用服务器Cache 应用Cache 可以被缓存并可以被所有用户共享 InitialContext object JNDI EJB Home interfaces 所有用户都一样 可以被单独的用户缓存 Database resultsets 例如,当你一次只显示部分数据时,缓存查询结果 可以在 servlet 中缓存, 可以在 session bean 中缓存
  • 21. 应用Cache基于HashMap或其他自定义数据结构的应用数据Cache 针对特定数据 需要通过代码控制Cache的时间,数据量等 使用成熟的Cache框架 OSCache
  • 22. OSCacheCache动态Web页面的Open Source项目(www.opensymphony.com),针对以下动态网页的特性 被处理的内容短时间不变,所以短时间内可以作为静态内容进行处理 在一个不太长的时间内,被处理的内容可能或者必定产生变化,所以必须将他们作为动态内容进行处理 在合理的时间区段内可以忽略被处理内容变化后带来的影响 对这些内容的处理动作比较消耗系统性能,影响系统响应时间 可选的缓存区 使用内存作为缓存区将可以提供更好的性能 使用硬盘作为缓存区可以在服务器重起后迅速恢复缓存内容 同时使用内存和硬盘作为缓存区则可以减少对内存的占用 灵活的缓存系统 页面 部分页面内容 高级特性 集群 主动刷新等
  • 23. OSCache使用OSCache Tag-Lib,可以设置以下属性 key scope time duration refresh mode CacheFilter过滤器,同样可以设置Cache属性 根据实际情况确定Cache属性,防止数据无法更新
  • 24. 基于Client的优化使用gzip压缩大网页,可以有效提升因网络带宽引起的性能问题,但对服务器会产生CPU的压力,需要根据主机处理能力决定是否采用。使用时通常做法是使用一个gzip的filter统一压缩 通过应用设计,减少客户端交互的数据量 提升网页设计技巧,尽量使用CSS,JavaScript等技术实现界面的梅花,减少图片的使用规模 使用局部数据刷新技术(iframe、ajax)
  • 25. 使用iframe实现局部数据在主框架增加一个iframe,可能在访问主页面的时候会增加一次访问服务器次数,但是在以后的页面访问中,服务器的负载量会减少 如果都使用同一个页面的话,那么每一个页面相同的部分会增加服务器的下载负担 总的来说使用iframe,会给服务器的负载产生一个峰值,但是以后性能会比使用同一个页面减少不少。
  • 26. AJAX技术RIA(Rich Internet Application),将GUI和基于浏览器的处理相结合,在B/S应用中 ajax flash AJAX(Asynchronous Javascript +XML) 在浏览器上通过Javascript,使用异步的XmlHttpRequest,实现无刷新的Web界面 所以AJAX并不是一个新技术,而是一些旧技术的集合 AJAX框架 BackBase Bindows Qooxdoo
  • 27. AJAX的优点减轻服务器的负担 Ajax的根本理念是“按需取数据”,所以最大可能在减少了冗余请求和响影对服务器造成的负担 无刷新更新页面,减少用户实际和心理等待时间 “按需取数据”的模式减少了数据的实际读取量 即使要读取比较大的数据,也不用像RELOAD一样出现白屏的情况,由于Ajax是用XMLHTTP发送请求得到服务端应答数据,在不重新载入整个页面的情况下用Javascript操作DOM最终更新页面的,所以在读取数据的过程中,用户所面对的也不是白屏,而是原来的页面状态(或者可以加一个LOADING的提示框让用户了解数据读取的状态),只有当接收到全部数据后才更新相应部分的内容,而这种更新也是瞬间的,用户几乎感觉不到。
  • 28. AJAX的优点更好的用户体验 可以把以前的一些服务器负担的工作转嫁到客户端,利于客户端闲置的处理能力来处理,减轻服务器和带宽的负担,节约空间和带宽租用成本 基于标准化的并被广泛支持和技术,并且不需要插件或下载小程序 Ajax使WEB中的界面与应用分离(也可以说是数据与呈现分离) AJAX的例子
  • 29. 合理使用AJAX大量使用JavaScript,引起代码的复杂化 JavaScript不是一种严谨的程序设计语言,容易产生错误,难以跟踪、调试 增加了大量的JavaScript代码,可能会造成网络流量的增加 尽量将JavaScript独立成文件 要尽可能减少AJAX调用的次数,尤其是在网络质量比较差的情况下,这样可以减少因网络连接产生的延时
  • 30. J2EE应用服务器调优这个和应用的具体情况相关,比如你的并发、应用对资源的耗用情况等等,需要反复的调优调出最适合你应用的配置: 初始配置-->系统试运行-->发现瓶颈-->调整参数                |                         |                <----------------------------- 所以你可以先设置一个初始值: Thread count:100 JVM: 1000M 不同的应用服务器调整的参数和方式各不相同,一般需要调整 内存参数 并发线程数 数据库连接池参数
  • 31. JVM尽可能使用操作系统支持的最高版本的Java虚拟机 AIX上只有1.4 根据硬件内存情况,尽可能使用最多的内存 JVM的内存参数有2G的限制 JVM进程可用2G,实际Java应用可用内存还不到2G,不同操作系统和JVM版本上不一样,在1.5G~1.7G之间 如果机器内存配置超作2G,而且CPU数量也比较多的情况下,可以考虑启动多个应用服务器实例,进行负载均衡
  • 32. 应用服务器调优(Weblogic)Java参数:修改启动文件startWebLogic.sh,加大JVM使用参数 使用产品模式 开启本地I/0,优化网络性能 调整并发线程参数 调整TCP连接参数 JDBC参数调优 在系统稳定发布运行后,调整JSP参数 设置jsp-param pageCheckSeconds=-1 设置serlet-reload-check=-1或ServletReloadCheckSecs=-1 设置jsp-param precompile=true,关闭JSP预编译选项
  • 33. J2EE应用服务器和Web服务器J2EE应用服务器 可以支持Web Client,也可以支持非Web Client J2EE应用服务器一般内置了Web服务器,用Java实现,性能不是很好 专门的Web服务器在响应基于浏览器的Client时有更好的处理能力,一般在Unix上都使用Apache作为Web服务器
  • 34. 分离静态/动态代码区分应用中的静态页面和动态页面(jsp、Servlet),分别交给2个不同的server处理 用专门的Web服务器处理静态页面 用J2EE应用服务器处理动态页面 一般由Web服务器响应客户端的请求,区分出动态页面,通过plugin转给J2EE应用服务器处理 不同的J2EE应用服务器与Web服务器的plugin方式各不相同,plugin一般由应用服务器厂商提供
  • 35. Apache+Tomcat的代码分离实现Tomcat支持AJP协议,通过一个特定的Socket端口支持应用接口调用 通过Apache的Mod JK实现Apache和Tomcat之间的连接 在httpd.conf文件中增加Mod JK的配置,如 JkMount /Servlet/* worker1 JkMount /*.jsp worker1 JkMount /*.do worker1 将需要由Tomcat提供服务器的网页路径配置在http.conf中,为了保证应用结构的正确性,将应用在Apache中的路径设置与在Tomcat中的设置保持一致
  • 36. IBM HTTP Server+WebSphere的实现IBM HTTP Server基于Apache实现 WebSphere提供了基于主流Web服务器的Plugin 在IBM HTTP Server上的配置
  • 37. 基于分布式架构的优化分布式应用部署 Session管理 数据共享
  • 38. 分布式应用的实现应用服务器集群 负载均衡 软件方式实现 硬件方式实现
  • 39. 商用J2EE应用服务器的集群版本商用J2EE应用服务器一般会有集群版本和非集群版本的区别,价格上有很大的差异 集群服务器支持各种容器在多个主机上的分布
  • 40. 负载均衡原理单台服务器的性能有限,一台普通服务器的处理能力最多只能达到每秒几万个请求,一秒钟内几十万到上百万个甚至更多的请求就需要将多台这样的服务器组成一个系统,并通过软件技术将所有请求平均分配给所有服务器,那么这个系统就完全拥有每秒钟处理足够请求的能力 最初的负载均衡技术是通过DNS轮循技术实现,通过为一个域名配置多个服务器IP 优化的负载均衡算法不仅仅是对后端服务器的轮循,还需要考虑考虑多个服务器的状态,CPU、内存及其他应用资源的负载情况,进行智能化调度,需要有一个比较复杂的程序才能完成 将这种算法固化在硬件中,一般称为四层交换机(处于7层网络协议的第四层应用) 对于实际应用服务器负载的支持,四层交换机需要针对应用进行一定的二次开发
  • 41. Apache+Tomcat的负载均衡实现同样通过Mod JK实现,在httpd.conf中增加配置文件JkWorkersFile conf/workers2.properties,该文件中包含以下内容 worker.list=loadbalancer worker.tomcat1.xxx=… worker.tomcat2.xxx=… worker.loadbalancer.type=lb worker.loadbalancer.balance_workers=tomcat1,tomcat2 worker.loadbalancer.sticky_session=true 然后将需要负载均衡的网页配置如下 JkMount /* loadbalancer
  • 42. 分布式系统下的Session管理Session复制 关键应用 系统开销很大,一般会引起30%以上的性能损失 需要集群支持,集群内服务器数量达到一定规模后,复制带来的开销会导致系统不可用 不管理Session 某个节点发生故障后,该节点提供服务的客户端请求会被分发到其他服务器,由于没有故障节点上的Session,客户端一般会要求重新登录
  • 43. 分布式环境下的文件系统数据共享单点发布应用,多机共享 共享目录存放应用 集群服务器的自动复制 任意主机上传文件,多机共享 共享目录存放文件 实现方式 采用多机共享的存储,如NAS等 某一台机器采用NFS、SAMBA等方式共享,其他机器同时连接 要求多台使用相同的目录结构
  • 44. 应用数据共享应用数据共享的需求 Session复制的替代方案 用户的数据量较大的临时数据(如电子商务网站的购物车对象) 基于数据库的共享 性能较差,不适合大量应用数据共享 基于内存数据库(In-memory Database),例如Oracle的TimesTen。内存数据库的出发点是允许数据临时地写入,但这些数据不必永久地保存到磁盘上,所有的操作都在内存中进行。这 样,内存数据库不需要复杂的算法来减少I/O操作,而且可以采用比较简单的加锁机制,因而速度很快。