420 likes | 618 Views
J2EE 的潜在难点和最佳实践. Rachel Shen rshen@ca.ibm.com. Centre for e-Business Innovation ::Vancouver IBM Pacific Development Centre. Approach. Java 2 Enterprise Edition (J2EE) 和 WebSphere Application Server (WAS) 的功能是强大的 错误使用, 不充分使用或过度使用 会给你的应用和用户带来损害 透视点 项目 & 团队问题 体系架构问题 设计 & 实施问题.
E N D
J2EE的潜在难点和最佳实践 Rachel Shen rshen@ca.ibm.com Centre for e-Business Innovation ::Vancouver IBM Pacific Development Centre
Approach • Java 2 Enterprise Edition (J2EE) 和 WebSphere Application Server (WAS)的功能是强大的 • 错误使用, 不充分使用或过度使用会给你的应用和用户带来损害 • 透视点 • 项目 & 团队问题 • 体系架构问题 • 设计 & 实施问题
Java 2 Enterprise Edition • 一系列相关的规范 • 用于实现和部署企业应用的唯一标准 • J2EE 规范级别 • WebSphere Application Server 4.0 支持 J2EE 1.2 • Servlet 2.2 / JSP 1.1 / EJB 1.1 … • WebSphere Application Server 5.0支持 J2EE 1.3 • Servlet 2.3 / JSP 1.2 / EJB 2.0 … • J2EE 1.4 更多地关注Web Services. October/November, 2001 开始着手于关键的 JSRs • J2EE 1.3 向后兼容 J2EE 1.2 • J2EE是一个用于构建灵活的、易升级的、可信任的、易维护的企业应用的平台
项目和团队问题 • 甚至在你开始构建之前就已经陷入到麻烦中…
对技术如果不理解 • 有关的新技术 • 如果你不理解或者没有经验,就有可能错误地使用,或者冒项目失败的风险 • 一个糟糕的经验可能使你的系统瘫痪 • Java 和 J2EE 并不是“ silver bullet” • 使用Java同样可能建造坏的应用 • 正如你可以使用任何语言建造坏的应用:只是“坏”在不同的方面 • 你很容易构建出一个十分缓慢的J2EE应用 • 尤其是在你不理解分布式应用的时候
如何理解技术? • 什么是你的团队或你所需要的: • 培训 • 上课, 书籍, web 网站 • 这些都是一般的并是可供选择的 • 经验 • 实现过一个逐渐复杂的原型 • 参与其他项目 • 你的用户知道多少? • 也许这个更重要 • 他们将接管应用 – 他们真的有能力做这些吗?
开发和测试的环境 • 应该作为同一个产品 • 一样的硬件 • 如果规模不一样,至少应该是一样的拓扑结构 • 一样的软件, 一样的版本 • 一样的数据 (尽量少修改) • 存在一定的风险, 否则 • 不要假设! • 例如, 在 PDC 我们成功地在NT环境下开发 WAS 应用,并且简单地将其拷贝到 AIX 中的 WAS 下 • 但是首先我们不得不测试它
架构上的问题 • 如果你决定使用 J2EE… • 你将用多少? • 怎么用?
Controller View Model databases “Model-View-Controller” (MVC) • 表示与逻辑分开 • View – 表示:显示输入输出数据 (可以是 HTML,可以是一个 windows 应用) • Model – 业务逻辑和数据:基于输入和定义的业务流程执行计算 或其它操作 • Controller – 协调view 和 model,在它们之间交换数据
MVC 可以基于 Servlet • MVC 的隐含式 J2EE 实现 • View 由 JSP 和 HTML 页面组成 • Servlet 可以同时是 controller 和 model • 直接存取数据
Controller的两个选择 • control 必须用servlet 吗? • 以 JSP 为中心 – 所有的请求直接发送到下一个JSP,用以处理和输出 • 以 Servlet 为中心 – 所有的请求发送到 servlet进行处理,输出到JSP
让应用以 servlet 为中心 • 绝大多数采用以 servlet 为中心 • 以JSP为中心可以用于 2-3 页的小应用 • 典型地情况下JSP中有太多的Java代码 • 在业务处理之后最好让 servlet 决定使用哪一个JSP • 可以使用 JSP 重定向,但是容易引起混乱
servlets JSPs objects databases 将业务逻辑处理放在 Servlet 之外 • HttpServlet的子类应该仅做 servlet 份内的工作 • 管理 request、response 及 HttpSession 对象 • 将业务逻辑写在传统的Java类 • 仅传送普通的 Java 类,不是 servlet 相关的类(例如 request, response 或 session) • 少用或不用共享类变量 • 比 servlet 容易开发、测试和重用
servlets JSPs EJBs databases MVC 模型可以基于EJB • 另一个典型的 J2EE 方案 • View 由JSP 和静态 HTML 组成 • Controller 是 servlet • Model 是 EJB • 很象使用传统的 Java 对象 – 只是运行在远程
J2EE - Web 应用体系结构 JDBC Database Servlets Legacy Systems Interaction HTML Javascript Control C o Business n Logic n 3rd party systems e c Page t o Construction r - Java classes s - beans JSPs - EJBs
EJB 的类型 • Enterprise JavaBeans的两种类型: • Entity Beans • 代表数据 • 在服务器重启后仍然存在 • 可以通过EJB container (“CMP”) 或者程序 (“BMP”) 持续化到数据库 • Session Beans • 执行动作 • 等价于‘一般’的 Java object, 只不过是在远程 • 可以是 stateless (是原子操作), 或 stateful (在一个 context中执行一系列的操作)
你需要 EJB 吗??? • EJB 是很酷的,并很时髦, 但… • 问一下你自己 (1) • 你需要存取多个数据源来支持交易吗? • 你需要分布业务逻辑吗? • 你需要支持多种用户类型吗? • 在你的对象中需要方法级的安全性吗? • 你需要一个基于标准的体系结构吗? • “最好有” != “需要” • 如果至少有一个是 “yes”, 考虑 EJB • 只有最后两点并不意味你“需要” EJB
“To EJB or Not to EJB?”(5) • 认真地考虑 EJB 是否对方案有贡献 • 这些贡献是恰当的吗? • 任何基于servlet的应用可以转换成EJB’s… • 有些地方使用 EJB 有明确的好处 • 例如, 为整个区域服务的银行系统,同时使用基于Windows 和基于 Web 的客户来存取同一个应用 • 要记住: 对于一个基于 web 的应用,EJB 一般增加了相当的复杂性和费用 (不仅是 $, 而且在运行时间)
好吧, 如何使用 EJB? • 多数人的第一反映是将现有的每一个数据库表映射成一个Entity Bean • 该方法在一定条件下可行,但在多数情况下不应该这样处理 • 对于程序员这是一个短期的收益,但…
Entity Beans Are Expen$ive! • 当从用户端存取一个EJB… • 调用是远程的 • 甚至 getter/setter 也是远程的 • 远程调用比本地调用更昂贵 • 缺省情况,每一次调用一个交易 • 甚至对 getter/setter 方法 • 如果不小心, 从一个表取一行有 20 个字段的记录,可能有 20 多次的数据库交易! • 如果将这些方法设置为 ”read-only” 能部分避免这些 • 交易隔离级别的设定将使系统变慢 • 排他性存取数据是很好, 但是将独占资源
Entity Beans == Bad Design? • 有时是, 但当然不总是 • 当交易很重要时非常有用 • 例如,在两个银行帐户之间转帐, 或改变一系列用户的记录 • 对于持续化对象非常有用 • 首先设计对象,然后映射到数据库 • 直接映射数据库表的 entity bean 没有提供一个有用的抽象 • 如果你想直接和数据通信,为什么不用JDBC或者一个 databean 以避免EJB的开销?
尽量使用 Session Bean 代替 • 如果用户应用直接存取 entity bean, 是因为他们有太多的业务逻辑吗? • 考虑系统为你做什么,不要总考虑要和数据库中的表保持一致 • 作为代替,在 session bean 中实现业务逻辑,返回一个包含结果的传统的 Java 对象或者 databean • 一个远程调用 -> 一个交易 • 返回数据可任意处置
例如… • Kyle Brown 谈到一个案例(1) :用户设定系统中的每一个对象是一个 entity bean • 超过 200 个entity EJB’s • 在服务器启动的时候要花费好几个小时 • 他建议用户用session bean,返回简单的 Java 对象 • 减少到 20 多个entity beans • 服务器启动时间不超过一分钟
分离出逻辑… • Session bean 只做EJB的份内工作 • 将实际的业务逻辑放在传统 Java 类中,可以独立于EJB container 之外进行测试开发 • 就象我们对 servlets 的建议一样 • 从这些类存取 entity bean 或者 session bean, 能获得更好的性能 • 容器中的本地调用比远程调用快很多 • 所有对 entity bean 的调用可以在一个交易内! • 也就是说, 使用 session bean 作为 façade…
occasionally… Session Bean Façade Diagram
使用 Façade 的好处 • 在 EJB 环境之外比在其之内开发业务逻辑更容易 • 也更容易测试 • 对于存取同一个后台资源的应用,业务类可以重用 • 不仅限于 EJB • 例如, 控制存取遗留系统 (Legacy-system) 的类 • 粒度减少了远程调用的开销(4) • 细粒度的业务对象完成少量的工作,因为他们是本地调用,因此开销少 • session bean façade 方法应该是粗粒度的,一次完成更多的工作,它们是远程调用,因为较少调用开销也较少
EJB 总结 • 认真考虑 EJB 是否为你的方案带来好处 • 很容易“过度使用” entity bean • 明智地使用他们! • 使用 session bean 作为 façade • 将业务逻辑放在简单的 Java 对象中 • 使用传统的 Java 对象返回数据库中的记录 (通过 session bean)
设计和实施的问题 • 我们将开始有趣的部分,写代码! • 有更好的方法去做这些事情…
使用框架 • 大多数J2EE应用共享许多任务: • 日志, 数据库存取, 数据校验, 属性管理, 异常操作, 生成HTML… • 不要在每一个项目中重写这些 • 不要在同一个项目用不同的方法做这些! • 一个 “framework” 设定通用的方式去做这些工作 – 通过重用代码 (和技能!) • 可能是内部框架 (通过以前的项目) • 可能是外部框架(e.g. JADE)
尽可能缓存对象 • 可以被缓存并可以被所有用户共享 • InitialContext object • JNDI • EJB Home interfaces • 所有用户都一样 • 可以被单独的用户缓存 • Database resultsets • 例如,当你一次只显示部分数据时,缓存查询结果 • 可以在 servlet 中缓存, 可以在 session bean 中缓存
Servlet 技巧 • init()做尽可能多的工作 • 只在初始化是执行一次 • 尽可能少地使用 Synchronize • 确保不要 synchronize 整个类 • 不要用任何实例变量 • 将被所有在线的用户使用 • 不要使用SingleThreadModel • 虽然是 thread-safe, 但性能太差… • 对于非 Java 群体: 不要在 cookies 中存对象 • 使用 HttpSession代替
JSP 技巧 • 保持尽量少的Java代码 • JSP中的Java代码很难维护和测试 • 绝对不要将业务逻辑放在JSP中 • 编写 helper classes 从数据生成HTML • One of the few times putting hardcoding HTML in Java is ‘okay’ • 理想情况下只使用 “<%= ... %>” tags… • 在每一个JSP只包含用于显示数据的简单对象 • 有时称之为 “view bean”, 但不用是一个真的 JavaBean • 限定 JSP 只做显示工作, 抵制在其中编写的商业逻辑的诱惑
更多的 JSP 技巧 • 如果在页面中你要共享组件和项目, 使用如下表格 • E.g. 对于菜单, 标题栏, 页脚,等等 • 可以使用 HTML 或者 JSP include 指令 • 可以包括静态 HTML, 或者其它 JSP • 不要忘记在整个 JSP 中使用 try/catch • 如果在 JSP 中抛出一个异常, 它不能被 servlet 捕获 • 作为替代, 将所有有异议的代码放在头部, 将这一部分封装在try/catch 中
EJB 技巧 • 尽量将 session bean 写成 stateless • EJB container 会缓存stateless session bean • 尽可能明确删除 stateful session bean 以减少不必要的passivation • 对用户端, 不要直接存取 EJB • 将它们封装在一个简单的传统的 Java 类中,用以处理诸如contexts, home and remote interfaces,等等 • Basically an adapter… an adapter for a proxy! • 作为选择, VAJ/WSAD 可以向导式地创建 “access beans” • Similar idea, “makes an EJB look like a JavaBean”
JDBC 和数据库技巧 • 使用连接池 • 创建一定数量的数据库连接,共享它们 • 在使用任何资源之后释放它们 • E.g. Statements, Connections, ResultSets… • 因为”raw SQL”使用是需要重新编译,因此效率低 • 使用 JDBC 的 PreparedStatement 代替 Statement • 如果想更快 – 尽管移植性不好 – 使用数据库的存储过程 (Stored Procedure)
HttpSession 对象技巧 • 确保放在session 中的每一个对象要实现 Serializable (or Externalizable) • 不是必须的, 但在分布式应用中是一个好的方法 • 避免在 session 中存放大对象 • 手工使 session 无效 • Can only do this if application has explicit ‘log out’ function • 如果在JSP中不需要session,禁用它 <%page session=“false”%>
JavaScript 技巧 • 如果可能,在 HTML 中尽量少用 JavaScript • 使用单独的 JavaScript 文件,与 HTML 分开 • 可以被浏览器缓存 • 使 HTML 文件更小 • 可以被共享, 容易维护 • Stick to ECMA standard for JavaScript • Defines a JavaScript core that all major browsers support • Should reduce or eliminate differences between browsers • http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM • http://www.jsworld.com/ecmascript/
Java 技巧 • 关注内存漏洞和垃圾回收 • E.g. use StringBuffer instead of String • Destroy references as soon as you’re done with them • 减少 synchronization • 如果许多类实例可以并行运行那么这就非常重要 • 避免过度使用诸如 Vector和 Hashtable这样的类 • 实现 Externalizable,而不是Serializable • 程序员做得多,但运行是更快 • 对 EJB 和 RMI 很重要
XML 技巧 • 不要过度使用它 • 分析和消息的创建非常消耗资源 (DOM trees aren’t so fun) • 尽一切可能, 在系统间使用XML传递消息… • 没有必要在系统内使用它 • 只使用 data objects! • 尽快将 XML 转为 data objects • 将 XML 中的数据转为传统的 Java 类 • 可以使用工具 (e.g. GenX) • XML是用于传送, 不是处理!
最后注意: 优化… • 跟我重复: • 你不能调优一个坏的应用. • 你不能调优一个坏的应用. • 你不能调优一个坏的应用. • 你不能调优一个坏的应用. • 你不能调优一个坏的应用. • 你不能调优一个坏的应用. • 你不能调优一个坏的应用. • 你不能调优一个坏的应用.
参考书目 The following were pilfered in the making of this presentation… :-) (Specific references were highlighted throughout with superscripts.) • Kyle Brown, IBM, “EJB Best Practices: Architecture (Why EJB’s?)” D25WKGP4/25/A/IBM, galambos\techni1.nsf, "EBU - EJB Best Practices“ • Brian Waterworth, IBM, “eBusiness Java/WebSphere practitioner best practices” • Harvey Gunther, IBM, “WebSphere Application Server Development Best Practices for Performance and Scalability” (includes statistics!)http://www-4.ibm.com/software/webservers/appserv/ws_bestpractices.pdf • Daniel Steinberg, Review of conference talk by Martin Fowlerhttp://www-106.ibm.com/developerworks/library/j-con3.html • Humphrey Sheil, “J2EE Project Dangers!”, JavaWorldhttp://www.javaworld.com/javaworld/jw-03-2001/jw-0330-ten.html
参考 The following sites are considerable sources for ‘best-practice’ material: • WebSphere WorldAn IBM-internal site from Kyle Brown, one of the biggest WebSphere and J2EE gurus in IBM. Lots of presentations and white papers, with considerable emphasis on best-practices.http://websphereworld.raleigh.ibm.com/KylesWorld • WebSphere Performance and Technology TeamAn IBM-internal site from a team that specializes in making WebSphere sing and dance. Lots of articles, presentations and papers.http://wasperf.rchland.ibm.com • WebSphere White PapersA public IBM site with several years of white papers related to WebSphere. Not as extensive, since not all good papers are released publicly…http://www-4.ibm.com/software/webservers/appserv/whitepapers.html • Internal WebSphere Developer DomainOverall a great source of training and marketing materials.http://submit.boulder.ibm.com/wsdd/