posts - 48,  comments - 14,  trackbacks - 0
Web Service 的故障处理会是一件很困难的事情,因为很多方面都会发生问题。这篇文章描述了你可能会遇到的各种问题,并说明应如何来处理它们。特别的,我们将讨论如下问题:

  • 回顾SOAP请求
  • 深入服务器端Visual Basic代码
  • 深入服务器端Visual C++代码
  • 跟踪SSL问题
  • 深入Favorites Service中的问题
回顾SOAP请求
当开发一个简单对象访问协议(SOAP)客户端应用程序或服务器终端时,有一大堆东西可能出错。例如,SOAP请求可能不符合Web Service 描述语言(WSDL)规范,或SOAPAction项是错的。为了调试这些问题,你需要一个工具来查看SOAP请求和消息交换。在Microsoft Windows平台上,你有两个很好的工具。如果你只是想要调试SOAP请求,你应该下载Microsoft SOAP Toolkit 2.0,得到SOAP跟踪工具(MsSoapT.exe)。当你想要查看整个HTTP信息,请去http://www.pocketsoap.com/下载tcpTrace。这两个工具是互补的。你应该怎样查看SOAP请求呢?
这两个工具都是通过截取并发送请求来查看SOAP请求的。要截取请求信息,你必须让你的客户端使用跟踪工具正在监听的端口。假定你在客户端用一个WSDL文件来建立调用,你必须将该文件装载到你的机器上,并编辑服务部分。在一台机器上,我们有一个Web Service ,它的服务部分如下:
<service name='ArticleDemo' >
<port name='ExampleSoapPort' binding='wsdlns:ExampleSoapBinding'>
<soap:address location='http://hopehubris/test/ArticleDemo.WSDL'/>
</port>
</service>

上面这个部分规定了ArticleDemo这个Web Service 的SOAP终端在http://hopehubris/test/ArticleDemo.WSDL默认的HTTP端口监听,即80端口。为了从该端口监听来往的消息,你必须编辑该文件以监听本机上另一个端口。要监听8080端口,你应将文件做如下修改并保存:
<service name='ArticleDemo' >
<port name='ExampleSoapPort' binding='wsdlns:ExampleSoapBinding'>
<soap:address
location='http://localhost:8080/test/ArticleDemo.WSDL'/>
</port>
</service>

经过以上改动,启动MsSoapT.exe或者tcpTrace.exe并告知它监听8080端口,然后将请求发向hopehubris的80端口(见图一和图二)

点击小图放大

图一 配置MSSoapT.exe

点击小图放大

图二 配置tcpTrace.exe
通过以上方法,你可以查看进出的请求了。当所有的通讯正常工作,你只需要调试SOAP消息时,MSSoapT.exe是一个很好的工具。图三中显示了正常的消息交换。

点击小图放大

图三 MSSoapT.exe中正常的交换
现在,我们来讨论怎样使用这些工具来调试问题。你可能经常遇到的问题是一个终端可能消失或者迁移了。利用一些良好的错误处理机制,你可以会发现问题,但是怎样确定是什么来往消息能够确认问题是由不存在的Web Service 造成的呢?对于这个问题,tcpTrace.exe能很好的解决。图四中显示了这种情况--你从服务器处得到响应,表示它对于你请求的终端不能处理。

点击小图放大

图四 使用tcpTrace.exe查看HTTP请求
当你开发SOAP客户端应用程序时,你可能发现产生了很多SOAP错误。可能的原因包含从传送坏数据到服务器端问题。有时候直接查看XML文件比将错误信息提取出来写进日志文件更容易。对于你产生的每一个错误,你会想办法让客户端去处理。但为了发现错误,使用跟踪工具是很有帮助的。查看原始XML文件,请使用MSSoapT.exe。为了显示它是怎样工作的,我们以一个SOAP调用为例,它将两个数字相加,并当地一个参数小于10时,强行返回一个SOAP错误。以下是5和20相加的SOAP请求:
<?xml version="1.0" encoding="UTF-8"standalone="no" ?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAPSDK1:AddNumbers
xmlns:SOAPSDK1="http://tempuri.org/message/">
<arg1>5</arg1>
<arg2>20</arg2>
</SOAPSDK1:AddNumbers>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

如果一切正常而且终端没有被破坏,我们希望返回25。但是,终端被破坏了,得到以下结果:
<?xml version="1.0" encoding="UTF-8"standalone="no" ?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>AddNumbers</faultstring>
<faultactor>
http://tempuri.org/action/Example.AddNumbers
</faultactor>
<detail>
<mserror:errorInfo
xmlns:mserror=
"http://schemas.microsoft.com/soap-toolkit/faultdetail/error/">
<mserror:returnCode>-2146828188</mserror:returnCode>
<mserror:serverErrorInfo>
<mserror:description>
The first number must be greater than 10
</mserror:description>
<mserror:source>AddNumbers</mserror:source>
</mserror:serverErrorInfo>
<mserror:callStack>
<mserror:callElement>
<mserror:component>Client</mserror:component>
<mserror:description>
The first number must be greater than 10
</mserror:description>
<mserror:returnCode>
-2147352567
</mserror:returnCode>
</mserror:callElement>
<mserror:callElement>
<mserror:component>
WSDLOperation
</mserror:component>
<mserror:description>
Executing method AddNumbers failed
</mserror:description>
<mserror:returnCode>
-2147352567
</mserror:returnCode>
</mserror:callElement>
</mserror:callStack>
</mserror:errorInfo>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

上面的错误提供了很多信息,可以帮助你发现问题的所在。从错误中可见,WSDLOperation组件发现AddNumbers方法失败。它还表明是客户端发生问题,而且问题是:第一个数必须大于10。图五中显示了MSSoapT.exe中这个错误是怎样的。

点击小图放大

图五 跟踪SOAP错误
这些工具还有很多用途。你可以用它们来分析SOAP请求和响应。有时候,Web Service只有一个客户端。如果你有客户端的源代码,你可以修改终端,让它可以通过跟踪工具。这样,你可以利用Microsoft SOAP Toolkit的底层API来反过来设计WSDL文件或构建客户端程序。

其他跟踪方法
MSSoapT.exe和tcpTrace.exe是查看SOAP请求甚至HTTP请求的优秀工具,但有的情况下,这些工具收效甚微。比如,如果你尝试发送SOAP请求给服务器,但是它的主机名不能解析,或者不能接受TCP连接,你就无法利用前面所述的两种跟踪工具了。另一种情况可能发生在你试图通过安全套接层(SSL)来进行SOAP通讯。MSSoapT.exe和tcpTrace.exe在SSL下是没有什么作用。所以,在这些情况下,可以使用以下方法:
  • Microsoft Network Monitor,它是监控网络数据包的一个管理工具。如果你安装了Windows 2000 Server中带的版本,你可以看到本机发送和接收的数据包。System Management Server中带的是完整版,它能够显示物理网络中所有的数据包。Network Monitor可以用来查看所有试图连接SOAP服务器的信息流。例如,当试图解析要连接的服务器主机名时,你可以看到DNS请求和响应。当与服务器建立连接时,你也可以看到TCP握手数据包。这可以告诉你TCP连接是否正常建立,还是服务器过早的重置了你的连接。你还可以看到数据包中的数据,这样就可以跟踪HTTP报文头和SOAP信封了,当然这在前面所述的两个工具中查看会更方便。Network Monitor不会显示发送到本机的数据流。而且,它虽然能够显示通过SSL连接的数据,但是那是加密的,所以查看其中的数据包内容是没有意义的。
  • 通过自定义的ISAPI ReadRawData and SendRawData Filter可以查看你的Web Service 器所有发送和接收的数据。这包括发向你的Web Service 的SOAP请求和响应。MSSoapT.exe 和tcpTrace.exe已经实现了通过ISAPI filter实现的许多功能,但有一个重要的例外:ISAPI filter可以查看SSL中传输的数据,因为它能工作在SSL加密/解密层之上。因此,如果你想要解决SSL中的问题,你可以看到其中HTTP和SOAP等数据。由于ISAPI filter处于较高的网络层次,你将看不到那些连接建立等Network Monitor提供的细节。想要知道如何编写ISAPI filter,请看开发ISAPI Filters一文。
深入服务器端Visual Basic代码
有时候,你需要调试你自己的代码以确定产生错误结果的原因。当调试Microsoft Visual Basic应用程序时,你必须按照KB:PRB:Error Occurs When You Debut a COM+ Component Under the Visual Basic IDE with an ASP Client中的步骤来处理。这篇文章只适用于Visual Basic集成开发环境下调试COM+组件。文章中第一条也适用于调试SOAP对象。为了节省你查看KB文章的时间,以下是其中一些相关内容的摘要:
1. 在DCOM中创建VB ASP Debugging项:
a. 打开写字板或其他文本编辑器,输入以下语句,这是大小写敏感的。
REGEDIT4
[HKEY_CLASSES_ROOT\CLSID\{70F214BA-94E2-4bdf-8F30-32CB4A905E4D}]
@="VB ASP Debugging"
[HKEY_CLASSES_ROOT\CLSID\{70F214BA-94E2-4bdf-8F30-32CB4A905E4D}\LocalServer32]
@="vb6.exe"
[HKEY_CLASSES_ROOT\AppID\vb6.exe]
"AppId"="{70F214BA-94E2-4bdf-8F30-32CB4A905E4D}"

b.将文件保存为Vbaspdbg.reg。
c.定位到保存该文件的文件夹,双击该文件(它会自动在Windows注册表中注册)。
2. 在DCOM配置中,将Everyone账号的许可加入Visual Basic ASP debugging中。
a.打开DCOMCNFG。在Start菜单中,按Run,在对话框中输入dcomcnfg。
b. 在Distributed COM Configuration Properties页面中,按Application标签,从列表中选择VB ASP Debugging,然后按Properties。
c. 在VB ASP Debugging Properties属性单中,按Securities标签,然后选中Use custom access permissions。按Edit。
d. 在Registry Value Permissions窗口中,按Add,然后加入Everyone账号,允许Allow Access。
e. 按OK,然后按Apply并退出Distributed COM Configuaration Properties页面。
注意,这样做会给你的系统带来一些安全漏洞。请不要在你实际生产或对外的机器上这样调试。
一旦完成以上步骤,当SOAP客户端调用COM对象时,你就可以调试它们了。如果重新build你的应用程序或设置断点时遇到问题,相关的COM对象可能已经在内存中了。要卸载这些对象,进入命令行,输入iisreset。它将使IIS和相关进程重启。在此过程中,DLL和COM对象就从内存中释放了。

深入服务器端的Visual C++代码
在服务器端调试Microsoft Visual C++?代码比VB要容易得多。Visual C++让你能够连接到正在运行的进程中,所以你只要连接到需要调试的DLL运行所在的进程,你就可以设置断点,单步调试等等。但也有一些要注意的地方,让我们来看一下其中一部分问题。
通常可以通过菜单操作,将Visual C++调试程序连接到运行的进程中去。在Visual C++编程环境中,选择Build,在选择Start Debug,然后再选Attach to Process。你可以看到Attach to Process对话框(见图一)并选择要调试的进程。一旦你连接上了,就可以打开源文件并设置断点,假如你的EXE或DLL的调试版本是在该进程中运行的,而且有debug symbol。

问题一:在对话框中没有进程列出!这是Microsoft Visual Studio? 6.0 SP3或更早版本中的bug,请使用SP4或更高版本。另一个方法是,请确定Visual C++是你的默认调试器,然后在任务管理器中点击右键,选中想要调试的进程并从弹出菜单中选择Debug。

问题二:对话框只显示了桌面上运行的程序!请确认你选中了Show System Processes。

问题三:我应该连接到什么进程?如果你有一个组件在IIS中使用(就像SOAP Toolkit 2.0中DLL组件),它们默认运行在dllhost.exe进程中。不幸的是,也许会有很多这样的进程,你就不知道你的DLL到底运行在哪一个之中了。如果你刚刚启动了一个dllhost.exe实例,想要调试,它会在Visual C++的Attach to Process对话框中列在最上面。如果你的应用程序已经运行了一段时间了,通常你可以通过任务管理器中Processest标签下查看你一个DLLHOST版本占用了大量内存和CPU,以次猜测出是该进程。但是,如果你想要精确的知道你的DLL运行在哪一个进程中,你可以使用tlist.exe这个工具,通过安装在Windows 2000的光盘中\Support\Tools目录中的支持工具就可以得到它。然后,你在命令行中可以输入:
TLIST -m mydll.dll

来得到加载了你的DLL的进程列表。你可以辨识出相应的dllhost.exe实例,然后连接上去。如果你的Web Service 运行所在的虚拟目录的应用程序安全性设置为低,它会在IIS的主进程inetinfo.exe中运行,而不是dllhost.exe。
我们开发Favorites Service时遇到的一个重要问题就是调试SSFKeyCache服务,它不在IIS进程或者DLLHOST进程之中。我们用ATL将SSFKeyCache创建为系统服务。当你在调试模式下编译COM server系统服务工程时,它被注册为普通进程外COM server。如果问题只发生在第一次调用COM server的时候就没有什么问题,但是如果像我们在SSFKeyCache中那样要保留调用中的信息,你必须将它驻留在内存之中。因此,为了调试它,我们将SSFKeyCache编译为调试版本,然后将其重新注册为普通系统服务。在命令行中运行:
SSFKeyCache -Service

然后,我们手工启动这个服务。请在命令行运行:
NET START SSFKEYCACHE

这样我们才能用Visual C++连接到运行的进程中,设置断点等等。如果不必要捕捉到SSFKeyCache组件第一个实例的创建,我们可以等待其他的调用,服务会自行启动的。

深入SSL问题
当通过安全套接层连接到Web Service 时,你会遇到很多问题。要诊断这些错误有时候是很困难的,特别是如果你只是从SOAP工具中收到一些普通的TCP连接错误。通常发生的有四个问题,其中的三个可以通过在IE浏览器中连接WSDL文件中指定的地址来发现。
SSL服务器证书没有安装。想要在你服务器上支持SSL,你首先要安装服务器证书。如果你没有安装,你不能连接到服务器上HTTP默认的SSL连接端口443。SOAP Toolkit 2.0会返回一个0x800A1518 (-2146822888)错误,表示连接错误。这也是其他三个SSL相关错误的错误代码。如果你在IE中试图浏览HTTPS开头的URL,你会得到一个标准的DNS出错页面。去掉"S"后再试一遍。如果你得到不同的出错信息,你就知道是服务器证书还没有安装。
URL中的主机名同服务器证书中的名字不匹配。当你为Web Service 器创建服务器证书时,你必须确定其中的名字同用户访问时URL中的主机名一致。如果不一致,当你用IE访问时,你会看到一个Security Alert对话框,如图六所示。当证书已经正确安装,但使用localhost指定本地计算机时,也常常看到这个问题。要避免这个问题,请将WSDL文件中location元素指定为你的服务器证书中所使用的名字。

点击小图放大

图六 IE Security Alert对话框,它表示证书同站点名称不一致

证书颁发机构不是受信任的机构。很多人都使用Microsoft Certificate Server来创建证书,安装到自己的机器上进行测试。这样可以比购买真正的得到全球广泛认证的服务器证书节约时间和费用。但是,当你成为自己的证书的认证机构时,网络中其他的机器并不信任你发布的证书。这些机器必须首先为你的认证机构安装根证书,然后才能通过安全套接层连到你的服务器。同样的,你可以通过在IE中用HTTPS URL指定Web Service,来确认是否有这个问题。如果证书颁发机构不是受信任的机构,你会看到和图6相似的对话框,除了左上角的图标会变成警告图示。你的认证机构的证书必须安装在想用SSL连接到你的服务器的所有计算机上。
该证书机构不在受信任的本机证书列表中。如果你在IE中连接到该Web Service ,没有看到Security Alert 对话框(即使重启IE也没有),但是你仍然无法通过ASP页面访问Web Service,这可能是一个更微妙的问题。当你安装证书认证机构的证书时,你可能将它加入到个人的证书认证列表中。而ASP页面是在IIS进程中的,不能访问你用户账号中的证书列表。为了使ASP页面能够通过SSL进行访问,请确定证书认证机构的证书是作为受信任的根证书安装在本机的证书列表之中。你可以打开mmc.exe,添加Certificates MMC插件并将证书认证机构的证书导入本机列表之中,成为受信任的根证书。这样问题就解决了。
关于Favorites Services中安装SSL功能的具体步骤,请查阅Installing the Favorites Service

深入Favorites Service 中的问题
如果你想使用Favorites Service并遇到了问题,你会怎么做呢?例如,你可能在登陆时会看到这样的消息:"Favorites现在不能使用。请您的网站管理员查看日志中的详细信息"。这时应该怎么处理呢?
首先,你应该按照消息中的指示去做。如果你在单机上进行了完整安装,那你就是网站管理员,所以你应该查看事件日志。Favorites Service(包括范例客户站点)在Application日志中记录事件,source是"Favorites Web Service"。出错消息如下所示:

点击小图放大

图七 Favorites Service日志范例
你可能注意到图七中描述框的内容还有待改进。我们现在没有提供更好的日志功能。由于日志功能是由VB写的DLL实现的,因此很难使用C++工具来定制日志中的格式化字符串。当日志查看器无法正确显示信息时,就将传递给日志的字符串显示出来。在这里就是"/ssf/logon.asp: Nonsecure Logon request attempted."。这表明有人试图通过非SSL的连接方式进行登陆,所以用户名和密码没有经过加密。而Favorites Service是不会接受非SSL传递的登陆请求的。
如果你怀疑你的日志中没有应该可以看到的日志记录,请你确认Application Event Log没有设置RestrictGuestAccess键。在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application中查看RestrictGuestAccess设置。默认状态下该键值为0,表示guess access是允许的。但是如果你对系统的安全性做过调整,或你的域安全策略在这方面有限制,那么这个设置会被启动。由于Favorites Service是运行在匿名账号下的,只有guest权限,如果RestrictGuestAccess设为1,你在事件日志中就看不到Favorites Service的事件了。
有时候,你除了日志信息外还需要一些其他的信息。例如,你可能收到一个加入喜好的请求,但产生了一个SOAP错误,你想要得到关于这个请求的更多的信息。Favorites Service有一个审计日志记录了它所有的活动供你查看。审计信息是存放在SSF-Report数据库中的AuditLog表中的。你可以使用SQL Query Analyzer或在Microsoft SQL Server?的Enterprise Manager中选择Return all rows查看所有的信息。Actiontype字段可以通过ActionType表以更友好的名字表示。而description字段中会包含与请求相关的额外信息。
怎样才能跟踪与请求相关的IP地址呢?你可能想要设置一些限制,或查看请求来自何方。审计日志中只告诉你时间,但没有IP地址。在http://www.coldrooster.com/,我们用IIS 日志来记录HTTP相关信息。为了跟踪日志记录中的请求的IP地址,我们要查看审计日志中的时间戳,在IIS日志中寻找相应的信息。通常在同一时间段中,不会有太多的请求同时发生。请记住,IIS日志默认是按格林尼治标准时间来记录时间戳的,所以你在做相应的查找时,必须做一些相应的时区转换。
最后一个我们要讨论的问题与web farm有关,就像http://www.coldrooster.com中:我们的Web服务器上不仅有Favorites Service的虚拟目录,还有其他的虚拟目录,如SSFPublic,coldrooster.com目录等。这使问题变得复杂,因为如果要查找一个问题,它可能发生在三台机器中的任何一台。同样,当一个错误的请求发送过来,并不确定是哪一个服务器来处理的。请注意,在一台单机上是很容易查找问题的,当与内部Web请求可能相关,要到其他机器上去寻找问题时,就会有问题了。要同步所有机器上不同的事件是很困难的,但并不是不可实现的。

小结
在这篇文章中,我们提供了一些Web Service故障检测和处理的方法,并以Favorites Service为例进行说明。这可以帮助解决一些你实际中遇到的问题。
posted on 2006-03-09 10:04 逍遥草 阅读(549) 评论(0)  编辑 收藏 引用 所属分类: Web Service
只有注册用户登录后才能发表评论。