ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>精品久久人人做人人爰,91精品国产综合久久福利软件 ,电影一区二区三区久久免费观看http://www.aygfsteel.com/liujw/zh-cnThu, 03 Jul 2025 16:43:36 GMTThu, 03 Jul 2025 16:43:36 GMT60IBM WebSphere 自定义门户代码的性能注意事项http://www.aygfsteel.com/liujw/archive/2006/04/04/39123.html刘军ä¼?/dc:creator>刘军ä¼?/author>Tue, 04 Apr 2006 04:44:00 GMThttp://www.aygfsteel.com/liujw/archive/2006/04/04/39123.htmlhttp://www.aygfsteel.com/liujw/comments/39123.htmlhttp://www.aygfsteel.com/liujw/archive/2006/04/04/39123.html#Feedback0http://www.aygfsteel.com/liujw/comments/commentRss/39123.htmlhttp://www.aygfsteel.com/liujw/services/trackbacks/39123.html性能通常是功能、可¾l´æŠ¤æ€§ã€ç¨‹åºæ‰§è¡Œæ—¶é—´å’Œå†…存使用间的折衷。本文档提供了一些编½E‹å¾è®®ï¼Œä»¥ä‹Éç”?IBM] WebSphere] Portal 最大限度地提高门户应用½E‹åº¾l„äšgåQˆå¦‚ Portlet、主题和外观åQ‰çš„æ€§èƒ½ã€?/blockquote>

摘自 IBM WebSphere 开发者技术期�/font>�/p>

引言

本文提供了一些常规指å¯û|¼Œä»¥åˆ›å»ø™ƒ½å¤Ÿæ­£å¸¸æ‰§è¡Œçš„ IBM WebSphere Portal 自定义代码。自定义代码不仅æŒ?PortletåQˆè™½ç„¶å®ƒä»¬æ˜¯æœ€å¸¸è§çš„é—¨æˆïL¼–½E‹æ¨¡åž‹ï¼‰åQŒä¹ŸåŒ…括 WebSphere Portal 的主题和外观代码。由于这些组件均采用ä¸?Portlet 相同的技术实玎ͼŒæ‰€ä»¥å¾ˆå¤šç›¸åŒçš„æ€§èƒ½æ³¨æ„äº‹é¡¹å¯¹å®ƒä»¬ä¹ŸåŒæ ·é€‚用ã€?/p>

对于 PortletåQŒæœ¬æ–‡ä¸»è¦é›†ä¸­è®¨è®ºéµå¾?Javaâ„?Portlet 规范 JSR 168 å?WebSphere Portal 中的对应实现的标准化 Portlet。本文基äº?WebSphere Portal V5.1 或更高版本,不过本文中所¾l™å‡ºçš„准则和大部分徏议永˜qœé€‚用åQŒè€Œä¸å—所˜qè¡Œçš?WebSphere Portal 版本的媄响ã€?/p>

本文ž®†è¯´æ˜Žå¦‚何设¾|®å’Œä½¿ç”¨ Porlet 应用½E‹åºçš„部¾|²å‚æ•îC»¥ä¼˜åŒ–门户å’?Portlet 的性能åQŒå› ä¸ø™¿™æ˜¯åˆ›å»ø™‡ªå®šä¹‰é—¨æˆ·ä»£ç çš„æœ€åŽä¸€æ­¥ã€‚不˜q?WebSphere Portal çš„æ€ÖM½“优化åQˆå³åˆ›å¾òq‰™ƒ¨¾|²è‡ªå®šä¹‰ä»£ç åŽæ‰§è¡Œçš„½Ž¡ç†æ“ä½œåQ‰å°†ä¸åœ¨æœ¬æ–‡ä¸­è®¨è®ºã€‚另一个文档对 WebSphere Portal 性能优化˜q›è¡Œäº†è¯´æ˜Žã€‚该文档与本文档共同提供了门户与性能斚w¢ä¸é”™çš„参考资料ã€?/p>

æœ¬æ–‡æ—¨åœ¨ä¾›å‚ä¸Žæž„å»ºé—¨æˆ·åº”ç”¨ç¨‹åºåÆˆå¸Œæœ›æé«˜å¯¹ä¸Žè‡ªå®šä¹‰ä»£ç ç›¸å…³çš„æ½œåœ¨æ€§èƒ½é—®é¢˜çš„ç†è§£çš„½E‹åºå‘˜ã€è®¾è®¡äh员和架构师ä‹É用ã€?br />

WebSphere Portal 环境概述

IBM WebSphere Portal 构徏äº?the IBM WebSphere Application Server 产品之上。因此,自定义门户代码的¾~–程环境å…ähœ‰ä¸‰é‡ç‰¹å¾åQŒå…¶å¯¹åº”的重要含义如下:

  • WebSphere Portal 及其所有组件均为基äº?Java 的程序ã€?/b>

    å› æ­¤åQŒæ€Èš„来说åQŒåº”该遵循编写高性能 Java 代码的最佛_®žè·üc€?/p>

  • WebSphere Portal 是运行于应用½E‹åºæœåС噍åã^åîC¸Šçš?J2EE 应用½E‹åºã€?/b>

    J2EE 包含多线½E‹æŠ€æœ¯ï¼›J2EE 容器通常采用每个è¯äh±‚一个线½E‹çš„æ–ÒŽ³•处理è¯äh±‚负荷。对于ä‹É用此机制必然涉及到的ä»ÖM½•实现或性能注意事项都应该加以注意ã€?/p>

  • WebSphere Portal 提供äº?API 以扩展门户功能ã€?/b>

    可以采用很多æ–ÒŽ³•对ä“Q务进行编½E‹ã€‚应该首先考虑影响性能的差异ã€?/p>

下一部分中将介绍一些关于门æˆïL¼–½E‹çŽ¯å¢ƒä¸åŒéƒ¨åˆ†çš„ä¸€èˆ¬æ€§èƒ½æ³¨æ„äº‹é¡¹ã€?/p>

Java

昄¡„¶åQŒæœ¬éƒ¨åˆ†òq¶ä¸ä¼šæä¾›å¤„ç?Java æ€§èƒ½çš„å…¨éƒ¨æŠ€æœ¯ã€‚æˆ‘ä»¬ä»…åœ¨æ­¤å¤„ç»™å‡ºåœ¨æˆ‘ä»¬è®¤äØ“˜q›è¡Œ WebSphere Portal 开发时最有用的相关事™å¹ï¼Œòq¶æä¾›ä¸€äº›å¯å¸®åŠ©æ·±å…¥äº†è§£ Java 性能的参考资料(请参é˜?a >参考资æ–?/font>åQ‰ã€?/p>

基本 Java 性能

在这一部分中,我们ž®†è®¨è®ÞZ¸€äº›åº”用到大部åˆ?Java 的一般性能™åV€‚å°½½Ž¡è¿™äº›å¾è®®å¯èƒ½åƈ不会带来大幅度的性能提高åQŒä½†å¯ä»¥ä½¿æ‚¨å¯¹åœ¨å¼€å‘阶ŒDµåº•层程序执行性能的重要性有所认识ã€?/p>

  • 当需要修改字½W¦ä¸²æ—Óž¼Œä½¿ç”¨ java.lang.StringBuffers 实例åQŒè€Œä¸è¦ä‹Éç”?java.lang.String 实例ã€?/b>

    åœ?Java 中,String 对象是不可变的,è€?StringBuffer 对象是可变的。无è®ÞZ½•时将文本附加åˆ?String 或从中删除,实际上都ž®†åˆ›å»ÞZ¸€ä¸ªæ–°å¯¹è±¡åQŒåƈž®†æ—§å¯¹è±¡ä¸¢å¼ƒã€‚因此我们首选以下的方式åQ?/p>
    																
    																		StringBuffer sb = new StringBuffer("Hello ");
    sb.append(var).append(" World");
    																
    														

    以此为基¼‹€çš„å­—½W¦ä¸²è”结操作åQ?/p>
    																
    																		String s = "Hello" + var + " World";
    																
    														

    有时可以通过讄¡½® StringBuffer 的初始容量进一步提高性能åQ›è¯¥¾cȝš„设计使其可以在不能保存全部数据时自动扩大定w‡ã€‚不˜q‡æ­¤å¤„有性能损失åQŒå› ä¸?StringBuffer 必须透明地增加其大小和对数据¿UÖM½ã€‚例如,如果ž®?StringBuffer ä½œäØ“æ”‰™›†å‚æ•°åQˆå³ž®†å‘其添加越来越多的数据åQ‰ä‹É用,应该在对其进行初始化之前计算恰当的缓冲区大小åQŒä»¥ä½¿å…¶æ°¸è¿œéƒ½ä¸éœ€è¦å¢žåР大ž®ã€?/p>

  • 避免在服务器端程序中˜q›è¡Œå¼€é”€å¾ˆå¤§çš?I/O 操作ã€?/b>

    åœ?I/O 操作期间臛_°‘会阻塞当前线½E‹ï¼›å¦‚果其他¾U¿ç¨‹ä¹Ÿå¿…™åȝ­‰å¾…磁盘,则系¾lŸå“åº”时间将会迅速增大。除非在执行日志记录功能åQˆä¾‹å¦‚,在记录异常或站点讉K—®ä¿¡æ¯åQ‰ï¼Œå¦åˆ™ WebSphere Portal 自己不会引è“vä»ÖM½•¼‚ç›˜è®‰K—®ã€‚我们将在后面对 I/O ˜q›è¡Œ˜q›ä¸€æ­¥è®¨è®ºã€?/p>

  • ž®½å¯èƒ½å‡ž®‘同步代码块的数量和长度ã€?/b>

    synchronized 关键字每‹Æ¡ä»…允许一个线½E‹è¿›å…¥ä»£ç å—。同步代码块所需的执行时间越长,其他¾U¿ç¨‹½{‰å¾…˜q›å…¥è¯¥ä»£ç å—的时间就­‘Šé•¿ã€‚我们将在后面对同步˜q›è¡Œ˜q›ä¸€æ­¥è®¨è®ºã€?/p>

  • 避免开销巨大的计½Ž—å’Œæ–ÒŽ³•调用ã€?/b>

    例如åQŒä‹Éç”?System.currentTimeMillis() ‹‚€ç´¢å½“前时间信息开销ž®Þq›¸å½“大。如果确实需要时间信息,è¯ïL¡®å®šæ˜¯éœ€è¦å½“前准¼‹®çš„æ—‰™—´åQŒè¿˜æ˜¯ï¼ˆä¾‹å¦‚åQ‰å‡†¼‹®åˆ°æœ€˜q‘çš„¿U’æ•°ž®Þpƒö够了。如果在代码路径中有很多获取旉™—´çš„è°ƒç”¨ï¼Œä½†åÆˆéžä¸€å®šè¦æ¯«ç§’¾U§çš„准确度,可以采用替换æ–ÒŽ³•åQŒå³¼‹®å®šè¯äh±‚开始的旉™—´åQŒç„¶åŽç›´æŽ¥åœ¨è¯äh±‚期间使用该信息ã€?/p>

  • 限制异常的ä‹É用ã€?/b>

    通常åQŒåº”ž®?Java 中的异常用于指示错误情况。不要ä‹É用异常指½Cºæ“ä½œæˆåŠŸï¼Œ˜q™ä¸»è¦æ˜¯å› äØ“ JVM 创徏异常堆栈跟踪非常è´ÒŽ—¶åQŒè€Œä¸”åœ?WebSphere Portal ¾pȝ»Ÿä¸­çš„跟踪深度会很深ã€?/p>

  • 使用 Java Reflection API æ—‰™œ€è¦è°}æ…Žã€?/b>

    æ­?API 为动态代码执行增加了功能强大的选项åQŒä½†ž®±æ–¹æ³•执行时间而言åQŒèŽ·å¾—è¿™¿Uçµ‹zÀL€§ä¼šå¯ÆD‡´ä¸¥é‡çš„æ€§èƒ½æŸå¤±ã€‚通常åQŒåº”ž®½åŠ›é¿å…åœ¨é—¨æˆ·ä»£ç ä¸­ä½¿ç”¨ Java Reflection API。不˜q‡ï¼Œå¦‚果有必要进行反ž®„调用,则应ž®½é‡ž®†å…¶æ”„¡½®åœ¨åˆå§‹æ–¹æ³•中åQŒä»¥ä½¿å…¶åœ¨æ¯ä¸ªè¯·æ±‚期间都不会执行ã€?/p>

内存使用和垃圄¡”Ÿæˆ?/b>

虽然内存对于 Java å®¢æˆ·æœø™ÊY仉™€šå¸¸ä¸æ˜¯ä¸€ä¸ªçªå‡ºçš„æ€§èƒ½é—®é¢˜åQŒä½†å¯¹äºŽ J2EE 应用½E‹åºå´æ˜¯ä¸€ä¸ªä¸»è¦é—®é¢˜ï¼Œ˜q™ä¸»è¦æ˜¯å› äؓ企业应用½E‹åºé€šå¸¸ç”±å¾ˆå¤šç”¨æˆ·åŒæ—¶è®¿é—®ã€‚äØ“äº†ä‹É应用½E‹åºæœåŠ¡å™¨é«˜æ•ˆè¿è¡Œï¼Œå¯ç”¨èµ„æºåQˆåŒ…括内存、CPU 和带宽)均由客户机的è¯äh±‚å…׃ín。我们要提到三个主要内存问题åQ?/p>

  • ž®½å¯èƒ½å‡ž®‘äÍ时对象的数量ã€?/b>

    ˜q™æ„å‘³ç€è¦å°½å¯èƒ½åœ°é‡ç”¨å¯¹è±¡ï¼Œè€Œä¸è¦å¤ªé¢‘繁地创建新对象实例。创建的对象­‘Šå¤šåQŒJVM 垃圾回收器就必须更频¾Jåœ°å›žæ”¶å†…å­˜òq¶ä¼šåQˆè‡³ž®‘éƒ¨åˆ†ï¼‰ä¸­æ–­æ­¤æ—¶çš„è¯·æ±‚å¤„ç†ã€‚åˆ›å»ø™®¸å¤šå¯¹è±¡è¿˜å®ÒŽ˜“增加堆碎片,而这会导致出现更多的垃圾回收周期。例如,不要˜q‡æ—©åˆ›å¾å¯¹è±¡åQ?/p>
    																
    																		String logData = "Parameter 1: " + param1;
    if (logger.isLogging(DEBUG)) {
    	logger.log(logData);
    }
    																
    														

    在本例中åQŒä»…在对条äšg˜q›è¡Œæ±‚å€ég¹‹åŽæ‰åº”创å»?logData。缓存和对象池技术均可以减少临时对象的创建。若要识别代码中最常导致内存分配问题的部分åQŒè¯·å‚阅工具ã€?/p>

  • ž®†å†…存永久占有的情况保持为最低ã€?/b>

    不要ž®†å¤ªå¤šä¿¡æ¯è¯»å…¥å†…存中åQ›è€Œè¦ä½¿ç”¨¾~“存保存重要的信息。有时可以针对一条信息更æ”ÒŽ•°æ®ç±»åž‹ã€‚例如,数据信息可以保存åœ?java.util.Date 对象内或 long 变量中。与基元数据¾cÕdž‹ç›¸æ¯”åQŒå¯¹è±¡é€šå¸¸æ›´å¤§åQŒå¤„理速度也会有些慢。它可能会依赖于邻近çš?API 和数据类型首选的数据¾l“构。通常åQŒå†…存占用率­‘Šé«˜åQŒå°±ä¼šå¯¼è‡´åžƒåœ‘Ö›žæ”¶çŽ‡æ›´é«˜åQŒè¯·æ±‚处理期间暂停的‹Æ¡æ•°ä¹Ÿä¼šå¢žåŠ ã€?/p>

  • ‹‚€æŸ¥åº”用程序以¼‹®å®šæ˜¯å¦å­˜åœ¨å†…存泄漏ã€?/b>

    内存泄漏通常出现åœ?Java 集合¾cÖM¸­ã€‚例如,如果有一ä¸?java.util.MapåQŒåœ¨ç‰¹å®šæƒ…况下,会将数据æ·ÕdŠ åˆ°æ˜ ž®„中åQŒä½†å´æ°¸˜qœä¸ä»Žå…¶ä¸­åˆ é™¤ã€‚å†…å­˜æ³„æ¼ä¼šå¯ÆD‡´ Java 堆保留的内存使用­‘Šæ¥­‘Šå¤§åQŒéšç€æ—‰™—´çš„增加,垃圾回收器能释放的内存会­‘Šæ¥­‘Šå°‘ã€‚è¿™æ øP¼Œä¼šå¯¼è‡´åžƒåœ‘Ö›žæ”¶æ›´é¢‘繁åQŒè€Œæœ€¾lˆå°†ä½‰K—¨æˆïL³»¾lŸåœæ­¢å“åº”。而更¾pŸç³•的是åQŒé€šå¸¸ä»…在长时间运行的‹¹‹è¯•中才能发现内存泄漏,不过可以使用各种工具帮助˜q›è¡Œæ­¤ç±»åˆ†æžåQˆè¯·å‚阅工具åQ‰ã€?/p>

性能和可扩展性代码设�/b>

设计和开发可伸羃性代码时åQŒéœ€è¦è®°ä½å¾ˆå¤šäº‹™åV€‚其中最为重要的三方面是åQšç¼“存、对象池和信息预提取åQ?/p>

  • ¾~“å­˜åQŒå­˜å‚¨å·²¾lè®¡½Ž—得到的¾l“æžœã€?/b>

    例如åQŒå¯ä»¥ä»ŽåŽç«¯¾pȝ»Ÿ‹‚€ç´¢ä¿¡æ¯ï¼Œä½†ä¸ž®†æ¯ä¸ªå¯èƒ½çš„对象均从存储区复制到内存中,而仅加蝲其中的小部分åQŒå°†å…¶æ”¾¾|®åœ¨¾~“å­˜ä¸­ã€‚è¿™æ øP¼Œè¯¥ä¿¡æ¯å°±å¯¹ç¨åŽçš„引用可用åQˆå¯èƒ½åœ¨åŽç®‹çš„另一è¯äh±‚中ä‹É用,甚至供另一个用户ä‹É用)ã€?/p>

    ¾~“存始终采用对象映射的åŞ式,å…ähœ‰å¤§å°ä¸Šé™ã€‚缓存还必须知道不可能再‹Æ¡è¯·æ±‚某个内容的情况åQŒä»¥ä¾¿åœ¨åˆé€‚时从缓存中ž®†å…¶åˆ é™¤ã€‚è¿™¿UæŽ’除操作通常由“生存时间â€?TTL) 或“最˜q‘最ž®‘ä‹É用”算法确定。而且使用¾~“存的客æˆähœºä¸èƒ½ä¿è¯ž®†æˆåŠŸä»Ž¾~“å­˜‹‚€ç´¢å¯¹è±¡ï¼›å¿…须首先‹‚€æŸ¥å¯¹è±¡æ˜¯å¦å­˜åœ¨ï¼Œå¦‚果没有扑ֈ°åQŒåˆ™ž®†åˆ›å»ø™¯¥å¯¹è±¡åQ?/p>
    																		
    																				Mail mail = myCache.get("myMail");
    if (mail == null) {
    	mail = readMailInformation();
    	myCache.put("myMail", mail) ;
    }
    ...
    																		
    																

    åQˆåœ¨æŸäº›æƒ…况下,特定于应用程序的¾~“存可以设计ä¸ÞZ»Žå¯¹å®¢æˆähœºé€æ˜Žçš„æŸä¸ªæ•°æ®æºæŸ¥æ‰¾æ‰€éœ€çš„æ•°æ®ã€‚)

  • 使用对象池限制特定类的实例的数量ã€?/b>

    每个è¯äh±‚都需要特定类的实例,但此对象òq¶ä¸åQˆä¹Ÿä¸åº”åQ‰éœ€è¦åœ¨æ¯ä¸ªè¯äh±‚中重新创建。在对象创徏和初始化开销很大的情况下åQŒå°¤å…¶æ˜¯˜q™æ ·ã€‚客æˆähœºå¯ä»¥ä¸æŽ¥å—性能命中åQŒè€Œä»Žæ± ä¸­è¯äh±‚对象åQŒç„¶åŽåœ¨ç”¨å®Œä¹‹åŽž®†å…¶˜q”回池中ã€?/p>
    																		
    																				PooledObject po = myPool.get();
    ...
    // use the PooledObject 
    ...
    myPool.put(po);
    																		
    																

  • 对象池的一¿Uç®€å•åŞ式就是将对象规范化ã€?/b>

    ˜q™æ„å‘³ç€å¯¹è±¡çš„æ‰€æœ‰ä¸åŒå®žä¾‹åœ¨½E‹åºåˆå§‹åŒ–阶ŒDµåˆ›å»ºï¼Œž®†åœ¨éšåŽé‡ç”¨å’Œå¼•用。java.lang.Boolean ¾cÕd°±æ˜¯å·²è§„范化对象的例子。只需要有两种不同çš?Boolean 对象卛_¯åQˆæœ€å¥½èƒ½ä½œäؓ常数讉K—®åQ‰ã€‚åŒæ øP¼Œä¹Ÿå¯ä½¿å…¶ä»–对象ä‹É用一¾l„固定的只读内部状态ã€?/p>

  • 只提取当前希望处理的数据åQŒè€Œä¸æå–多余的数据ã€?/b>

    例如åQŒåœ¨ Portlet 中,可以提供一个电子邮件列表;è¯?Porlet ž®†æ˜¾½CÞZ¸»é¢˜ã€æ—¥æœŸã€å‘ä»¶äh和其他重要信息。当用户选择了特定的电子邮äšgæ—Óž¼Œž®†æ˜¾½Cø™¯¥é‚®äšg的正文。在ä»?Porlet 中选择特定的项之前åQŒä¸éœ€è¦æ­£æ–‡ï¼Œå› æ­¤æå‰‹‚€ç´¢æ­£æ–‡å°†‹¹ªè´¹æ‰§è¡Œæ—‰™—´å’Œå†…存资源。这¿Uæ¨¡å¼åœ¨å¾ˆå¤šæƒ…况下都适用。æ€Èš„原则是,仅计½Ž—å’Œ‹‚€ç´¢å¯¹äºŽå½“前请求和响应有直接意义的信息ã€?/p>

J2EE

IBM WebSphere Application Server æ˜?J2EE 实现åQŒWebSphere Portal ž®±æž„å»ÞZºŽå…¶ä¸Šã€‚由于本部分中很多性能注意事项适用äº?J2EE ˜qè¡Œæ—¶ä¸Šä¸‹æ–‡åQŒæ‰€ä»¥å…¶ä¸­çš„很多信息除了适用äº?WebSphere Application Server 之外åQŒä¹Ÿé€‚用于其他应用程序服务器å’?J2EE 应用½E‹åºã€‚下面所列出的项目在此处只进行了½Ž€å•概˜qŽÍ¼Œž®†åœ¨åŽé¢˜q›è¡Œæ›´äؓ详细的说明。有å…Ïx›´å¤šçš„一般性讨论,请参é˜?a >参考资æ–?/font>ã€?/p>

J2EE 标准

J2EE 标准规范包含了大量与性能相关的事™å¹ï¼š

  • 应当使用初始æ–ÒŽ³•计算所有后面将用到且不会发生更改的内容åQˆå¾ˆå¤?J2EE 资源都可以ä‹É用初始方法,Portlet 也可以ä‹É用此¾cÀL–¹æ³•)。例如,数据源等普通资源的 JNDI ½E‹åºåº”该仅在初始化时执行一‹Æ¡ã€‚此外,也应该仅åœ?Portlet 初始化期间读取一‹Æ¡æ¥è‡ªç‰¹å®šåªè¯ÀL–‡ä»¶çš„æ•°æ®ã€‚可以对 Portlet 服务æ–ÒŽ³•˜q›è¡Œæ‰«æåQŒä»¥å‘现所有对每个è¯äh±‚执行相同操作的代码,ž®†å…¶¿UÕdŠ¨åˆ°åˆå§‹æ–¹æ³•ä¸­åQŒä»¥é™ä½Žè¯¥æœåŠ¡æ–¹æ³•çš„˜qè¡Œæ—¶å¼€é”€ã€?/p>

  • EJB 和会话是 J2EE 中非帔R‡è¦ä¸”功能强大的概念,但如果ä‹Éç”¨ä¸å½“ï¼ŒäºŒè€…å‡å¯èƒ½å¯ÆD‡´æ€§èƒ½æŸå¤±ã€‚例如,应用½E‹åºä¸åº”ž®†è¿‡å¤šçš„æ•°æ®æ”„¡½®åˆîC¼šè¯ä¸­åQŒä»Žè€Œå‡ž®‘æœåŠ¡å™¨çš„å†…å­˜å ç”¨åÆˆæ›´å¿«é€Ÿæ–¹ä¾¿åœ°ä¿æŒä¼šè¯ã€‚å…³äº?EJB ¾l„äšgåQŒåº”该熟悉与˜qœç¨‹è°ƒç”¨å’Œæœ¬åœ°è°ƒç”¨ç­‰ç›¸å…³çš„不同持久类型。EJB 可以使用的某些功能会带来大的性能损失ã€?/p>

WebSphere Application Server

WebSphere Application Server 产品提供了各¿UåŠŸèƒ½ï¼Œä»¥å¸®åŠ©å¼€å‘äh员和架构师设计高性能¾pȝ»Ÿã€‚(请参é˜?a >参考资æ–?/font>中给出的 WebSphere Application Server 信息中心å’?WebSphere Business Integration Server Foundation 信息中心åQ‰ã€?/p>

  • 正如前面所提到的,创徏数据库连接的开销非常大。按ç…?J2EE 标准中的定义åQŒåº”用程序服务器可以提供˜qžæŽ¥æ± æœºåˆÓž¼Œä»Žè€Œæ— éœ€ä¸ºæ¯ä¸ªä¼ å…¥è¯·æ±‚é‡æ–°åˆ›å»ø™¿žæŽ¥ã€‚WebSphere Application Server 使用一些额外的性能 Helper 提供˜q™æ ·çš„连接池机制åQŒç›¸å½“于频繁执行çš?SQL 语句的语句缓存。不˜q‡ï¼Œå¦‚果完成数据库交互后没有及时˜q”回˜qžæŽ¥åQŒå°†å›žå¯¼è‡´ç›¸å½“é•¿æ—‰™—´å†…连接对其他è¯äh±‚不可用。通过使用 WebSphere Application Server ½Ž¡ç†æŽ§åˆ¶åŽÍ¼Œå¯ä»¥ž®†è¿žæŽ¥æ± ä½œäØ“ JDBC 数据库的数据源属性进行控åˆÓž¼Œòq¶èƒ½˜q›è¡Œå®šä¹‰åQŒä¾‹å¦‚可以定义连接池中的最ž®‘连接数和最大连接数。(请参é˜?WebSphere Application Server 信息中心以了解详¾l†ä¿¡æ¯ã€‚)

    下面所¾l™çš„½CÞZ¾‹æ¼”示了多个请求对˜qžæŽ¥˜q›è¡Œé‡ç”¨ã€‚在本例中,可以使用 JDBC ˜qžæŽ¥æ± å’Œåˆ©ç”¨ Application Server 提供的语句缓存:

    . . . 
    public class IDontCare extends GenericPortlet {
          
       private javax.sql.DataSource ds;
       
       public void init() throws javax.portlet.PortletException {
          
          try {
             Hashtable env = new Hashtable();
             env.put( Context.INITIAL_CONTEXT_FACTORY,
                "com.ibm.ejs.ns.jndi.CNInitialContextFactory" );
             Context ctx = new InitialContext( env );
             ds = (javax.sql.DataSource)ctx.lookup( "jdbc/MYSHOES" );
             ctx.close();
          } catch (Exception any) {
             // handle exceptions here
             . . . 
          }
       }
    
       . . . 
       public void processAction ( 
          ActionRequest request, 
          ActionResponse response
       ) throws PortletException, IOException {
          . . . 
          try {
             Connection con = null;
             ResultSet rs = null;
             PreparedStatement pStmt = null;
             con = ds.getConnection ( dbuser, dbpasswd );
             pStmt = con.prepareStatement(
                "select * from myscheme.size_of_shoes");
             rs = pStmt.executeQuery(); 
             . . . 
    
             // release the resource when it is no longer used
             if (pStmt != null) pStmt.close();
             if (con   != null) con.close();
          } catch (Exception any) {
             // handle exception here
             . . . 
          } 
       }
    }

  • WebSphere Application Server ˜q˜æ”¯æŒå¯¹è±¡æ± çš„常规概念,每个对象池均å…ähœ‰æ± ç®¡ç†å™¨åQŒä»Žè€Œäؓ不同¾cȝ±»åž‹æä¾›å¯¹è±¡æ± è®‰K—®ã€‚可以查询此¾cÕd¯¹è±¡æ± ä»¥èŽ·å¾—ç±»¾cÕdž‹å®žä¾‹åQŒå¦‚前面关于池技术的½CÞZ¾‹ä¸­æ‰€˜q°ã€‚请参阅 WebSphere Business Integrator Server Foundation 信息中心以获得详¾l†ä¿¡æ¯ã€?/p>

  • WebSphere Application Server ˜q˜æä¾›äº†â€œä¸€èˆ¬ç”¨é€””的¾~“存。在½Ž¡ç†æŽ§åˆ¶åîC¸­åQŒå¯ä»¥å®šä¹‰ç¼“存实例,应用½E‹åºå¯ä»¥ä½¿ç”¨˜q™äº›¾~“存实例存储、检索和å…׃ín数据。与¾~ºçœå…׃ín动态缓存(门户使用其缓存对象)不同åQŒç¼“存实例仅可由知道å…?JNDI 名称的应用程序访问。DistributedMap ¾cÀL˜¯åº”用½E‹åºæ‰€ä½¿ç”¨çš„ç¼–½E‹æŽ¥å£ï¼Œè¯¥ç±»å…è®¸åº”用½E‹åºä»Žç¼“存实例获得对象和ž®†å¯¹è±¡æ”¾¾|®åˆ°å…¶ä¸­åQŒåƈ可以使其失效。请参阅 WebSphere Business Integrator Server Foundation 信息中心以获得详¾l†ä¿¡æ?[8] (LINK)ã€?/p>

    如果 Portlet 使用¾~“存实现åQŒå®ƒä»¬åº”该在其初始阶ŒD‰|Ÿ¥æ‰¾æˆ–实例化一个缓存实例,òq¶ä¿æŒè¯¥¾~“存的引用,以ä‹É¾~“存条目å…ähœ‰å¯èƒ½æ¯”单个请求长的生存期。在处理 Portlet 的操作和呈现阶段æ—Óž¼Œå¯ä»¥ž®†æ¡ç›®æ”¾¾|®åˆ°¾~“存中,òq¶ä»Žä¸­è¿›è¡Œæ£€ç´¢ã€‚Portlet 实现需要确保如果ä‹É用特定键查询æ—Óž¼Œ¾~“存没有˜q”回数据åQŒåº”有适当的后端访问和¾~“å­˜˜q›è¡Œæ›´æ–°å¤„理。另外,˜q˜è¦æ³¨æ„åQŒäؓ了实现设计的特定功能åQŒå¯èƒ½éœ€è¦é™å®šé”®åœ¨ç¼“存中的范å›ß_¼ˆå¦‚,åŸÞZºŽç”¨æˆ·ä¼šè¯åQ‰ã€‚ç¼“å­˜é€šå¸¸ä¸ø™‡ªæˆ‘管理的单元åQŒæ ¹æ®ç¼“存实玎ͼŒå¯ä»¥æŽ’除条目或ä‹É其失效。请注意åQŒå‡ºäºŽåŒæ ïLš„原因åQŒç¼“å­˜åÆˆä¸é€‚åˆåœ¨å¤šŒDµä»£ç é—´˜q›è¡Œä¿¡æ¯é€šä¿¡ã€‚缓存还应该¾l´æŠ¤ä¸€ä¸ªåˆç†çš„大小上限åQŒä»¥é¿å…è‡ªå®šä¹‰ä»£ç ä¸­å†…存的过度ä‹É用ã€?/p>

门户 API

WebSphere Portal 支持两种不同çš?Portlet APIåQ?/p>

  • IBM Portlet APIåQŒè¯¥ API å¯?Servlet ˜q›è¡Œæ‰©å±•ã€?
  • JSR 168 Portlet APIåQŒè¯¥ API ç”?Java Community Process (JCP) 定义ã€?

在本文中åQŒæˆ‘们将重点讨论 JSR 168 Portlet APIã€?/p>

WebSphere Portal 提供了各¿UæŽ¥å£ï¼Œç”¨äºŽž®?Portlet 集成åˆ?WebSphere Portal 环境中。因此,应该谨慎设计 PortletåQŒä»¥å……分利用各种门户功能。请¼‹®ä¿é‡‡ç”¨æœ€ä½›_®žè·µï¼ˆè¯·å‚é˜?a >参考资æ–?/font>中列出的最佛_®žè·µï¼‰åQŒä»¥åº”用恰当çš?WebSphere Portal APIã€?br />

常见的实现注意事™å?/font>

在本部分中,我们ž®†è®¨è®ÞZ¸Žä¸»é¢˜å’Œå¤–è§‚ç¼–½E‹ä»¥å?Portlet 开发相关的性能主题ã€?/p>

JSP

JavaServer Page (JSP) æ˜?Portlet ¾~–程的基¼‹€ä¹‹ä¸€ã€‚在大多æ•?Portlet 中,JSP 通过使用 Model View Controller (MVC) ä½œäØ“è§†å›¾¾l„äšg使用。JSP ç”?HTMLåQˆæˆ–其他标记语言åQ‰ç»„合和 Java 代码¾l„成åQ›åœ¨å¤§å¤šæ•?HTML 中,它们的处理输å‡ÞZ¹Ÿæ˜¯æ ‡è®°è¯­­a€ã€‚其最½Ž€å•的形式中,JSP 不包含ä“Qä½?Java 代码åQŒä½†ä»…包含自定义标记åQŒè°ƒç”¨è¿™äº›æ ‡è®îC»¥æ‰§è¡Œé?HTML 操作。(相反圎ͼŒJSP æ–‡äšg中也可能不包含ä“Qä½?HTML 内容åQ‰ã€?/p>

  • 在第一‹Æ¡è®¿é—?JSP æ–‡äšgæ—Óž¼Œž®†å¯¹æ–‡äšg˜q›è¡Œåˆ†æžåQŒå°†å…¶è{æ¢äØ“å¸¸è§„ Java Servlet 源文ä»Óž¼Œè¯¥æºæ–‡äšgž®†éšåŽç¼–è¯‘äØ“å­—èŠ‚ä»£ç ã€‚å› æ­¤ï¼Œç”׃ºŽåŽç®‹çš„两‹Æ¡è{换(ä»?JSP åˆ?Java 源再到字节代码)åQŒç¬¬ä¸€‹Æ¡è¯·æ±?æ—‰™€šå¸¸æ¯”较¾~“æ…¢åQŒä½†å¯¹äºŽä¹‹åŽçš„æ‰€æœ‰è¯·æ±‚,JSP ž®†åŒä»ÖM½•å…¶ä»– Servlet 一样工作ã€?

    ˜q™ä¸Žå…¶ä»–生成 HTML 内容的方法(XML å’?XSLTåQ‰ä¸ä¸€æ —÷€‚ä‹É用其他方法时åQŒå¯¹äºŽæ¯‹Æ¡è¯·æ±‚都必须解析 XML 和应用样式表转换。只有很好地¾~“存了结果而不需每次è¯äh±‚都重新运行è{换,才能保证性能。因此,从性能的角度出发,JSP 应该优于 XML/XSLT。此外,门户基础设施˜q˜é’ˆå¯?JSP ˜q›è¡Œäº†ä¼˜åŒ–,允许方便地扩展以支持其他标记、语­a€å’Œæµè§ˆå™¨ã€?/p>

  • 应用½E‹åºæœåŠ¡å™¨æ‰§è¡?JSP 的方式与执行常规 Servlet ¾cÖM¼¼ã€‚不˜q‡ï¼ŒJSP ¾~–译产生çš?Servlet 包含生成的代码,˜q™äº›ä»£ç çš„æ€§èƒ½ä¼˜åŒ–½E‹åº¦½Eé€ŠäºŽæ‰‹åЍ¾~–写的代码。如果性能对于特定 JSP 非常重要åQŒè€Œä‹É用生成的代码又不能达到目的,误‚€ƒè™‘手动ž®†æ ‡è®°ç¼–写到输出‹¹ä¸­ã€?/p>

  • JSP 中的 Java 代码片断¿UîCØ“ Scriptlet。由äº?JSP ž®†è{æ¢äØ“ Java 源代码,因此使用 Scriptilet òq¶æ²¡æœ‰çœŸæ­£çš„æ€§èƒ½æŸå¤±ã€‚WebSphere Application Server 的最新版本中的某些优化将åœ?JSP æ–‡äšg不包含ä“Qä½?Scriptlet 的情况下应用。通常åQŒä¸åº”å°† Scriptlet 代码攄¡½®åˆ?JSP 中,而应使用标记完成˜q™äº›ä»ÕdŠ¡ã€?/p>

  • JSP 中可以包含其ä»?JSP。这意味着单个 JSP 不必对请求作出全部响应;可以ž®†å“åº”æ‹†åˆ†äØ“å¤šä¸ª JSPåQŒåœ¨çˆ?JSP 中包括其ä»?JSP。有两种包含方式åQŒé™æ€åŒ…含和动态包含:

    • 静æ€?JSP 包含在编译时解析。JSP ¾~–译器会包含所引用的文ä»Óž¼Œè€Œä¸åŒ…含 include 语句。此选项通常非常快,完全不会增加˜qè¡Œæ—¶å¼€é”€ã€?/p>
      																						
      																								<%@ include file="include2.jsp" %>
      																						
      																				

    • 动æ€?JSP 包含在运行时解析åQŒå¼€é”€òq¶ä¸ž®ã€‚就垃圾生成和执行时间而言åQŒè§£æžè¦è°ƒåº¦çš„æ­£¼‹?JSP 开销非常大。例如(åœ?JSP 中)åQ?/p>
      																						
      																								<jsp:include page="include2.jsp" flush="true" %>
      																						
      																				

      JSP 中的动态包含在通过 Servlet 代码包含其他文äšgæ—¶ä‹É用如下语句:

      																						
      																								javax.servlet.RequestDispatcher 
      																						
      																				

      å› æ­¤åQŒåªè¦æœ‰å¯èƒ½åQŒåº”该尽量ä‹É用静态包含。动态包含提供了最高的灉|´»æ€§ï¼Œä½†å¦‚æžœä‹É用过于频¾Jï¼Œä¼šå¸¦æ¥å·¨å¤§çš„æ€§èƒ½å¼€é”€ã€?/p>

EJB 用法

Enterprise JavaBean (EJB) 定义了一个基于组件的体系¾l“æž„åQŒç”¨äºŽæž„建可扩展的分布式多用户业务应用程序。EJB ¾l„äšg设计用于ž®è£…业务逻辑åQŒåƈ同时ž®†æ‰€æœ‰çš„复杂性隐藏在 Bean 和内¾|?EJB 容器服务后ã€?/p>

对企业应用程序频¾Jä‹É用的各种功能的支持会带来一定的性能开销åQŒåœ¨ä½¿ç”¨ EJB æ—‰™œ€è¦åŠ ä»¥è€ƒè™‘ã€?/p>

  • Portlet 可以通过 JNDI 查询包含 EJB 引用åQŒè€?JNDI 查询在性能斚w¢å¼€é”€å¾ˆå¤§ã€‚例如,如果 Portlet òq¶ä¸¾~“å­˜å¯?EJB ä¸ÀLŽ¥å£çš„å¼•ç”¨åQŒåˆ™æ¯ä¸ªå¯?EJB 的逻辑引用需要两‹Æ¡è¿œ½E‹è°ƒç”¨ï¼šä¸€ä¸ªè°ƒç”¨å‘½åæœåŠ¡ï¼Œå¦ä¸€ä¸ªè°ƒç”¨å®žé™…çš„å¯¹è±¡ã€‚äØ“äº†æ”¹˜q›è¿™¿Uæƒ…况,请ä‹É用缓存技术以减少或消除对 EJB ä¸Õd¼•用的重复查询ã€?/p>

  • EJB ¾l„äšgž®†å…¬å¼€˜qœç¨‹æŽ¥å£å’Œæœ¬åœ°æŽ¥å£ã€‚依赖于位置çš?EJB ž®†ä‹É用远½E‹æŽ¥å£ã€‚方法参数和˜q”回值将åœ?RMI-IIOP 上序列化åQŒåÆˆç”±å€ÆD¿”回。远½E‹æ–¹æ³•å¿…™å»è®¾è®¡äؓ能够æ ÒŽ® API çš„ä‹É用模式满­‘Ïx•°æ®éœ€æ±‚。请使用 API 中的适合接口的ä‹É用情å†ëŠš„æ–ÒŽ³•和数据类型粒度,以尽可能减少序列化开销ã€?

  • ž®½å¯èƒ½å‡ž®‘远½E‹è°ƒç”¨çš„æ•°é‡åQŒä»¥å‡å°‘ç”׃ºŽä»£ç è·¯å¾„中的˜qœç¨‹è°ƒç”¨å¸¦æ¥çš„ç³»¾lŸå¼€é”€ã€‚ä‹É用会è¯?Bean ä½œäØ“˜qœç¨‹å¤–观使用åQŒå¯¹å¤æ‚交互˜q›è¡ŒåŒ…装åQŒåƈ减少 Portlet 和域对象间的˜qœç¨‹è°ƒç”¨ã€‚直接访问远½E‹å®žä½?Bean çš?Portlet 通常会导致多个远½E‹æ–¹æ³•调用。如果在此环境中使用实体 BeanåQŒè¯·é¿å…¾l™äºˆå…¶è¿œ½E‹æŽ¥å£ã€‚作为外观的会话 Bean ž®†é€šè¿‡å…¶æœ¬åœ°æŽ¥å£è®¿é—®å®žä½?BeanåQŒä»Žå…¶æ”¶é›†æ•°æ®ï¼Œç„¶åŽž®†æ­¤ä¿¡æ¯˜q”回发出调用的应用程序ã€?/p>

    å½“å‘å‡ø™°ƒç”¨çš„客户机(如会话外观)与被调用çš?EJB å…׃ín同一个容器时åQŒæœ¬åœ°æŽ¥å£çš„æ¦‚念ž®†ä¼šæœ‰æ•ˆæžœã€‚ä‹É用本地接口可以消除分布式对象协议的系¾lŸå¼€é”€åQŒä»Žè€Œé™ä½Žè¿›½E‹é—´é€šä¿¡å¼€é”€ã€‚æœ¬åœ°è°ƒç”¨åÆˆä¸ä¼šé€šè¿‡é€šä¿¡å±‚ï¼Œæ‰€æœ‰å¯¹è±¡å‡å¯ä»¥é€šè¿‡å¼•ç”¨ä¼ é€’ã€?/p>

  • EJB 容器支持的事务管理也可以影响性能。开发了 EJB 后,½E‹åºå‘˜å¿…™å»è®¾¾|®å®šä¹‰å„¿Uç‰¹å¾ï¼ˆå¦?EJB 的事务支持和隔离¾U§åˆ«åQ‰çš„部çÖv描述½W¦ã€‚如果不需要事务,请将事务¾cÕdž‹è®„¡½®ä¸?NotSupportedã€?/p>

  • 事务隔离¾U§åˆ«æ˜¯åŸº¼‹€æ•°æ®åº“将已更改但ž®šæœªæäº¤çš„æ•°æ®å‘å…¶ä»–äº‹åŠ¡å…¬å¼€çš„ç¨‹åº¦ã€‚äØ“äº†èŽ·å¾—æœ€ä½³çš„æ€§èƒ½åQŒè¯·ä½¿ç”¨è‡ªç”±éš”离¾U§åˆ«ã€‚不˜q‡ï¼Œè®©å…¶äº‹åŠ¡çœ‹åˆ°æœªæäº¤çš„æ•°æ®å¯ä»¥å¸¦æ¥æ„æ–™ä¹‹å¤–çš„å‰¯ä½œç”¨åQŒå¦‚更新冲突和读取不一致等。有兛_¦‚何设¾|®éš”¼›Èñ”别的说明åQŒè¯·å‚阅 WebSphere Application Server V5.1.x 信息中心ã€?/p>

请参é˜?IBM 白皮ä¹?WebSphere Application Server Development 性能和扩展性最佛_®žè·?/font>å’?IBM ¾U¢çš®ä¹?IBM WebSphere V5.1 性能、扩展性和高可用æ€?WebSphere 手册¾pÕdˆ—åQŒä»¥è޷得其他廸™®®ä»¥åŠå…³äºŽæ¯ä¸ªå»ø™®®çš„相关理由ã€?/p>

标记大小

标记大小指从门户服务器传输到客户机的完全呈现门户™åµé¢çš„字节数量。从门户服务器的角度来看åQŒæœ€é‡è¦çš„部分是包含¾l“果标记çš?HTML ™åµé¢çš„大ž®ã€‚也必须ž®†å…¶ä»–æ–‡ä»Óž¼ˆå¦‚样式表、图像或 JavaScriptåQ‰ä¼ è¾“到客户机。由于静态文仉™€šå¸¸ä¿å­˜åœ?HTTP 服务器或代理¾~“存上的门户¾pȝ»Ÿä¹‹å¤–åQŒæ‰€ä»¥ï¼Œæ­¤å¤„我们ž®†ä¸»è¦è®¨è®ºâ€œçœŸæ­£çš„”HTML 标记大小ã€?/p>

到底å‡ÞZºŽä»€ä¹ˆåŽŸå› éžå¾—å…³æ³¨æ ‡è®°å¤§ž®å‘¢åQŸåœ¨å…¬å¸çš„内部网内,¾|‘络带宽的问题可能会ž®‘一些,但如果用户通过调制解调器或其他低带宽网¾lœè¿žæŽ¥åˆ°é—¨æˆ·åQŒå¤§åž?HTML 响应很长的下载时间可能会令äh非常受不了ã€?/p>

让我们进行一个简单的计算。假设服务器或集¾Ÿ¤æ¯¿U’钟最多能处理 100 个请求。HTML ™åµé¢å¤§å°åº”该ä¸?100KBåQŒè¿™ä¸ªå€ÆD™½ç„¶çœ‹ç€å¾ˆå¤§åQŒä½†å¦‚果在页面上有复杂的主题和若òq²ä¸ª PortletåQŒå°±å¾ˆå®¹æ˜“达到这个大ž®ã€‚对于服务器åQŒè¿™æ„å‘³ç€å¿…须提供¾U?10MB/sec 的速度åQ?00 KB * 100 ™åµé¢/¿U’)。而这个值是 100MB 的网¾lœå¯ä»¥å¤„理的最大通信‹¹é‡ã€‚(以太¾|‘不可能癑ֈ†ä¹‹ç™¾åœ°æ”¯æŒå…¶ 100MB/sec 的速度åQŒä¸”传入通信‹¹é‡ä¹Ÿä¸å®¹å¿½è§†ã€‚对于通过 56K è°ƒåˆ¶è§£è°ƒå™¨è¿žæŽ¥åˆ°é—¨æˆ·çš„ç”¨æˆøP¼Œæ¯ä¸ª™åµé¢çš„下载时间应åœ?15 ¿U’的旉™—´èŒƒå›´å†…!åQ?/p>

多大能称为太大?˜q™ä¸ªé—®é¢˜é€šå¸¸å¾ˆéš¾å›žç­”。不˜q‡ï¼Œæ¯ä¸ª HTML ™åµé¢çš„大ž®è¶…˜q?100KB 可能ž®±å¤ªå¤§äº†ã€‚另外,˜q˜è¦è®îC½åQŒè¾ƒž®çš„讑֤‡å¯¹å…¶å¯ä»¥å¤„理的每个请求的标记大小有一定的限制ã€?/p>

构成标记大小的主要内å®ÒŽ˜¯ä¸»é¢˜å’?Portlet 输出。由于所有门æˆ?JSP 均可自定义,所以可以改变标记的在终端的紧凑½E‹åº¦ã€‚要限制标记大小åQŒå¯ä»¥é‡‡å–以下措施:

  • åœ?JSP 中ä‹Éç”?JSP 注释åQŒè€Œä¸æ˜?HTML 注释ã€?/b>

    JSP ¾~–译器将删除½H—体注释 <%-- ... --%>åQŒè€Œä¿ç•™çª—体注é‡?<!-- ... -->òq¶å°†å…‰™€šè¿‡¾|‘络传输ã€?/p>

  • ž®½é‡å‡å°‘ JSP 源文件中的空白、制表符和分行符åQŒå› ä¸?JSP ¾~–译器将会保留这些内宏V€?/b>

    ˜q™å¯èƒ½ä¼šé™ä½Žä»£ç çš„可è¯ÀL€§ã€‚这些内容可以帮助开发布局良好的代码,但在 JSP æ–‡äšg应用到生产环境前åQŒå°†ä½¿ç”¨å·¥å…·å¯¹å…¶˜q›è¡Œå¤„理åQŒé™¤åŽÕd…¶æ ¼å¼è®„¡½®ã€?/p>

  • ž®½é‡é¿å…å¤šæ¬¡å‘客æˆähœºå‘送相同的信息ã€?/b>

    例如åQŒæ ·å¼å®šä¹‰åº”当放入独立的 CSS æ–‡äšg中。JavaScript 代码也应如此。而且åQŒç”±äºŽè¿™äº›ç‹¬ç«‹çš„æ–‡äšg通常不会更改åQŒå› æ­¤å¯ä»¥å°†å…¶ç¼“存在‹¹è§ˆå™¨æˆ–代理¾~“存中,从而进一步减ž®‘网¾lœé€šä¿¡‹¹é‡ã€?/p>

  • 如果您的环境讄¡½®ä¸ºæ”¯æŒåŽ‹¾~©ï¼Œ˜q˜å¯ä»¥ä‹Éç”?HTTP 压羃ž®†åŽ‹¾~©è¿‡çš„æ ‡è®°å‘送到的客æˆähœºã€?/b>

    请参è€?Web 服务器和客户机的文档åQŒä»¥èŽ·å¾—è¯¦ç»†ä¿¡æ¯ã€?/p>

日志记录、跟ítªå’Œ I/O

日志通常最¾lˆä¼šæ¶‰åŠåˆ°å¯¹¼‹¬ç›˜å†™å…¥ã€‚从性能的角度而言åQŒä“Q何与¼‚ç›˜é¢‘繁˜q›è¡Œäº¤äº’的内定wƒ½æ˜¯æ½œåœ¨çš„大开销操作åQŒå› æ­¤ï¼Œæœ€å¥½å°½é‡å‡ž®‘在生äñ”环境中ä‹Éç”?Java I/O 库。由于通常通过使用某些 Java ¾~–程之下的本机库提供 I/OåQŒå› æ­¤ä¼šæœ‰ä¸€å®šçš„¾~ºçœ¾pȝ»Ÿå¼€é”€ã€‚System.out.println 之类的操作在文äšg I/O 期间会对处理˜q›è¡ŒåŒæ­¥åQŒè¿™ž®†å¯¹æ€§èƒ½é€ æˆå¾ˆå¤§çš„媄响ã€?/p>

在开发和‹¹‹è¯•æ¨¡å¼ä¸­ï¼Œå¯èƒ½å¸Œæœ›æ‰€æœ‰æ—¥å¿—è®°å½•å’Œè°ƒè¯•åŠŸèƒ½å‡äØ“‹zÕdŠ¨çŠ¶æ€ï¼Œå› äØ“˜q™äº›åŠŸèƒ½å¯¹äºŽå‘çŽ°é”™è¯¯éžå¸¸é‡è¦ã€‚åœ¨ç”Ÿäñ”环境中部¾|²åº”用程序时åQŒè®©å„ç§æ—¥å¿—åŠŸèƒ½å‡å¤„äºŽæ‰“å¼€çŠ¶æ€åÆˆéžå¯è¡Œçš„é€‰æ‹©ã€‚æœ€ä½›_®žè·µåº”是对日志语句加以保护åQŒä‹É其仅在出错和˜q›è¡Œè°ƒè¯•的情况下打开。可以通过使用一个最¾lˆçš„ Boolean å˜é‡å®žçŽ°æ­¤åŠŸèƒ½ï¼Œå½“å°†å…¶å€ÆD®¾¾|®äØ“ false æ—Óž¼Œå¯ä»¥æœ‰æ•ˆåœ°æŒ‡½Cºç¼–译器˜q›è¡Œä¼˜åŒ–åQŒä¸å†æ£€æŸ¥å’Œæ‰§è¡Œæ—¥å¿—记录代码åQ?/p>

														
																static final boolean LOGGING = false;
if (LOGGING) {...}
														
												

Java 语言提供了两¿UæµåQšè¯»å–器/写入器和输入/输出åQ?/p>

  • è¯Õd–器和写入器是åœ?I/O 操作中支æŒ?unicode 字符的高¾U§æŽ¥å£ã€?
  • 输入/输出‹¹æä¾›éžå¸æ€½Žçš„çñ”别(字节¾U§ï¼‰çš„æ•°æ®è®¿é—®æœºåˆ¶ã€?

è¯Õd–å™?写入器有性能开销åQŒå› ä¸ºå®ƒä»¬æ—¨åœ¨ç”¨äºŽå­—½W¦æµåQŒä¸”会在后台ž®†æ•°æ®ç¼–ç äØ“å­—èŠ‚ã€‚åªè¦å¸Œæœ›æ“ä½œäºŒ˜q›åˆ¶æ•°æ®åQŒå°±åº”该使用输入/输出‹¹ã€?/p>

ä¸ÞZº†ž®½å¯èƒ½æé«?I/O 性能åQŒåº”该对è¯Õd–和写入操作进行缓存。如果希望写入大量来è‡?Portlet 的数据,通常最好采用对已缓存的数据˜q›è¡Œéƒ¨åˆ†åˆäh–°çš„æ–¹å¼ï¼Œè€Œä¸é‡‡ç”¨å¯¹å…¨éƒ¨æ•°æ®ä¸€‹Æ¡æ€§åˆ·æ–°çš„æ–¹å¼ã€‚另一斚w¢åQŒä¸è¦å¤ªé¢‘繁地刷新缓冲区ã€?/p>

同步与多¾U¿ç¨‹

用于协调对共享对象的讉K—®çš?Java 机制¿UîCؓ同步。同步语句一‹Æ¡ä»…允许一个线½E‹è¿›å…¥ä»£ç å—ã€?/p>

  • åœ?Portlet 的生存期中,容器会将不同¾U¿ç¨‹ä¸­çš„æœåŠ¡è¯äh±‚发送到单个 Portlet 实例。请避免åœ?Portlet ä¸­è¿›è¡ŒåŒæ­¥ï¼Œå› äØ“åŒæ­¥æœ‰å¾ˆå¤§çš„æ€§èƒ½å½±å“åQšåŒæ­¥ä¼šå‡å°‘òq¶å‘åQŒå› ä¸ºåœ¨åŒæ­¥å—中一‹Æ¡ä»…允许˜qè¡Œä¸€ä¸ªçº¿½E‹ï¼Œæ‰€æœ‰åƈ发的¾U¿ç¨‹éƒ½è¦˜q›è¡ŒæŽ’队。另外,Java 虚拟æœÞZ¼šä½¿ç”¨ç›‘视器以支持同步åQŒç®¡ç†è¿™äº›ç›‘视器也有性能开销。除了性能影响之外åQŒè¿˜å¯èƒ½å‡ºçŽ°æ­»é”åQŒè€Œè¿™å¯èƒ½å¯ÆD‡´å•个 Portlet å†È»“åQŒæˆ–者甚è‡Ïx›´¾pŸï¼Œå¯ÆD‡´æ•´ä¸ªé—¨æˆ·å†È»“。由于监视器不支持进行ä“Q何死锁处理,因此½E‹åºå‘˜åº”负责防止死锁的出现ã€?/p>

  • 在有必要˜q›è¡ŒåŒæ­¥çš„场合下åQŒåº”该尽量羃ž®åŒæ­¥ä»£ç å—。准¼‹®åœ°è¯†åˆ«å“ªäº›ä»£ç çœŸæ­£éœ€è¦åŒæ­¥åƈž®½å¯èƒ½å°‘地进行同步,˜q™éžå¸”R‡è¦ã€‚如果同步代码块不够ž®ï¼Œåº”该对代码进行分析,对其重构åQŒä»¥ä½¿æ‰€æœ‰å¯ä»¥å¼‚步运行的代码均位于同步代码块之外ã€?/p>

  • 某些 Java J2SE 功能会间接地使用同步。Java 集合¾c»ï¼ˆå¦?Vector æˆ?HashtableåQ‰éƒ½æ˜¯å…¨é¢åŒæ­¥çš„。即使在单线½E‹çŽ¯å¢ƒä¸­ Java ½E‹åºä¹Ÿä¼šæœ‰ä¸Ž¾U¿ç¨‹åŒæ­¥ç›¸å…³çš„开销。Java 1.2 引入的较新的集合åQˆå¦‚ ArrayListåQ‰åƈ不进行同步。这ž®±æä¾›äº†å¯ÒŽ•°æ®æ›´å¿«çš„讉K—®ã€‚在需要线½E‹å®‰å…¨çš„æƒ…况下,请ä‹É用线½E‹å®‰å…¨è§†å›¾ã€‚线½E‹å®‰å…¨è§†å›¾æ˜¯åŒ…装¾c»ï¼Œè¯¥ç±»å¢žåŠ äº†åŒæ­¥æ ‡å‡†é›†åˆæ–¹æ³•çš„åŠŸèƒ½ã€‚é›†åˆç±»çš„å·¥åŽ‚æ–¹æ³•å°†˜q”回¾U¿ç¨‹å®‰å…¨çš„集合,该集合由特定的集合类型的实例支持åQ?/p>
    																		
    																				List list = Collections.sychronizedList(new ArrayList());
    																		
    																

  • 另一个非直接同步的例子就æ˜?Java I/O 库。请ž®½å¯èƒ½å°‘åœîC‹Éç”?Java I/O 库方法(例如 System.out.println()åQ‰ï¼Œä»¥å‡ž®‘不必要的性能开销ã€?/p>

  • 不要ä»?Portlet 生成非托½Ž¡çº¿½E‹ã€‚当å‰?J2EE å¼ºçƒˆå»ø™®®ä¸è¦è¯•图在容器生成新¾U¿ç¨‹ã€‚实际上åQŒJ2EE 规范 6.2.1 ¾~–程限制指出åQ?/p>

    “如果应用程序组件包含的功能ä¸?J2EE ¾pȝ»ŸåŸºç¡€¾l“æž„æ‰€æä¾›çš„åŠŸèƒ½ç›¸åŒï¼Œåˆ™ä¼šå­˜åœ¨åŠŸèƒ½å†²çªå’Œç®¡ç†æØœä¹±ã€‚ä¾‹å¦‚ï¼Œâ€¦â€¦ä»¥½Ž¡ç†¾U¿ç¨‹â€¦â€¦â€?/i>

    不要试图生成新线½E‹çš„ä¸€ä¸ªå®žé™…åŽŸå› æ˜¯å› äØ“æ–°çº¿½E‹å¯¹ J2EE 上下文没有完全访问权限。而且åQŒæ–°åˆ›å¾çš„非托管¾U¿ç¨‹ä¼šå¦¨¼„?WebSphere Portal 实现½E›_®šçš„、优化的可扩展运行时环境。因此,请ä‹Éç”?WebSphere Application Server 中的异步 Bean 功能åQˆè¯·å‚阅 WebSphere Application Server Enterprise V5 和编½E‹æ¨¡åž‹æ‰©å±?WebSphere 手册¾pÕdˆ—åQ‰ã€‚异æ­?Bean 是一ä¸?Java 对象æˆ?Enterprise BeanåQŒèƒ½å¤Ÿä‹Éç”?J2EE 上下文提交在独立¾U¿ç¨‹åQˆå¼‚步)˜qè¡Œçš„代码ã€?/p>

Portlet

Portlet ¾~–程模型允许开发äh员创建特定类型的 Web 应用½E‹åºåQŒæ­¤¾cÕdº”用程序可以作为客æˆähœº‹¹è§ˆå™¨ä¸­è‹¥å¹²æ­¤ç±»åº”用½E‹åºçš„聚合视囄¡š„一部分。在 WebSphere Portal 中,此类应用½E‹åºä¸ä»…能共存在一个页面(卌™šåˆè§†å›¾ï¼‰ä¸Šï¼Œ˜q˜èƒ½åœ¨æž„造该™åµé¢æ—¶å½¼æ­¤è¿›è¡Œé€šä¿¡ã€‚因此,Portlet 的实现可以媄响页面的æ€ÖM½“性能åQ›ä¾‹å¦‚,如果特定的“关键”Portlet é©È•™åœ¨é¡µé¢ä¸ŠåQŒåˆ™å€¼å¾—èŠÞq²¾åŠ›åœ¨åŒä¸€ä¸ªé¡µé¢ä¸Šå®žçŽ°ä¸€äº›å…¶ä»–çš„å…³é”®æ€§èƒ½ Portletã€?/p>

后端讉K—®

在实际的门户中,完全自我依赖çš?Portlet 非常ž®‘见åQŒå› ä¸ºé—¨æˆ·é€šå¸¸ç”¨ä½œ¾|‘站的附加内å®ÒŽˆ–帮助工具。此¾c?Portlet 应仅在其本地代码执行路径中优化,不应对允许的门户¾pȝ»Ÿå¸¦æ¥å¤ªå¤šçš„负荗÷€?/p>

Portlet æ›´äØ“å…¸åž‹çš„ç”¨æˆ·å°±æ˜¯æä¾›éœ€è¦è®¿é—®å…¶ä»–æ•°æ®æºæˆ–äº‹åŠ¡ç³»¾lŸçš„应用½E‹åºåŠŸèƒ½åQŒé™¤äº?Portlet 的原始执行系¾lŸä¹‹å¤–,˜q™äº›æ•°æ®æºæˆ–事务¾pȝ»Ÿä¹Ÿéœ€è¦æ‰§è¡Œèµ„源。数据可能会从网¾lœä¸Šçš„其他后端系¾lŸæ£€ç´¢æˆ–存储到其中。需要在æ€ÖM½“¾pȝ»Ÿè®¾è®¡ä¸­è€ƒè™‘在后端系¾lŸä¸Šå¯èƒ½å‡ºçŽ°çš„äº‹åŠ¡é•¿åº¦ã€éš”¼›Èñ”别以及数据锁定ã€?/p>

è¯äh³¨æ„ï¼Œå•个 Portlet 可能不是后端¾pȝ»Ÿçš„唯一客户机。事实上åQŒåœ¨å®žé™…ä½¿ç”¨ä¸­ï¼Œä¼šæœ‰å¾ˆå¤šå®¢æˆ·æœø™¿žæŽ¥åˆ°æ­¤ç±»¾pȝ»ŸåQŒç”šè‡›_•ä¸?Portlet ˜q˜å¯èƒ½åŒæ—¶å¤š‹Æ¡è®¿é—®åŒä¸€ä¸ªåŽç«¯ç³»¾lŸã€‚Portlet 可能会在多个独立的服务器¾U¿ç¨‹ä¸­æ‰§è¡Œå…¶ä»£ç ä»¥å“åº”不同的用户è¯äh±‚。因此,有必要对讉K—®æ¨¡å¼˜q›è¡Œäº†è§£åQŒPortlet 或其他客æˆähœºèŽ·å–äº‹åŠ¡æˆ–é”å®šçš„æ–¹å¼å¯èƒ½ä¼šåª„å“æ­¤¾cÕdŽç«¯ç³»¾lŸçš„òq›_‡å“åº”æ—‰™—´ã€?/p>

如果某个 Portlet 在操作或呈现阶段需要进行密集的后端¾pȝ»Ÿè®‰K—®åQŒå“åº”æ—¶é—ß_¼ˆå®Œæˆ˜q™äº›é˜¶æ®µçš„æ—¶é—ß_¼‰ž®†è¶Šæ¥è¶Šä¾èµ–于后端系¾lŸçš„响应。(如果½{‰å¾…门户服务器外的响应以满èƒöä¼ å…¥è¯äh±‚åQŒå°†ä¼šå¸¦æ¥åšg˜qŸï¼Œæ­¤åšg˜qŸä¸èƒ½é€šè¿‡ä¼˜åŒ– Portlet 代码的执行èµ\径得到改善。)å…ähœ‰åŽç«¯¾pȝ»Ÿé€šä¿¡çš„良好设计,òq¶äº†è§£äº‹åŠ¡è¡Œä¸ºé€šå¸¸å¯ä»¥å¾—åˆ°æ›´é«˜çš„æ€§èƒ½ã€?/p>

ä¸ÞZº†é¿å…ç”׃ºŽåŽç«¯¾pȝ»Ÿå´©æºƒè€Œä‹É PortletåQˆä»¥åŠå…¶æ‰€åœ¨é¡µé¢ï¼‰åœæ­¢å“åº”åQŒå¯ä»¥åœ¨ä»£ç ä¸­åŠ å…¥è¶…æ—¶æœºåˆÓž¼›ä¸è¿‡åQŒè¯·æ³¨æ„åQŒç®¡ç†å’Œè·Ÿè¸ªæ—‰™—´æˆ³ä¼šå¸¦æ¥ä¸€äº›å¤„理开销。如果ä‹É用了 WebSphere Portal 中的òq¶è¡Œ Porlet 呈现功能åQˆç¨åŽè®¨è®ºï¼‰åQŒåˆ™å¯äØ“òq¶è¡Œå‘ˆçް¾U¿ç¨‹é…ç½®­‘…æ—¶ã€?/p>

ž®½å¯èƒ½å‡ž®‘与此类外部后端¾pȝ»Ÿçš„交互和数据通信‹¹é‡ä¹Ÿæ˜¯ä¸é”™çš„åšæ³•ã€‚äØ“äº†å®žçŽ°è¿™ä¸€ç‚¹ï¼Œå¦‚æžœä¿¡æ¯çš„åˆ·æ–°æ ‡å‡†å…è®¸è¿›è¡Œç¼“å­˜ï¼ŒPortlet 可以对信息进行缓存。这可以减少为每个传å…?WebSphere Portal è¯äh±‚多次获取相同数据的往˜q”次数。这栯‚¿˜å¯ä»¥å¸®åŠ©é™ä½ŽåŽç«¯¾pȝ»Ÿä¸Šçš„负蝲åQŒå› ä¸ø™¿™æ ·å°±æ— éœ€å¤šæ¬¡æä¾›ç›¸åŒçš„信息了。另外,如果不需要在¾|‘络上传输数据,Portlet 可能可以更快地进行呈现ã€?/p>

避免到后端系¾lŸçš„å¾€˜q”的另一个方法就是除了检索满­‘›_½“前请求实际所需的数据外åQŒè¿˜‹‚€ç´¢æ‰€çŸ¥çš„ž®†åœ¨å¯èƒ½çš„后¾l­è¯·æ±‚中所需的数据。不˜q‡ï¼Œä½¿ç”¨æ­¤æ–¹æ³•æ—¶åQŒå¦‚果知道在后箋è¯äh±‚中将要实际需要哪些预提取数据åQŒæˆ‘们仍然徏议ä‹Éç”¨æ™®é€šçš„é¢„æå–åŠŸèƒ½ã€‚äØ“äº†åˆç†åœ°è®¾è®¡æ­¤ç‰¹æ€§ï¼Œéœ€è¦å¯¹ Porlet 应用½E‹åºçš„å…¸åž‹ç”¨æˆ·äº¤äº’éžå¸æ€º†è§£ã€‚要è®îC½åQŒæå‰æ£€ç´¢ä¼šå¯šw—¨æˆ?JVM 的内存ä‹É用造成影响。(请参é˜?a >性能和可伸羃性代码设è®?/font>。)此类设计æ–ÒŽ³•可能需要更改后端系¾lŸçš„æŽ¥å£åQŒä½†å¯ä»¥èŠ‚çº¦å¤§é‡çš„å¤„ç†æ—¶é—ß_¼Œä½¿å¾—更改物超所倹{€?/p>

对于¾~“å­˜åQŒWebSphere Application Server 利用光™¢å‘çš„ Portlet çš?DistributedMap 接口提供了动态缓存功能。(请参é˜?WebSphere Application Server 5.1 信息中心以获得更多的信息。)

会话与其他数据存储区

保持和维æŠ?Portlet 的数据,使其生存期长于单个请求的生存期,˜q™æ˜¯ä¸€ä¸ªå…¸åž‹çš„ Portlet ¾~–程ä»ÕdŠ¡ã€‚é€šå¸¸è€ƒè™‘é‡‡ç”¨çš„ç¬¬ä¸€ä¸ªæ–¹æ³•å°±æ˜¯ä‹Éç”?PortletSession。从½E‹åºå‘˜çš„角度而言åQŒPortletSession 使用很方便,但从应用½E‹åºæœåŠ¡å™¨çš„è§’åº¦è€Œè¨€åQŒç®¡ç†ä¼šè¯éœ€è¦ä‹É用资源。如果会话包含越来越多的数据åQŒä»Žè€Œè¦æ±‚ä‹É用更多的内存åQŒåˆ™ä¼šè¿›ä¸€æ­¥ä‹É问题严重化ã€?/p>

如果ž®†ä¼šè¯é…¾|®äؓ持久地存储在数据库中åQŒæˆ–é…ç½®ä¸ø™¿›è¡Œå†…存到内存复制åQˆå³åœ¨é›†¾Ÿ¤åŒ–çŽ¯å¢ƒä¸­äØ“ WebSphere Portal 配置了故障è{¿U»ï¼‰åQŒåˆ™è¯¥ä¼šè¯å°†åœ¨å…¶å†…容更改时被序列化ã€?/p>

当会话数据写入到˜qœç¨‹å‰¯æœ¬æ—Óž¼Œå¯¹ä¼šè¯æ•°æ®è¿›è¡Œåºåˆ—化和反序列化所需的时间可能变得非常大。在非常ž®‘见的情况下åQŒå­˜å‚¨åœ¨ä¼šè¯ä¸­çš„æŸäº›å¯¹è±¡å¯èƒ½è¢«æ ‡è®îCؓ瞬态的。这ž®†é™ä½Žä¼šè¯çš„序列化后的大ž®ï¼Œä½†ä¸ä¼šæ›´æ”¹å†…存的大小åQŒè€Œè¿™å¯¹åº”用程序服务器处理会话的效率也有媄响ã€?/p>

大型的会话对象会减少可用以创建和执行应用½E‹åºå¯¹è±¡çš?JVM 内存。因此,随着可用堆内存的减少而导致更频繁的垃圑֛žæ”Óž¼Œæ€§èƒ½å¯èƒ½ä¼šé™ä½Žã€?/p>

另一个因素就是内存内的生存期比所需的ä‹É用时间长åQŒå› æ­¤å ç”?Java 堆中的空间的会话数量通常比活动用æˆïLš„æ•°é‡å¤šã€‚在 WebSphere Application Server 中可以配¾|®ä¼šè¯è¿‡æœŸæ—¶é—ß_¼Œ˜q™ä¸ªå±žæ€§éžå¸¸å¿…要,可以防止在几¿U’钟没有‹zÕdŠ¨åŽå°±è¦æ±‚ç”¨æˆ·å†æ¬¡ç™Õd½•的情å†üc€‚会话的释放ç”?WebSphere Application Server å’?Portlet 容器负责ã€?/p>

序列化的会话大小应该ž®äºŽ 4KBåQŒå› ä¸?WebSphere Application Server 能以可以接受的数据库性能开销存储此类会话åQŒåœ¨¾|‘络上传输此¾cÖM¼šè¯çš„æ—‰™—´ä¹Ÿæ›´ž®‘。如果会话大ž®è¶…˜q‡äº† 32KBåQŒæ•°æ®åº“必须使用面向二进制大对象配置的表单元æ û|¼Œè€Œå¦‚果此¾cÖM¼šè¯ä»Žæ•°æ®åº“检索或写入到数据库中,则将需要访问物理磁盘(对于大多数受支持的数据库åQ‰ã€?/p>

ç”׃»¥ä¸Šåˆ†æžå¾—出的½W¬ä¸€ä¸ªç»“论就是,从应用程序的角度而言åQŒåº”该尽可能避免创徏会话。在大多数公共页面和无需íw«ä†¾éªŒè¯çš„页面上åQŒé€šå¸¸ä¸éœ€è¦ä¼šè¯ã€‚在此类™åµé¢ä¸Šå¯ä»¥é€šè¿‡å‘ˆçŽ°é“¾æŽ¥ä¸Žé—¨æˆ¯‚¿›è¡Œäº¤äº’ï¼Œè€Œå‘ˆçŽ°é“¾æŽ¥å®šä¹‰äØ“ä¸æ›´æ”ÒŽœåŠ¡å™¨ç«¯çš„çŠ¶æ€ã€‚é—¨æˆ·å°†ä¸ºæ¯ä¸?Portlet ¾l´æŠ¤å‘ˆçŽ°å‚æ•°åQŒä»¥ç”¨äºŽå¯¹è¯¥™åµé¢çš„æ‰€æœ‰åŽ¾l­è¯·æ±‚ã€‚äØ“äº†é¿å…?JSP ¾~ºçœåˆ›å¾ä¼šè¯åQŒåº”该将 JSP 中的™åµé¢ä¼šè¯æŒ‡ä×o讄¡½®ä¸?falseåQ?/p>

														
																<@ page session="false"%>
														
												

否则åQŒå¦‚果不存在会话åQŒæ­¤ JSP ž®†åˆ›å»ÞZ¸€ä¸ªä¼šè¯ã€?/p>

以下çš?Java 代码片段演示了如何确保传入会话加入现有的会话åQŒè€Œä¸æ˜¯æ— æ¡äšg地创建新会话åQ?/p>

														
																PortletRequest.getPortletSession(false)
														
												

ž®†æ­¤å‚æ•°çš„å€ÆD®¾¾|®äØ“ false æ—Óž¼Œå¦‚果之前不存在会话,ž®†ä¸ä¼šåˆ›å»ÞZ¼šè¯ã€‚如果之前不存在会话åQŒä»…ä¸ÞZº†åœ¨å…¶ä¸­å­˜å‚¨æ•°æ®è€Œåœ¨ Portlet 中创å»ÞZ¸€ä¸ªä¼šè¯ï¼Œå¯èƒ½òq¶ä¸åˆé€‚ã€?/p>

ç”׃»¥ä¸Šåˆ†æžå¾—到的½W¬äºŒä¸ªç»“论就是,ä¸?/b>要将会话误用作通用数据存储机制。请è®îC½åQŒæˆ‘们的目的是尽可能使会话保持最ž®ã€‚如果由äº?Portlet 的设计,ž®†æŸäº›æ•°æ®ä¿å­˜åœ¨å†…存中具有一定优势,则可以ä‹É用缓存。可以ä‹É用会è¯?ID 讄¡½®¾~“存条目的范å›ß_¼Œä»¥ä‹É会话和要保存在内存中的数据徏立关联。请注意åQŒæ­¤¾cȝ¼“存在呈现故障转移时不支持集群åQ›è€Œè¿™æœ‰æ—¶æ˜¯å¯ä»¥æŽ¥å—的折衷。如果数据可以ä‹É用其ä»?Portlet 可用数据重新创徏åQŒåˆ™¾~“存条目的会话范围要求就有待商榷ã€?/p>

在很多情况下åQŒé€šè¿‡ä»…在会话中存储一个键åQŒåÆˆä½¿ç”¨è¯¥é”®ä½œäØ“å¼•ç”¨ä»¥åœ¨å…¶ä»–æ•°æ®¾l“构中查找更大的对象åQŒä»Žè€Œå¯ä»¥é¿å…åœ¨ä¼šè¯ä¸­å­˜å‚¨å¤§å¯¹è±¡ã€‚另外,可以选择使用相同信息的更紧凑的表½CºåŞ式,而后ž®†è¯¥å¯¹è±¡æ”‘Ö…¥ä¼šè¯ä¸­ã€?/p>

而且åQŒPortlet 设计需要仔¾l†è€ƒè™‘会话中实际存储的内容。会话通常仅旨在用于存储用户交互与门户应用½E‹åºçš„对话状态(例如åQŒç½‘上商åº?Porltet 中的购物车的内容åQ‰ã€‚æ­¤¾cÀL•°æ®ä¸èƒ½é‡‡ç”¨å…¶ä»–ä“Q何手ŒDµé‡æ–°åˆ›å»ºã€‚在 WebSphere Portal 中,˜q™ç§¾cÕdž‹çš„æ•°æ®å¤„理称ä¸?b>会话状æ€?/b>ã€?/p>

如果òq¶ä¸éœ€è¦ä¼šè¯çŠ¶æ€ï¼ŒPortlet 可以使用其他数据存储选项åQ?/p>

  • åœ?Portlet 的操作阶ŒDµï¼Œå¯ä»¥ä¸?Portlet 的后¾l­å‘ˆçŽ°é˜¶ŒDµè®¾¾|®å‘ˆçŽ°å‚æ•°ã€‚Portlet 使用呈现参数呈现其特定于一¾l„特定值的视图。由容器在请求间¾l´æŠ¤å‘ˆçŽ°å‚æ•°åQŒå³ä½¿å‡ºçŽîC¸Žå…¶ä»– Portlet 的交互也是如此。在 WebSphere Portal 中,˜q™ç§¾cÕdž‹çš„æ•°æ®å¤„理称ä¸?b>坯Dˆªçжæ€?/b>ã€?/p>

  • 如果需要跨多个用户会话保持数据åQŒåˆ™å¯ä»¥ä½¿ç”¨ PortletPreferences API ä¸?Portlet 存储数据。请è®îC½åQŒæ­¤ API òq¶ä¸èƒ½æ›¿ä»£é€šç”¨æ•°æ®åº“。在 WebSphere Portal 中,˜q™ç§¾cÕdž‹çš„æ•°æ®å¤„理称ä¸?b>持久性状æ€?/b>ã€?/p>

  • PortletConfig API ä½?Portlet 可以è¯Õd–å…‰™…¾|®ï¼Œè¯¥é…¾|®ç”±å¼€å‘äh员通过使用 Portlet 部çÖv描述½W¦æä¾›ï¼›˜q™å¯¹äº?Porltet 的所有用户均有效ã€?/p>

  • PortletContext API 允许存储同一应用½E‹åºä¸­å…¶ä»?Portlet 也可以访问的属性ã€?/p>

误‚€ƒè™‘使用会话之外的其他选择åQŒå°†å…¶ç”¨äºŽå­˜å‚?Portlet 创徏和ä‹É用的数据。避免将可以通过用户交互之外的其他源重新创徏的数据复制到会话中ã€?/p>

呈现链接与操作链�/font>

与对特定çš?Portlet 视图å¯Õd€ç›¸æ¯”åQŒä‹É用呈现参数有很多优势ã€?/p>

如果 WebSphere Portal ‹‚€‹¹‹åˆ°äº?Portlet 的操作参敎ͼŒåˆ™å¿…™å»è°ƒç”¨ç‰¹ŒDŠçš„æ“ä½œé˜¶æ®µå¤„理åQŒä‹É其具有不必ä‹É用操作参数的优势。不˜q‡ï¼Œè¯äh³¨æ„ï¼Œå¤„理呈现链接时一定不能更æ”?Portlet 的服务器端状态。要更改服务器端状态,唯一得到认可的方法就是ä‹É用操作链接,而对于事务类型的è¯äh±‚åQŒæ“ä½œé“¾æŽ¥æ˜¯æœ€å¥½çš„选择ã€?/p>

使用呈现链接而不使用操作链接的例子很多。例如,假设一个报¾U?Portlet 可以同ä‹É用“上一™åµâ€å’Œâ€œä¸‹ä¸€™åµâ€æŒ‰é’®æ˜¾½Cºç‰¹å®šçš„™åµé¢ã€‚逐页‹¹è§ˆæŠ¥çº¸çš„页面不一定会更改服务器端的状态,此状态在本例中就是报¾U怸­åŒ…å«çš„å…¨éƒ¨ä¿¡æ¯ã€‚äØ“äº†å¯»å€æŠ¥çº¸çš„ä¸‹ä¸€™åµï¼Œž®†ä¸‹ä¸€™å늚„的页码编码到所昄¡¤ºæŒ‰é’®çš„呈现链接中ž®Þpƒö够了。Portlet 可以æ ÒŽ®å‘ˆçŽ°å‚æ•°ä¸­æ‰€¾l™çš„™å늠¼‹®å®šè¦å‘ˆçŽ°çš„™åµé¢ã€?/p>

此外åQŒç”±äºŽæ¯ä¸ªå‘ˆçŽ°çš„è§†å›¾éƒ½ç”±ç‹¬ç«‹çš?URL å¯Õd€åQŒæ‰€ä»¥ï¼Œé€šè¿‡ä½¿ç”¨å‘ˆçŽ°é“¾æŽ¥è€Œä¸ä½¿ç”¨æ“ä½œé“¾æŽ¥åQŒè¿˜å¯ä»¥å……分利用¾~“存基础¾l“æž„åQˆæ— è®ºæ˜¯‹¹è§ˆå™¨ç¼“存还是代理缓存)。URL 是用于访问此¾cȝ¼“存基¼‹€¾l“构中的特定生成视图的唯一的键ã€?/p>

Portlet 功能

接下来的几个部分中将讨论开发äh员应该考虑çš?WebSphere Portal 中可用的一äº?Porlet 优化功能åQŒè¿™äº›åŠŸèƒ½å¯ä»¥åª„å“æ‰€é€‰æ‹©çš„å®žçŽ°æŠ€æœ¯ã€‚éœ€è¦ä‹Éç”?Portlet 的部¾|²æ˜q°ç¬¦æä¾›ä¸€äº›å¿…™åȝš„讄¡½®åQŒè€Œä¸”åQŒç”±äºŽè¿™äº›é¡¹ä¹Ÿæ˜¯ç”?Portlet 开发äh员提供的åQŒå› æ­¤è¢«è®¤äؓ是自定义代码ã€?/p>

允许 Portlet ˜q›è¡Œòq¶è¡Œå‘ˆçް

WebSphere Portal 提供了让™åµé¢ä¸Šçš„ Portlet òq¶è¡Œå‘ˆçŽ°çš„é€‰é¡¹ã€‚æ­¤åŠŸèƒ½òq‰™žå®Œå…¨â€œå…è´¹â€çš„åQŒå› ä¸ºéœ€è¦è®¡½Ž—资源以¾l´æŠ¤å’Œç®¡ç†å‘ˆçŽ°æ¯ä¸?Portlet 所使用的不同线½E‹ã€?/p>

如果涉及到很多后端系¾lŸï¼Œè€Œæ¯ä¸ªåŽç«¯ç³»¾lŸåœ¨å‘ˆçŽ°å•ä¸ª™åµé¢æ—‰™ƒ½ä¼šäñ”生åšg˜qŸï¼Œæ­¤æ—¶ä½¿ç”¨òq¶è¡Œ Portlet 呈现ž®±å…·æœ‰ä¸€å®šä¼˜åŠÑ€‚例如,假设一个门户页面包含很å¤?PortletåQŒæ¯ä¸?Portlet 都会讉K—®ä¸åŒçš„后端系¾lŸã€‚在串行呈现模式中,从所有后端系¾lŸæ£€ç´¢æ‰€éœ€æ•°æ®çš„æ€ÖM½“延迟为各个åšg˜qŸæ—¶é—´çš„æ€Õd’Œã€‚而在òq¶è¡Œå‘ˆçŽ°æ¨¡å¼ä¸­ï¼Œå»¶è¿Ÿæ—‰™—´åº”äØ“æ‰€æœ‰å•ä¸ªåšg˜qŸæ—¶é—´ä¸­çš„æœ€å¤§å€¹{€?/p>

如果 Portlet òq¶ä¸¾lå¸¸ä½¿ç”¨åŽç«¯¾pȝ»ŸåQŒç”±äºŽå¯ç”¨åƈè¡?Portlet 呈现所带来的开销可能会比由此功能所带来的好处更大。如果页面上çš?Portlet 能够独立于后端系¾lŸè¿›è¡Œå‘ˆçŽŽÍ¼Œåˆ™åªéœ€è¦é—¨æˆähœåŠ¡å™¨è®¡ç®—æœºæœ¬åœ°çš„ CPU 资源。这¿Uæƒ…况下åQŒé¡µé¢å‘ˆçŽ°å“åº”æ—¶é—´ä¸ä¼šå¾—åˆ°æ”¹˜q›ã€?/p>

可以使用囑ÖŞ用户界面、部¾|²æ˜q°ç¬¦æˆ?WebSphere Portal çš?XML 讉K—®æŽ¥å£å¯ç”¨òq¶è¡Œ Portlet 呈现。而且åQŒè¿˜æœ‰ä¸€ä¸ªç›¸å…³çš„全局属性å€û|¼Œå¯ä»¥å…¨é¢å¼€å¯å’Œå…³é—­òq¶è¡Œ Portlet 呈现功能ã€?/p>

要正¼‹®å›ž½{”æ˜¯å¦æ”¯æŒåÆˆè¡?Portlet 呈现门户˜q™ä¸€é—®é¢˜åQŒéœ€è¦è€ƒè™‘若干事项åQ›ä¾‹å¦‚,呈现™åµé¢æ‰€æ¶‰åŠåˆ°çš„后端¾pȝ»Ÿçš„æ•°é‡ã€ä‹Éç”¨åÆˆè¡?Portlet 呈现的页面上çš?Portlet çš„åã^均数量,½{‰ç­‰ã€‚Portlet 开发äh员事先不一定能¾l™å‡º˜q™äº›é—®é¢˜½{”案åQŒä½†å¦‚果合理的话åQŒå¼€å‘ähå‘˜å½“ç„¶äº‹å…ˆå¯ä»¥ç¡®ä¿äØ“ Portlet å¯ç”¨äº†åÆˆè¡?Portlet 呈现ã€?/p>

�Portlet 容器中进行缓�/b>

åŸÞZºŽ Portlet çš?Web ™åµé¢æ˜¯åŠ¨æ€èšåˆçš„åQŒå› ä¸ºå®ƒä»¬èƒ½ä»¥ä¸ªæ€§åŒ–的方式提供动态内宏V€‚这个灵‹zÀL€§å…·æœ‰ä¸€å®šçš„å¼€é”€ã€‚ç”±äºŽäØ“äº†å“åº”è¯·æ±‚ç”Ÿæˆè¿™äº›é¡µé¢å¿…™å»è¿›è¡Œé¢å¤–的工作åQŒæ•…而网站的响应旉™—´ž®†å¢žåŠ ã€?/p>

æ–°çš„¾~“存技术将改善动态页面的生成和减ž®‘ç³»¾lŸè´Ÿè½½ã€‚WebSphere Portal 支持片断¾~“å­˜åQˆä¹Ÿ¿UîCØ“ Servlet ¾~“å­˜åQ‰ï¼Œå¯ä»¥ä½¿ç”¨ WebSphere Application Server 动态缓存在¾~“存中保å­?Portlet 输出。对¾~“å­˜çš?Portlet 的请求将从缓存(而不æ˜?PortletåQ‰æ£€ç´¢å†…宏V€‚可以通过在部¾|²æ˜q°ç¬¦ä¸­æŒ‡å®šè¿‡æœŸå®žçŽ°ç‰‡æ–­ç¼“å­˜çš„å¤±æ•ˆã€‚è€Œä¸”åQŒåœ¨ Portlet 的操作阶ŒDµä¹Ÿä¼šä‹É片断¾~“存条目失效ã€?/p>

‹È€‹zȝ‰‡æ–­ç¼“存不需要进行费时的安装和集成工作。通过使用½Ž€å•çš„ XML 部çÖv描述½W¦æ–‡ä»¶å’Œé€šè¿‡ä½¿ç”¨ WebSphere Application Server ½Ž¡ç†æŽ§åˆ¶å°å‡å¯ä»¥å¯ç”¨å’Œç¦ç”¨è¯¥¾~“存功能。(请参é˜?WebSphere Portal 信息中心åQŒä»¥äº†è§£åœ?WebSphere Application Server 中启ç”?Servlet ¾~“存的详¾l†ä¿¡æ¯ã€‚)

ä¸ÞZº†ä½¿ç”¨åŸÞZºŽ˜q‡æœŸçš„缓存,Portlet 必须在部¾|²æ˜q°ç¬¦ portlet.xmlåQˆå¯¹äºŽç¬¦å?JSR 168 规范的标准化 PortletåQ‰ä¸­å®šä¹‰˜q‡æœŸ¾~“存的持¾l­æ—¶é—ß_¼š

														
																<expiration-cache>300</expiration-cache>
														
												

  • 整数定义¾~“存条目在缓存中存在的秒数倹{€?/p>

  • å€?-1 指示 Portlet ¾~“存永远不过期ã€?/p>

  • å€?0 æŒ‡ç¤ºä¸ø™¯¥ Portlet ¼›ç”¨¾~“存功能ã€?/p>

一定不能在同一 Portlet 的所有用户间å…׃ín¾~“存的条目。此¾~“存技术是åŸÞZºŽç‰¹å®š Portlet 的特定用æˆïLš„ã€?/p>

对于在其部çÖv描述½W¦ä¸­å®šä¹‰äº†è¿‡æœŸç¼“存的 JSR 168 PortletåQŒPortlet ½H—口可以在运行时通过讄¡½® RenderResponse 中的 EXPIRATION_CACHE 属性修改过期时é—ß_¼Œå¦‚下所½Cºï¼š

														
																renderResponse.setProperty(
   RenderResponse.EXPIRATION_CACHE,
   String.valueOf(numberCrunchingCalculation())
);
														
												

对于在从后端åQˆå¦‚ EJB ¾l„äšg和数据库åQ‰è®¡½Ž—其响应和请求数据时计算旉™—´å¾ˆé•¿çš„复æ?PortletåQŒæ­¤æ–ÒŽ³•非常有用。对于简å?PortletåQŒä¸åº”启用片断缓存。WebSphere Portal ž®†ä‹É用额外的执行资源计算机片断缓存的内部¾~“存键。对于简å?PortletåQŒç”±äºŽç¼“存键计算比重新计½Ž?Portlet 响应开销更大åQŒå…¶æ€§èƒ½å¯èƒ½ä¼šé™ä½Žã€?/p>

对于真正动态的 PortletåQŒç‰‡æ–­ç¼“å­˜åÆˆä¸é€‚ç”¨åQ›å¦‚åQŒå¯¹æ¯ä¸ªè¯äh±‚都需要从其他数据源收集当前数据的åŸÞZºŽå®žæ—¶çš?Portlet 或对每个è¯äh±‚都会更改其响应标记的 Portlet。这ž®†ä¼šå¯ÆD‡´å¤§é‡çš„缓存失效,因此性能不会得到提高。所以,仅在 Portlet 的输出在更新前会在一ŒD‰|—¶é—´å†…ä¿æŒæœ‰æ•ˆçš„æƒ…å†µä¸‹æ‰åº”è¯¥äØ“ Portlet 启用¾~“存功能ã€?/p>

在远½E‹ç¼“存中˜q›è¡Œ¾~“å­˜

通过独特的自适应¾~“存功能åQŒWebSphere Portal 可以在门æˆïL¼“存之外的¾~“å­˜åQˆç§°ä¸ø™¿œ½E‹ç¼“存)中动态缓存生成的™åµé¢åQˆå¦‚果所有页面组件均指示自èín可以¾~“å­˜åQ‰ã€‚如果从˜qœç¨‹æä¾›å®Œå…¨å‘ˆçŽ°çš„é¡µé¢ï¼Œž®±å¯ä»¥é¿å…åˆ°é—¨æˆ·æœåŠ¡å™¨çš„å¾€˜q”,此类™åµé¢çš„响应时间可以与从静态网站提供时一样快ã€?/p>

有关˜qœç¨‹¾~“存的全部详¾l†ä¿¡æ¯ï¼Œè¯·å‚é˜?a >使用 WebSphere Portal V5.1 开发包含静态内容和动态内容的高性能¾|‘ç«™ã€?/p>

PortletåQˆä»¥åŠä¸»é¢˜ï¼‰å¯ä»¥æä¾›å®Œå…¨å‘ˆçް™åµé¢çš„æ€ÖM½“˜qœç¨‹¾~“存信息中其所特定的远½E‹ç¼“存信息。远½E‹ç¼“存信息一个数据结构,由关于缓存范å›ß_¼ˆæ˜¯å¦å¯ç¼“存,是共享的åQŒè¿˜æ˜¯éžå…׃ín的)和过期时é—ß_¼ˆå†…容在多长时间内为有效)的信息组成。可以通过部çÖv描述½W¦æˆ– WebSphere Portal GUI 提供 Portlet 的远½E‹ç¼“存信息。除此之外,Portlet ˜q˜å¯ä»¥åœ¨å‘ˆçŽ°æ—¶äØ“æ¯ä¸ª Portlet 提供˜qœç¨‹¾~“存信息åQŒå¦‚下面的代码中所½Cºï¼š

														
																. . . 
import com.ibm.wps.util.RemoteCacheInfo;
import javax.portlet.RenderResponse;
. . .
/* Do rendering */
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
   throws PortletException, IOException {
   /* Some code might happen here */
   . . . 
   /* Publish a dynamic expiration time during rendering */
   renderResponse.setProperty( 
      RenderResponse.EXPIRATION_CACHE, 
      String.valueOf(numberCrunchingCalculation())
   );
   /* Publish a cache scope value of "shared" during rendering *)
   renderResponse.setProperty( 
      RemoteCacheInfo.KEY_SCOPE, RemoteCacheInfo.Scope.SHARED_STRING );
   /* Some other code might happen here */
   . . . 
}
														
												

讄¡½®˜qœç¨‹¾~“存信息的方式依赖于呈现的视囄¡š„“刷新”要求和范围。请注意åQŒå¦‚果从¾~“存提供呈现的页面,è¯äh±‚可能甚至不会发送到门户服务器ã€?/p>

如果可以在基¼‹€¾l“构中ä‹É用缓存,自定ä¹?Portlet 开发äh员应当考虑利用˜qœç¨‹¾~“存功能ã€?br />

主题与外�/font>

在门æˆähœ¯è¯­ä¸­åQŒä¸»é¢˜æ˜¯¼‹®å®šé—¨æˆ·åº”用½E‹åºçš„外观和风格的若òq?JSP 集。由于主题由 JSP ¾l„成åQŒåœ¨ JSP 部分¾l™å‡ºçš„æŠ€å·§ä¹Ÿé€‚用于此。这一部分详细讨论了ä‹É用组成主题的 JSP æ–‡äšg集可能存在的性能¾~ºé™·ã€?/p>

通常åQŒä¸»é¢˜ç”±å¾ˆå¤šä¸åŒçš„æ–‡ä»¶ç»„成,每个文äšg提供屏幕的特定区域的内容。尽½Ž¡å¯ä»¥åŠ¨æ€åœ°åŒ…å« JSPåQŒä½†é€šå¸¸åQˆä¹Ÿå»ø™®®åQ‰å°† JSP 静态包含在其他 JSP 中ã€?/p>

ç”׃ºŽ¾~–译时可能会ž®†å¾ˆå¤?JSP 包含到其ä»?JSP 中,所得的 Java 源代码和 Servlet 字节代码文äšg可能会非常大。ä‹É用大的类文äšg通常不会有性能问题åQŒä½†ç”׃ºŽ Java ¾~–程语言中包含的大小限制åQŒå¯èƒ½ä¸èƒ½å°† Java æºä»£ç ç¼–è¯‘äØ“¾c…R€‚例如,Java 中的æ–ÒŽ³•的大ž®ä¸èƒ½è¶…˜q?64KB。大型的复杂主题很容易达到这个限åˆÓž¼Œè€Œå¯¼è‡´ä¸å†èƒ½¾~–译。这¿Uæƒ…况下åQŒæœ‰ä¸‰ç§é€‰æ‹©åQ?/p>

  • 用动态包含代替一些(而非全部åQ‰é™æ€åŒ…含ã€?/b>

    å¦?JSP 部分 (LINK) 提到的,˜q™æ˜¯ç”¨æ€§èƒ½ä½œäؓ交换åQŒä»¥ä¾¿èƒ½¾~–译 JSP。从性能的角度而言åQŒå°½½Ž¡è¿™ä¸ªæ–¹æ³•最易于实现åQŒä½†å´æ˜¯æœ€ä¸å¥½çš„è§£å†Ïx–¹æ³•ã€?/p>

  • ž®½é‡é™åˆ¶ JSP ä¸?Scriptlet çš„ä‹É用ã€?/b>

    WebSphere Application Server 可以对仅调用标记处理½E‹åºçš„代码进行优化,而这可以有助于ä‹Éæ–‡äšg保持åœ?64KB 的上限之内ã€?/p>

  • 清除 JSP 代码ã€?/b>

    ˜q™äº›æ–‡äšg通常包含òq‰™žå¿…要的多余代码。通常删除 HTML 注释行或½Iºç™½åQŒæˆ–者将 JavaScript 代码¿UÕdŠ¨åˆ°å•ç‹¬çš„æ–‡äšg中均可保证èƒö够的½Iºé—´ã€?/p>

主题有时会完成应用程序中复杂的ä“Q务。不˜q‡æ­¤æ—¶åº”该è°}慎。请è®îC½åQŒå¯¹äºŽé—¨æˆïLš„æ¯ä¸ªè¯äh±‚åQŒéƒ½ä¼šå‘ˆçŽîC¸»é¢˜ï¼Œå› æ­¤ä¸è¦åœ¨å…¶ä¸­è¿›è¡Œä¼š¾l™ç³»¾lŸå¸¦æ¥é«˜è´Ÿè·çš„计½Ž—工作ã€?/p>

在模拟门户功能时要特别è°}慎。例如,主题可能会åó@环访问门户应用程序中的大量页面;应该å¯ÒŽ­¤˜q›è¡Œ½{›é€‰ï¼Œä»…向用户昄¡¤ºä¸€ä¸ªå¯¼èˆªç»“构,其中仅包含主题从门户 API è¯äh±‚的若òq²é¡µé¢ã€‚è¿™¿Uæƒ…况下åQŒé—¨æˆ·ä¸­˜q›è¡Œçš„å¾ˆå¤šå¤„ç†éƒ½ä¼šä¸¢å¤±ï¼Œå› äØ“ä¹‹åŽä¼šå°†å…¶ç»“æžœä¸¢å¼ƒã€‚æ­¤å¤„æ ¹æ®é—¨æˆ¯‚®¿é—®æŽ§åˆ¶æˆ–个性化规则˜q›è¡Œ½{›é€‰ä¼šæ›´äؓ有效ã€?/p>

此外åQŒè¦ž®½é‡é™åˆ¶é—¨æˆ·™åµé¢ä¸­é—¨æˆ¯‚µ„源链接的数量。门户必™åȝ”Ÿæˆçš„æ¯ä¸ª URL 链接都会¾l™ç³»¾lŸå¸¦æ¥é¢å¤–的负蝲。如果需要具有大量链接的应用½E‹åºä¸»é¢˜åQŒè¯·ž®è¯•¾~“存其中的一些页面,从而ä‹É其不必在每次è¯äh±‚æ—‰™ƒ½é‡æ–°è®¡ç®—所有链接ã€?/p>

主题也是 WebSphere Portal 中的˜qœç¨‹¾~“存基础¾l“构的一部分。主题的˜qœç¨‹¾~“存是一¾l„可以通过 XML 讉K—®å…·ä½“指定的元数据åQŒå¦‚以下½CÞZ¾‹ä¸­æ‰€½Cºï¼š

														
																<!-- Theme "shared" scope and 40 seconds cache expiration -->
<theme action="update" active="true" objectid="xmplTheme" uniquename="wps.theme.example">  
   <parameter name="remote-cache-scope" type="string" update="set">SHARED</parameter> 
   <parameter name="remote-cache-expiry" type="string" update="set">40</parameter>     
</theme>
														
												

主题不能提供ä»ÖM½•呈现时远½E‹ç¼“存信息ã€?/p>

WebSphere Portal 支持高性能外观的识别。这些外观非常特ŒDŠï¼Œå› äؓ它们不是åŸÞZºŽ JSP 生成的;它们的输出是æ ÒŽ®é¢„编译的 Java ¾cÕdˆ›å»ºçš„。当ç„Óž¼Œæ­¤ç±»å¤–观的可自定义性要差一些;只能å¯ÒŽ ·å¼è¡¨ä¿¡æ¯å’ŒåŒ…含的囑փ˜q›è¡Œä¿®æ”¹ã€‚不˜q‡ï¼Œå¦‚果性能是您要考虑的最重要的因素的话,ž®±åº”该考虑为页面上特定的元素或特定 Portlet 启用高性能外观。(请参é˜?a >参考资æ–?/font>中的信息中心以了解详¾l†ä¿¡æ¯ï¼ŒåŒ…括各种可帮助您¾~–写高速外观和主题的提½Cºã€‚)

工具

åœ?WebSphere Portal 应用½E‹åºå¼€å‘和验证的所有阶ŒDµå‡å¯ä»¥ä½¿ç”¨å„种工具提供帮助。本部分对不同开发周期中可以使用的不同工å…ïL±»åˆ«è¿›è¡Œäº†è¯´æ˜ŽåQŒåƈ提供了一些例子,以帮助您˜q›è¡Œè‡ªå®šä¹‰ä»£ç çš„开发和分析ã€?/p>

开发环�/font>

从技术角度而言åQŒå¯ä»¥ä‹É用ä“Q何文本编辑器¾~–写 Portlet、主题和外观åQŒä½†ä½¿ç”¨é›†æˆå¼€å‘环境(如将 IBM Rational] Application Developer å’?IBM Portal Toolkit ¾l“合使用åQ‰è¦æ–¹ä¾¿å¾ˆå¤šã€‚还可以使用 Portlet 代码½CÞZ¾‹å’ŒåŸºæœ¬é—¨æˆ·ä»£ç ç‰‡æ–­å¼€é€Ÿå…¥é—¨ï¼›è¯¥å¼€å‘环境还与一个门æˆähœåС噍˜q›è¡Œäº†é›†æˆï¼Œä»¥ä¾¿ç«‹å³éƒ¨çÖv和测试代码ã€?/p>

性能分析工具

当代码就¾lªï¼Œå¯ä»¥éƒ¨çÖvæ—Óž¼Œéœ€è¦è¯¦¾l†äº†è§£å…¶å¯èƒ½çš„æ€§èƒ½é—®é¢˜ã€‚可以采取若òq²æ­¥éª¤ï¼ˆä¸‹é¢å¯ÒŽ­¤˜q›è¡Œäº†æ€È»“åQ‰ï¼Œä½†æ€§èƒ½æ–šw¢æœ‰ä¸€æ¡å§‹¾lˆé€‚用的一般规则:在大多数½E‹åºä¸­ï¼Œ¾U¦æœ‰ 80% 的执行时间都花在 20% 的应用程序代码中。这 20% 的代码位于“关键èµ\径”上åQŒæ­£æ˜¯è¿™äº›æ–¹é¢å€¼å¾—˜q›è¡Œæ€§èƒ½ä¼˜åŒ–。例如,Portlet 的呈现方法要比其初始æ–ÒŽ³•çš„æ€§èƒ½å…³é”®æ€§æ›´å¼ºï¼Œå› äØ“æ¯ä¸ªè¯äh±‚都会调用呈现æ–ÒŽ³•ã€?/p>

  • 代码分析应在开发的早期阶段˜q›è¡ŒåQŒæˆ–ž®†å…¶ä½œäؓ开发后的第一个性能‹¹‹è¯•。分析意味着ž®†åœ¨æ–ÒŽ³•¾U§æ”¶é›†æ‰§è¡Œæ—¶ä¿¡æ¯åQŒé€šå¸¸ä¼šä‹Éç”?JVMPI 接口˜q›è¡Œæ­¤é¡¹å·¥ä½œã€‚分析器¾l“果可以帮助标识应用½E‹åºçš„关键èµ\径;卛_¤§éƒ¨åˆ†æ—‰™—´æ‰€æ‰§è¡Œçš„代码。分析器˜q˜é€šå¸¸ä¼šç»™å‡ºå…³äºŽå¯¹è±¡åˆ›å»ºé€ŸçŽ‡å’Œå†…å­˜ä‹É用的信息ã€?/p>

  • 一旦将 Portlet 部çÖvåˆîCº†é—¨æˆ·ä¸­ï¼Œž®±åº”该测è¯?Portlet 在负载下的行为。压力或负蝲生成器(å¦?Rational Performance Tester、Rational Robot、Apache JMeter ½{‰ç­‰åQ‰æ˜¯å…ähœ‰æˆæœ¬æ•ˆç›Šçš„负载测试解å†Ïx–¹æ¡ˆï¼Œå¯ä»¥å¸®åŠ©æ‚¨å‡†¼‹®åœ°æ¨¡æ‹Ÿç”Ÿäñ”负蝲下的¾pȝ»Ÿæ€§èƒ½ã€‚这些工具将攉™›†å¤§é‡ä¿¡æ¯åQŒä»¥å¸®åŠ©¼‹®å®š¾pȝ»Ÿæ˜¯å¦å…ähœ‰è‰¯å¥½çš„æ€§èƒ½è®¾è®¡åQŒå…¶ä¸­åŒ…括关于请求响应时间、处理器使用率等的数据ã€?/p>

  • 在负载测试期é—ß_¼Œåº”该监视门户环境中的若干性能参数。IBM Tivoli] Performance VieweråQˆä¸Ž WebSphere Application Server 一èµähä¾›ï¼‰å¯ä»¥å¸®åŠ©ç›‘è§†åº”ç”¨½E‹åºæœåŠ¡å™¨å†…çš„èµ„æºä‹É用情å†üc€?/p>

  • 门户环境的许多问题都和内存有兟뀂JVM 实现为工å…ähä¾›äº†ä¸¤ç±»ä¿¡æ¯åQŒä»¥ä¾›è¿›è¡Œæ€§èƒ½åˆ†æžåQ?/p>

    • 垃圾回收器的输出 verbose:gcã€?
    • å †è{储,发现内存泄漏旉™žå¸¸æœ‰ç”¨ã€?

    åœ?IBM alphaWorks 中可以得到垃圑֛žæ”¶å™¨è¾“出的分析工兗÷€‚而另一斚w¢åQŒheapRoots 则是一‹Æ‘Ö¼ºå¤§çš„å †è{储分析辅助工兗÷€‚《IBM Java 诊断指南》也提供了处理门æˆïLš„相关性能问题的有用信息。请参阅参考资æ–?/font>åQŒä»¥èŽ·å¾—˜q™äº›å‚考资料的链接ã€?/p>

å¼€å?WebSphere Portal 代码æ—Óž¼Œé€šå¸¸ä¸éœ€è¦æ‰€æœ‰è¿™äº›å·¥å…øP¼Œä½†è¦åœ¨ç”Ÿäº§çŽ¯å¢ƒä¸­æŽ¨å‡ºæ›´å¤§çš„é—¨æˆøP¼Œå¿…须从性能的角度对门户代码有个良好的理解ã€?br />

¾l“束è¯?/font>

创徏自定义门户代码时åQŒå¼€å‘äh员必™å»è€ƒè™‘很多斚w¢çš„因素,以确保门æˆäh€§èƒ½å¾—到优化。小¾l“如下:

  • ž®†ç²¾åŠ›ä¸»è¦æ”¾åœ¨å…³é”®ä»£ç èµ\径的改进上。关键代码èµ\径是处理旉™—´é•¿æˆ–频繁执行的代码èµ\径。找到哪些类的哪些方法位于关键èµ\径上。在关键路径外的优化效果相当ž®ã€?/p>

  • 要同时兼™å¾æ‰§è¡Œæ€§èƒ½å’Œå†…存分配ã€?/p>

  • 使用恰当的工å…ähµ‹é‡å’Œåˆ†æžä»£ç åQŒä»¥èŽ·å¾—æœ€å…¸åž‹çš„ç”¨æˆ·äº¤äº’ã€?/p>

  • 不同¾~–码问题解决æ–ÒŽ¡ˆå¯èƒ½æœ‰å¾ˆå¤§çš„æ€§èƒ½å˜åŒ–ã€?/p>

  • 必须全面了解处理发现的性能问题的特定实现的¾l†èŠ‚ã€?/p>

  • 设计自定义代码时要考虑后端讉K—®æ¨¡å¼ã€?/p>

  • ä¸è¦é”™è¯¯åœ°å°†ä¼šè¯ä½œäØ“ Portlet 的通用数据存储åŒÞZ‹É用。可以采用更好地æ–ÒŽ³•处理数据åQŒä»¥æ»¡èƒö各种不同的实现要求ã€?/p>

  • 考虑利用 WebSphere Application Server å’?WebSphere Portal 提供的特ŒDŠåŠŸèƒ½ä»¥ä¼˜åŒ– Portlet 性能åQˆå‡è®„¡›®æ ‡çŽ¯å¢ƒä¹Ÿåœ¨ä‹É用相同的功能åQ‰ã€?/p>



]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ÁúÃÅÏØ| аͶû»¢×óÆì| ÀÖÒµÏØ| ¿ËÀ­ÂêÒÀÊÐ| ³ö¹ú| ÑôÔ­ÏØ| ½õÆÁÏØ| ¿Ë¶«ÏØ| ÄÏľÁÖÏØ| ÌÀÔ­ÏØ| ʯÚäÏØ| ãò¶¨ÏØ| ɳƺ°ÓÇø| ̽Ë÷| ÕýÑôÏØ| ¶«ÁÉÏØ| ÒË´ºÊÐ| ÉÏÈÄÊÐ| È·É½ÏØ| ÁÙÈªÏØ| ¶õÖÝÊÐ| »¨Á«ÊÐ| Î÷³ÇÇø| ´ïÖÝÊÐ| Í©°ØÏØ| ÁéÊ¯ÏØ| ÓàÇìÏØ| ÎÞÎªÏØ| ½¡¿µ| ½¨ê±ÊÐ| ÈÊ»³ÊÐ| °¢ÈÙÆì| ÆÜϼÊÐ| ´óÒ¦ÏØ| ÁéÌ¨ÏØ| ¸£¹±ÏØ| µÂ»¯ÏØ| ¾¸Ô¶ÏØ| ÔªÊÏÏØ| ³µéÏØ| äü¹ØÏØ|