中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> Bea专区 > WebLogic Server 8.1
在WebLogic中诊断应用程序失败原因
作者:佚名 时间:2005-11-24 15:52 出处:互连网 责编:chinaitpower
              摘要:如何诊断复杂应用的故障原因。
  假设您正在设计和开发一个基于Web的高度复杂的应用程序。该应用程序可以为上万名,甚至上百万名客户提供服务。它将被部署在数百台服务器中。Web和应用服务器可以与多种第三方服务进行交互,更不用说访问内部和遗留应用程序以及向各种数据库发送查询请求了。进一步说,该系统需要使用大量的工具和框架(来自不同的软件厂商),以一种高度动态的方式执行不同的任务以及互操作。


  在标准的开发周期中,您将尽可能地收集所有已知的和必要的需求、执行系统分析、设计数据库模式以及定义集成点。诚然,在整个周期中,您需要遵循现有的最佳实践建议。所有这些只是应用程序设计的序曲。这个流程可能需要上千个人力小时(person-hour),以及需要通过上千个关键问题(或大或小)来跟踪。您非常自信,因为所有艰难的决策都已经预先考虑并得到改进,企业和外部开发合作伙伴中的独立团队制定的折衷方案都得到了解决。我们都对这个流程非常熟悉,一个需要天赋和毅力的流程。
  然后就可以部署应用程序了。
  但问题出现了。
  随着最初的恐慌逐渐褪去,您开始进入筛余流程。不幸的是,您总是不知道为什么应用程序会失败,因为谁而失败,或者失败的确切原因。您的应用程序用户可能主要来自日本,但是您的服务器存放在亚利桑那州,其支持团队位于美国东海岸,而开发团队位于加利福尼亚州。这个简单的事实说明了即使确定发生了什么事情也需要花费几天或者几周的时间,更不用说判断问题对应用程序用户的影响了。
  WebLogic是当今市场中复杂J2EE应用程序的最佳平台之一。它使应用程序的开发、部署和管理极其方便。但是,应用服务器本身仅可以解决应用程序生命周期内非常常见的问题。当今复杂应用程序的实现通常需要更优秀的诊断功能,特别是在后期生产阶段。

问题
  在反复考虑了这个问题之后——因为bug、小故障、服务中断或其他问题而失败——应用程序体系结构将最终决定需要重新关注他们的优先权,以更好地预测生产诊断。毕竟,医疗社区教给我们:预防比治疗更加简单有效。这条经验同样适用于软件开发。为解决问题积极准备比等待问题出现更为有效。但是问题是,当进入治疗阶段的时候,如何避免耗时的应用程序筛余,尤其是当应用程序已经发售和被客户使用的时候?
  这就需要诊断子系统的设计包含以下特点:
  • 为各种类型的消息记录可描述的和统一的日志:记录的日志应当不仅仅包含应用程序本身,还应当包含应用程序可能访问的所有服务和组件。这些消息的记录应当基于一种通用的日志记录框架、应用程序代码调试器和二进制代码调试器,以及把可能的第三方组件日志数据标准化为一种使其可以关联从本机日志框架中发送来的消息的格式。
  • 消息的恰当粒度:当出现错误的时候,精确定位导致问题出现的组件以及掌握服务中断对用户的影响非常重要。能够详细地排除每一个应用程序模块的故障也非常重要,不管应用程序固有的复杂性程度有多高。
  • 高度灵活的日志记录配置:易于使用和描述性地查看由不同管理组件收集到的数据。在故障排除阶段,我们需要把已经分析的数据控制在一种可以管理的数量下。被大量的数据所湮没的情况很常见,但是仍然会丢失对相关信息的跟踪。有用性对每一种应用程序日志记录策略的成功来说至关重要。没人希望使用杂乱的数据,而且不便于收集。对于应用程序的所有支持层来说,智能化的从筛余逐级提升到问题解决方案非常重要,可以筛选出不相关的信息。最终,以一种可以管理的数量来交付相关的信息也至关重要,因此,下一阶段的支持可以开始致力于在不增加额外请求的情况下解决问题。
  • 支持前摄性问题确定和解决环境的能力:通过实时报警和通知(电子邮件、IM等)。
  • 日志数据的强大集成:借助事件跟踪系统,包括描述性报告和视图。
  • 支持问题反复挖掘的能力:今天运行任何的业务都需要符合高质量的标准,这不仅仅是修复bug所要求的,而且是判断这个bug的含义所要求的。这包含了揭示问题的每一个方面,关联问题和所有受影响的用户,以及向用户提供必要的服务。这个目标通过高度可调整的查询和数据挖掘工具得以完美解决,从而使访问应用程序收集到的所有日志信息变得更加轻松。

解决方案
  现今最常见的筛余问题确定解决方案是普通日志。通常,应用程序架构师会选择这样一种日志记录策略,即开发人员用来从应用程序代码直接发送日志消息给事件记录子系统。很可能使用公开可用的日志框架,诸如log4j或者java.util.logging,或者内部开发一种框架。无论采用何种方法,统一所有应用程序中的日志框架,以及把不同记录器的输出统一成通用格式是非常重要的。例如,使用log4j可以轻松地标准化日志记录基础架构、创建记录器的分层架构、通过appender扩展日志记录子系统和管理日志源。可以控制每一个记录器的输出并把他们回馈到单个可以搜索的存储库中,以及保留所有重要的结构化数据(如时间戳、服务器和应用程序名称、组件名称等等)非常关键。此外,如果应用程序使用了第三方组件和服务,那么可以搜索这些日志也是一种最佳实践。使用这种方法,将应用程序报告的问题和这些日志中的记录关联起来就成为可能了。
  问题是:在应用程序代码中自始至终都遵循日志策略和日志消息是否可能?一套精心设计的日志子系统不可能解决复杂应用程序中所有可能出现的故障点,而没有被日志数据湮没或者应用程序代码在诊断调试器中过度加载的风险。即使再谨慎设计的日志层都会在划分与“noise”问题相关的信息时显出不足。幸运的是,使用按需自动化编码调试器来构建一款动态的日志解决方案是可能的。目前有很多工具和框架都允许以不同的方法来调试代码:从使用面向方面的切点的源代码扩展到使用BCEL(或者借助其他工具,如OC Systems的Aprobe)的字节码修补。通过把日志数据削减到理想的数量,这些技术解决了架构师或开发人员在应用程序生命周期的每一个阶段中所关心的问题。使用上述工具或者具有同等功能的技术,开发一套组件(或者探测器)来解决应用程序中出现的不同类型的问题并仅在必要的时候将其仅应用到应用程序的重要部分就变得非常轻松了。换句话说,调试器在组件层和代码层都实现了必要的日志粒度。同时,代码的复杂性保持不变。因此,开发人员可以清楚的从真正的业务逻辑中区分出诊断任务,这些业务逻辑使任务在应用程序代码中松散地耦合。
  企业基础架构问题的另一方面(很可能是最神秘的方面)是应用程序用户的行为,我们需要解决这个问题。通常可以使用案例来描述打算如何使用应用程序的众多情景,但是总会出现一些难以预料的案例——用户发现了一种可以绕过受测试路径的方法,但是却遇到一个应用程序错误。这就是为什么在所有的日志任务设计和实现期间综合用户会话环境是如此重要了。现代应用服务器都是精心设计的,可以孤立并发的用户与其他用户以及用户执行的操作。WebLogic Server被证实为市场中最快的J2EE服务器,意味着它可以高效地管理底层硬件资源,如内存、线程和套接字。然而,编写得极为糟糕的应用程序会严重影响甚至是最优秀的应用服务器的性能。
  从版本2.3开始,servlet规范为用户环境问题解决方案提供了一条很好的线索。在“筛选”一节中,我们可以找到一种优秀的日志和审计过滤器理念。它可以帮助架构师、站点管理员和应用程序支持人员判断需要记录多少有关用户交互的信息。Servlet 2.3过滤器允许您清空某些请求字段和参数,以及响应部分,而不必对servlet和 JSP做任何修改。例如,TeaLeaf Technology的J2EE过滤器收集有关请求参数、属性和其他特定请求数据,以及整个响应部分的信息,并把它写入到TeaLeaf RealiTea服务器中,用于存储和后期处理。随着数据的收集,过滤器创建惟一的环境标识ID,下游组件在绑定额外日志数据时可以重用。惟一的ID创建一种环境,可以用于在所有应用程序组件之间分组日志活动,它允许用户隔离产生问题的会话,并重复导致问题产生的步骤。

使所有的日志记录技术共同工作
Servlet 2.3 API过滤器
  Servlet 2.3规范把过滤器作为servlet容器的一个整体部分而引入。规范本身声称过滤器是记录不同类型用户交互的理想方法。但是寻找一种如何进行该类日至记录的恰当实例仍旧非常困难。为了不使大家陷入其他文章的大量细节当中,我们推荐的日志框架准备使用Servlet 2.3过滤器,这出于以下目的:

  • 记录请求信息。
  • 记录响应信息。
  • 引入一种惟一的命中ID,这种ID将传递到WebLogic internal tracing API中。

  上述的每一个步骤都非常直接,基于通过调用请求对象的方法、打包响应对象、支撑输出流、生成全球惟一命中ID(很可能基于惟一的硬件属性,程序将在该硬件中运行,并在出现调用时与精确的移动结合在一起)的数据收集,最后通过调用WebLogic tracing API把这个ID添加到正在运行的线程中。

weblogic.trace.Trace.beginTrace(uniqueId); // uniqueId

  上面是为每一次命中所创建的字节数组。

WebLogic跟踪
  WebLogic内部跟踪允许用户在整个呼叫链中把字节数组数据传播到单个JVM或者多个不同的JVM中。如前所述,我使用这种特性来关联每一个具体的Web站点命中和在生成适当的响应时下游组件执行的全部的调用。换句话说,它是一种在应用程序中,任何方法单一功能调用,这个功能可以获取调用方法运行的确切Web命中信息。

byte uid[] = weblogic.trace.Trace.currentTrace();
//retrieving hit id recorded on previous step


测试
  现在可以使用工具(如BCEL、OC Systems的Aprobe或者AspectJ)来测试应用程序的具体部分和日志消息,从而为日志添加动态特性。日至消息需要从前一节中讲述的跟踪环境来获取命中ID,并添加所需的任何信息。诸如Aprobe或者AspectJ等工具允许在开发人员希望通过一种有用的方式来插入日志消息的地方定义切点。例如,在Aprobe中,回调类支持业已公布的接口和一些需要测试的方法。在AspectJ中,只有切点定义和代码将被插入到指定的方法中。

Glue
  整个基础架构中最后,也最重要的组件是存储全部数据的系统,这些数据将由全部的记录器记录,并且可以查询。您可以选择不同的策略,从在文本文件中存储数据然后导入到关系型数据库中,到直接记录到数据库中或者使用优化的记录解决方案(如TeaLeaf RealiTea),它允许实时存储和查询数据。“Glue server”非常重要,因为通过servlet过滤器来跟踪我们插入的环境,通过WebLogic跟踪来传播以及被日志代码使用,这些将仅在一个中央位置上变得相互关联,在那里你可以关联来自机器A上托管的servlet数据和来自机器B上托管的EJB数据。

实际情况
  让我们假设我们的应用程序部署在几个集群节点上。在成功地运行了一段时间之后,我们突然收到复制子系统发出的几份串行通知。
  这些消息包含了一些对象无法串行化的信息。使用标准的日志来提供对该问题的确切环境的深入观察。我们不知道servlet或者JSP代码试图在会话环境中插入什么无效的属性,或者更为重要的是,哪一个对象无法实现串行化。为了模拟上述的问题,我们可以使用一些简单的代码块来简单地计算对页面的访问,在其每一次被访问时为会话环境插入一个串行化的对象,增加计数器,并且仅在#3命中时它会插入一个拥有非串行化成员的对象:

<%@ page import="dummy.*" %>
<%
Integer i = (Integer)session.getAttribute("counter");
int iv = (i==null)?1:i.intValue()++;
session.setAttribute("counter", new Integer(iv));
if(iv==4) {
session.setAttribute("BADAT
TRIBUTE", new MyData());
}
%>
<html><body><h1> Counter = <%=iv%></h1></body><html>


  让我们把示例变得更加复杂一些,使MyData的一个成员(MyInternal)非串行化:

package dummy;
import java.io.Serializable;
public class MyData implements Serializable {
String str = "dummy string";
MyInternal mi = new MyInternal();
}
And MyInternal source code:
package dummy;
public class MyInternal {
Object o = new Object(); // this is
non-serializable member
String str = "string";
}


  实际的情况可能更加复杂——动态的页面代码可能更加复杂;会话属性插入可能不够直接;应用程序可以使用控制器来粘合不同的表示、模型和数据访问组件。所有这些都会显著地增加问题诊断和解决的复杂性。
  为了解决问题,我们可以使用TeaLeaf的过滤器组件并结合WebLogic的跟踪功能和代码测试。所需要的步骤就是在应用程序中安装过滤器(每个应用程序只能执行该步骤一次),使WLS运行使用跟踪(Dweblogic.TracingEnabled=true),以及配置测试补丁。这种情况中的过滤器将执行以下任务:

  • HTTP 流量日志记录(请求和响应数据返回到客户端,包括 HTML/XML);
  • 为从servlet中调用的应用程序servlet和下游组件创建和绑定跟踪环境;
  • 将所有数据反馈给TeaLeaf RealiTea Server,允许用户会话重新进行,并使整个会话可以实时搜索和访问。相反,RealiTea Server可以把所有的数据以日志文件的格式记录到本地服务器上。

  WebLogic跟踪提供了日志代码和测试补丁以及惟一的环境标示符,任何的下游组件都进行访问,并且在RMI调用的情况下,可以跨JVM边界来传播环境。
  对于这个例子中的代码补丁,很可能使用OCSystems的Aprobe、BCEL,甚至是AspectJ。主导思想是如果它是串行的,就需要在写入流(weblogic.common.internal.RemoteObjectReplacer.replaceObject)之前添加额外的方法验证以确认每一个对象,如果它是非串行的,就执行事件发布。

...
if(returnValue instanceof Serializable)
return;
...


  在验证时,使用WebLogic tracing API来释放当前的调用跟踪环境,并把日志消息加入到过滤器记录的请求/响应数据中是非常必要的:

byte b[] = weblogic.trace.Trace.currentTrace(); // get logging context
if(b!=null && b.length==64) {
sid = new String(b,0,32); // get unique session id
hid = new String(b,32,32); // get unique hit id
// record an event with your favorite logging API
logger().error(sid, hid, "SERIAL_FAIL",
SymbolTable.getPrintableMethodName(super.methodId));
}
...


  最后,我们需要测试应用程序,并让其运行。在执行了有四次命中的会话之后,我们可以发现以下被记录的信息(假设我使用RealiTea Viewer、TeaLeaf Event API和捕获过滤器,参见图1):


  现在,我们会发现问题正好出现在这次会话的第四次命中上。我们还可以清楚地看到,无法串行化的对象是MyInternal类的实例,并且所有通过浏览器发送到WebLogic Server以及servlet 生成的请求和响应数据可以通过过滤器自动捕获。简而言之,我们可以轻松地发现同一问题影响到的每一位用户(参见图2)。

结束语
安装好日志过滤器,并运行在您的生产服务器上和您的集中式日志系统中,结合自定义的日志测试,这些将显著地缩短诊断严重应用程序问题所需的时间。通过初始化前摄性的警告和通知来对复杂的Web应用程序实施不间断监控,还可以进一步加强该过程。另一方面,用户交互的完整记录不仅可以帮助解决技术问题,还可以帮助解决业务问题和应用程序失败如何影响站点的全部用户这一问题。

原文出处
http://www.sys-con.com/story/?storyid=42977&DE=1

 作者简介
Vitaliy Stulski是TeaLeaf Technologies的一名Java开发人员和架构师,TeaLeaf Technologies是一家帮助企业确保其Web应用程序精确性的解决方案提供商。他在设计和开发基于J2EE平台的大型的、高度可伸缩的、分布式的企业应用程序方面具有丰富的经验。Vitaliy还有几年BEA产品方面的经验,特别是在WebLogic Application Server。Vitaliy拥有白俄罗斯明斯克大学数学学士学位。
关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有