65.9K
CodeProject 正在变化。 阅读更多。
Home

“故障排查”技巧——在远程 WCF 服务中

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2013年12月12日

CPOL

23分钟阅读

viewsIcon

21861

downloadIcon

114

了解如何在已部署的 WCF 服务中查找问题。

跟踪 WCF 远程请求 

先决条件   

  1. 在您的 IIS 服务器上安装了 .NET 4.5(您可以修改代码以使用 .NET 4.0) 
  2. Visual Studio 2012 Express(用于查看/编译/部署项目)
  3. Soap UI
  4. WCF 测试客户端 
  5. 服务跟踪查看器安装链接   
  6. 远程调试器软件 

简介

以下是 VS2010 对远程调试的支持(对于此演示,我们只关注 C# 的调试)。

在本博客中,我想向您展示如何使用跟踪来提供客户端和远程服务之间(包括远程服务之间的调用)的调用序列。

对于此跟踪部分,您需要以模仿远程调用的方式部署代码。为了便于设置,我将在本地 IIS 中创建另一个名为“RemoteService”的网站。我将把远程服务项目部署到此网站,并将本地服务项目部署到我的“Default Web Site”。我的客户端 (WPF) 应用程序将使用本地服务,本地服务将使用远程服务。因此,我将使用本地服务作为代理从客户端进行远程调用。

我设置的场景是,我的本地服务和远程服务都返回错误——其中一些错误是 WCF FaultException,另一些是更一般的异常(我在服务中使用了“DivideByZeroException”)。

IIS 设置 

在 IIS 中创建一个新站点(这将作为您的远程站点服务器位置)。从图 1 中您可以看到我将该站点命名为“RemoteService”,它将使用端口号 81(或您自己的 IIS 设置中下一个可用的端口号)。它将使用与您现有“Default Web Site”相同的应用程序池帐户——参见图 2。

图 1

图 2

项目结构 

如果您打开解决方案(图 3),您会注意到解决方案中有四个项目。一个用于客户端应用程序,两个服务和一个公共模型项目(这只是为了在服务项目之间共享数据结构)。

图 3

编辑配置文件中的跟踪部分(服务和客户端应用程序)  

远程服务 

右键单击配置文件并从上下文菜单中选择“编辑 WCF 配置”选项(图 4),使用 WCF 编辑器编辑配置文件。

图 4

远程服务设置

您可以在图 5 中看到远程服务的配置设置。下方是“System.Diagnostics”部分中配置设置的 XML 表示(图 8)。

图 5

确保您已启用跟踪设置(“Propagate activity”和“Activity tracing”),如图 6 所示。对服务和客户端应用程序配置执行此操作,这用于跟踪从客户端到远程服务的单个调用。您可以通过单击跟踪部分中的“Trace Level”链接来编辑跟踪设置。

图 6

通过单击“ServiceModelTraceListener”链接配置“Listener Setting”(图 7),并设置路径和文件名(我对每个服务和客户端设置都使用了相同的路径——并使用了唯一的 filenam,它告诉我其内容),还要启用时间戳复选框(如果您愿意,可以添加其他监听器属性——但最好也将它们添加到其他配置文件设置中)。

图 7
<system.diagnostics>
    <sources>
      <source propagateActivity="true" 
              name="System.ServiceModel" switchValue="Warning, ActivityTracing">
        <listeners>
          <add type="System.Diagnostics.DefaultTraceListener" name="Default">
            <filter type="" />
          </add>
          <add name="ServiceModelTraceListener">
            <filter type="" />
          </add>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing">
        <listeners>
          <add type="System.Diagnostics.DefaultTraceListener" name="Default">
            <filter type="" />
          </add>
          <add name="ServiceModelMessageLoggingListener">
            <filter type="" />
          </add>
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add initializeData="C:\Logs\LocalServiceTracelog.svclog" 
         type="System.Diagnostics.XmlWriterTraceListener, System, 
             Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
        <filter type="" />
      </add>
      <add initializeData="C:\Logs\LocalServiceMessages.svclog" 
        type="System.Diagnostics.XmlWriterTraceListener, System, 
            Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
        <filter type="" />
      </add>
    </sharedListeners>
    <trace autoflush="true" />
</system.diagnostics>
图 8 

本地服务设置

图 9

客户端应用程序配置设置 

图 10

编辑配置文件中的消息部分(服务和客户端应用程序) 

为什么要启用配置文件中的消息部分?.

基本上,您会希望看到用户数据在请求之间发送/接收(不是头信息,而是实际序列化的数据类,例如)。您可以深入查看返回的内容,以验证服务是否返回了正确的数据。

如果您查看图 5(远程服务)配置设置,会有一个名为“MessageLogging”的消息部分。在此部分中,您可以配置要记录的内容、位置以及跟踪级别。如果您单击“ServiceModelMessageLoggingListener”链接以弹出对话框(图 11),您可以设置日志文件的路径和文件名,同样,为了方便起见,我对所有消息日志记录都使用了相同的路径,这样当我查看它们时,我只需到一个文件夹。在生产环境中,情况并非如此,但您可以将消息或跟踪文件发送给您,以便在您的跟踪查看器中进行分析。

图 11

通过单击“Log Level”链接配置消息级别设置,以显示图 12 中的对话框。在这里您可以设置所需的日志记录级别,同样,如果您更改此设置,最好在所有服务设置之间保持一致(当在跟踪查看器中查看数据时,以便您能够一致地处理每个日志文件)。

图 12

部署服务 

注意:部署服务后,请务必在本地服务项目和客户端应用程序中更新服务引用,然后才能运行项目。

右键单击远程服务并从上下文菜单中选择“发布”以部署到您的“RemoteService”站点,将显示图 13,请注意,我没有将远程服务部署到“Default Web Site”,因为我想模拟远程站点部署(尽管在这种情况下在同一服务器上)。 

图 13 

部署本地服务  

图 14

部署服务后,您可以展开相应的站点并查看已部署的服务。下面(图 15)您可以看到部署在“Default Web Site”中的本地服务和部署在“RemoteService”站点中的远程服务。

图 15

运行客户端应用程序(从而生成跟踪和消息日志文件) 

在调试模式下编译解决方案(因为我们稍后会需要 PDB 文件),然后从 Visual Studio 内部运行应用程序或执行 WPF “ClientApp.exe”,以显示主窗体,如图 16 所示。UI 非常基本,它包含两个组框,带有触发对相应服务调用的按钮。返回的消息显示在下面的类似控制台的框中。通过运行按钮(从上到下),您将在相应位置创建跟踪和日志文件(图 22)

从本地服务获取有效数据 

图 16 
本地服务无效调用 

图 17
从本地服务捕获 FaultException 

图 18 
调用远程服务有效返回 

图 19 
调用远程服务方法 – 抛出异常 

图 20 
捕获远程服务故障异常 

图 21
图 22

如何在查看器中显示跟踪错误、警告和两者 

在打开任何跟踪文件之前,需要澄清的是,跟踪警告为黄色,错误为红色,同时包含警告和错误的服务调用将为红色文本,黄色背景(图 23)。

图 23

检查跟踪文件 

首先,我们将查看并逐一检查跟踪调用,以找出我们调用中的故障/异常(稍后我们将查看消息日志以验证每个服务返回的数据)。

双击“ClientTracing.svclog”文件以显示其跟踪内容。如果您选择活动窗格(图 24)并选择第一个警告(黄色行),这是一个对我们本地服务上的“InvalidLocalMethod”的调用。此服务抛回一个异常(DivisionByZero)图 25 和 26。但是,如果您查看此活动右侧的内容(通过选择警告条目),您将不会在其下方显示的跟踪详细信息中看到对特定异常的任何引用。有异常堆栈跟踪,但不够详细,无法让我们判断实际错误是什么。

图 24

图 25

图 26

返回故障异常

如果选择第二个警告(对“InvalidLocalMethodWirhFaultException”方法的调用)。并在左侧选择警告(图 28);您会注意到 FaultException 消息在跟踪详细信息中可见(图 29),这是方法返回的自定义错误消息。

图 27

图 28

图 29

从本地服务获取异常消息

第一个异常我们无法判断到底出了什么问题,但如果我们添加本地服务跟踪日志,我们将能够跟踪调用并返回,并提取错误消息。因此,将“LocalServiceTracelog.svclog”拖放到活动窗格中(图 30)。

图 30

现在请注意黄色和红色行(图 30);这是我们对本地服务方法“InvalidLocalMethod”的无效调用,如果您选择此行以在右上角窗格中查看跟踪(图 31)。

图 31

突出显示错误行(红色)以显示异常的详细信息(图 32)。请注意现在实际的错误,在下面的红色框中——“尝试除以零”。因此,我们现在已经找到了问题,稍后我将向您展示如何调试到您的远程代码并精确定位导致问题的确切行。但现在您已通过服务跟踪查看器中的两次点击快速确定了问题。

图 32

服务跳转到返回异常的远程服务

现在我们想看看远程服务上的异常是什么。在我们的代码中,本地服务调用远程服务方法“InvalidRemoteMethod”,但此方法返回一个异常。让我们看看我们的两个跟踪日志(客户端和本地)会得到什么!

选择对远程服务方法的调用,如图 33 中所示,以显示跟踪详细信息(图 34)。

图 33

图 34

选择警告(黄色)行以显示下面的异常详细信息(图 35)。请注意,我们收到返回到本地服务然后返回到客户端的通用错误消息。

图 35

现在,通过将“RemoteServiceTracelog.svclog”拖到活动窗格中,添加远程服务跟踪。活动窗格将添加更多调用,重新选择活动窗格中的相同警告。这次,左上角跟踪详细信息中现在有一个异常(图 36)。

图 36

选择该错误(红色)行,以获取从远程服务返回的错误消息(图 37),在本例中为“尝试除以零”。因此,我们现在已经从客户端跟踪到本地服务再到远程服务,并找到了错误方法及其相应的异常消息。

图 37

使用“图表”选项卡跟踪多个调用

执行与上述相同的操作,但使用跟踪查看器中的图表(选项卡)功能。如果查看器中只有跟踪文件,您会注意到“活动”窗格中有更多条目,它们将按顺序排列,但会有大量数据需要仔细研究。为了使这些数据具有一些顺序感,最好使用“图表”窗格来协调每个服务(从客户端开始)的调用序列。

使用图表调用“InvalidLocalMethod”

在活动窗格中,突出显示对“InvalidLocalMethod”的调用,然后选择图表选项卡以图形形式查看该条目(图 39)。

图 38

图 39

您会注意到异常图标,如果单击它,它将突出显示跟踪详细信息中的相应行,这反过来又会在其下方显示异常。因此,通过图表,您可以看到所有传入和传出调用都以正确的顺序进行——这是一种更容易可视化导致异常的序列的方法。  

了解消息日志选项卡

加载所有三个跟踪文件后,拖动名为“ClientMessages.svclog”的日志文件,以查看通过线路发送到/来自服务的数据。选择“消息”选项卡(图 40),然后选择第一个条目(对“ValidLocalMethod”方法的调用)图 40。此方法确实向客户端返回一个序列化类列表,我们希望查看该列表。

图 40

在右侧的跟踪条目中,选择“消息日志跟踪”行(图 41)。这将显示发送回客户端的数据。

图 41

选择“XML”选项卡(图 42)以查看发送到客户端的序列化数据。在这里,我们可以查看并验证从服务调用返回的详细信息是否正确。

图 42

请注意,某些调用下方有一空行(图 43);这是返回给调用者的内容。

图 43

跟踪异常的消息日志

这次,突出显示对方法“InvalidLocalMethod”的调用(图 44)。

图 44

突出显示错误(红色)行(图 45),以在下面的查看器中以 XML 格式显示内容(图 46)。请注意错误消息“Attempt to divide by zero”。

图 45

图 46

调试远程服务  

介绍  

这种方法最适合内部软件部门,团队安装软件并可以访问服务器和代码,或者开发团队希望通过设置生产环境(尽可能好)在内部测试生产问题,或者 QA 可能发现了一个您无法重现的问题,因此您现在可以调试到该 QA 的远程计算机并解决该问题。

为了解决这个远程调试问题,我们可以使用一个名为*远程调试监视器* (MSVSMON.EXE) 的小工具。它允许您从运行 Visual Studio 的另一台计算机(本地开发环境)运行、调试和测试在另一台设备(客户端计算机)上运行的应用程序。

对于我们的示例,在远程服务器上调试代码之前需要进行一些设置,在我们的案例中,我们将调试远程 WCF 服务。如果您还没有家庭网络,我建议在此演示中,在您的家庭环境中的两台计算机之间创建一个“家庭组”网络。XP 或 Win7 可以创建“家庭组”,但操作系统不能混用!

指定一台计算机作为您的主机,一台作为您的远程计算机。

远程服务器设置  

MSDeploy 3.0  

由于我们使用的是 HomeGroup,因此我们可以在远程计算机上安装 MSDeploy,以便您可以从本地 Visual Studio 环境发布远程服务,以及相关的 PDB 文件。  

创建新用户帐户(远程和本地电脑)

在“计算机管理”模块中,创建一个名为“WcfDebugger”的新用户帐户(图 47)并为其设置密码(记下密码,因为您需要在主机上使用相同的凭据)。

图 47

将此新用户添加到管理员组(图 48)。

图 48

用户组  

在远程计算机上,由于我们使用的是 MSDeploy 工具,请检查是否存在名为“MSDepSvcUsers”的用户组,如果没有,请创建此新用户组,并将“WcfDebugger”添加到用户组“MSDepSvcUsers”中。

远程调试软件 

您需要安装所需的远程调试软件,以便客户端可以连接到远程计算机。此软件可从此处下载:VS2012 Update 4VS2010 远程调试器。有关安装远程调试器的良好指南可在此处找到:这里

注意:如果您的远程计算机已安装 Visual Studio(显然不是生产环境),则您已安装远程调试软件:检查以下位置,更改为相应的 Visual Studio 版本和框架版本

“C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Remote Debugger\x64\ msvsmon.exe”

配置防火墙 

打开您的防火墙(图 49)并选择“允许程序通过 Windows 防火墙进行通信”功能。

图 49

您必须允许“Visual Studio 2012”通过防火墙访问(如果未列出,单击“添加另一个程序”并选择 Visual Studio 2012,图 50(或您的主机正在使用的 VS 版本),然后单击“添加”)。

图 50

确保选中相应的复选框(如果您创建了“家庭组”,则选中“家庭/工作(私人)”复选框,图 51)。

另外,请确保“RemoteDebugger”有权通过防火墙访问(相同设置)。

图 51

服务 

以下 Windows 服务应将“WcfDebugger”作为其启动用户(测试后恢复为原始用户凭据)

  • Visual Studio 10 远程调试器
  • Web 部署代理服务
  • Web 管理 

启动远程调试器 

安装远程调试器软件后,应该会有一个桌面链接或启动远程调试器应用程序(msvsmon.exe)。打开它时,您将看到图 52 中的图像。

图 52

您只需要确保配置正确,配置不多,但缺少任何一项都会导致无法调试。

通过点击“Ctrl + P”选择“权限”,并允许“已验证”安全性(图 53)。

图 53

通过点击“Ctrl + O”选择“选项”,并确保“WcfDebugger”是可用用户之一(图 54)。

图 54

单击“应用”并接受警告消息,确保选中“专用网络”选项(图 55)。

图 55

主机服务器设置  

  • 在您的主机上,创建具有相同密码的相同用户帐户(添加到管理员组)。
  • 在您的主机上安装 Visual Studio 2012(或 Express),您将从此调试远程服务器代码。
  • 以“Debug”模式编译整个解决方案,以便生成 .PDB 文件。
  • 远程服务项目部署到远程计算机的 IIS“默认网站”(确保也部署 PDB 文件)。
  • 更新本地服务项目以使用新的远程服务。
  • 重新编译本地服务项目。
  • 在远程服务方法中设置一些断点(这样我们就知道代码已被命中)
  • 在 Visual Studio IDE 中,选择“调试->附加进程”,并在“限定符”中输入远程 PC 名称(而不是 IP 地址),包括端口号。您可以从远程 PC 上的远程调试器监视器中轻松找到端口号。 

  • 单击“查找”,确保选中“显示所有用户的进程”复选框。

  • 向下滚动远程计算机中运行的可用进程,选择“w3wp.exe”,然后单击“附加”按钮,系统将提示您出现安全警告 – 单击附加按钮。

  • 然后您会注意到远程 PC 中的远程调试器监视器已使用您的附加请求进行了更新。

  • 由于您正在使用 Visual Studio 调试应用程序,因此您必须使用生成的 exe 文件运行应用程序。打开“ClientApp”项目的“Bin\Debug”文件夹并运行应用程序“ClientApp.exe”。单击其中一个远程调用方法(您已设置断点的方法)。您应该会注意到您的断点现在已被命中,并且您能够像在 Visual Studio 环境中本地运行所有代码一样逐步执行代码。

注意:在 IDE 中附加断点时,如果正在运行,它们将是实心红色圆圈。如果不是,则远程 PDB 文件与您的代码不同步(重新编译并重新部署远程服务)。 

不干预远程服务器的远程 WCF 服务测试  

介绍  

有时,由于客户站点的限制,无法在生产环境中安装远程调试器。那么唯一的选择就是实际调用远程服务并使用响应来确定错误问题。有几个工具可以使您的工作更轻松

我们将使用最初部署到 IIS 中第二个网站 (RemoteService) 的远程服务(图 56)。我们只需要 WSDL URL 即可测试服务。我选择了两种流行的(免费)工具来向您展示如何在不编写任何代码的情况下测试您的服务,以及我个人更喜欢哪一种。市场上有许多共享软件服务测试工具,但这两个免费工具同样优秀。

图 56

Soap UI   

创建 Soap UI 项目  

首先是 SmartBear 的 SoapUI。当您第一次安装并打开 SoapUI 时,您会看到主窗体(图 57)。

图 57

从这里,您将通过单击“文件-新建 Soap 项目”来创建一个项目(图 58)。

图 58

将我们远程服务的 URL(在我的情况下是 https://:81/RemoteService/Services/RemoteService.svc?wsdl)输入到第二个文本框中(项目名称将默认填充——但可更改)。

选中“创建请求”复选框(图 59),此选项将为您创建虚拟数据,这可能并不总是像您最初想象的那样有用,但我确实喜欢为我填充日期和时间字段(更多地是作为正确使用格式的指南)。

您会注意到“TestSuite”的复选框,如果您愿意,您还可以创建测试请求的集合(我将在以后撰写博客)——但对于免费工具来说,这是一个强大的功能。

单击“确定”,将显示进度条,因为 WSDL 正在被检查其签名方法(图 60)。 

图 59

图 60

运行服务方法   

WSDL 解析完成后,左侧将显示树形结构,它将代表您的服务方法。如果您展开一个节点,调用的默认名称是“Request1”。我经常将其重命名以包含 soap 请求中使用的参数(图 61)。

图 61

如果您双击“CallValidMethod”的请求,您将在右侧看到 SOAP 信封请求和结果(在我们的例子中没有参数,因此请求会自动发送)。但是,如果我们有参数,我们通常会更改参数并单击运行按钮(图 62)。在图 63 中,您将看到服务终结点的响应。

图 62

图 63

 检查故障异常的响应  

双击“CallInvalidMethodWithFaultException”的请求,您将在右侧看到响应(图 64)——您将看到我们为故障异常返回的硬编码响应。

<faultstring xml:lang="en-GB">来自远程服务的 FaultException。</faultstring>

图 64

检查一般异常的响应  

如果您运行方法 `CallInvalidMethod` 的请求,您将收到服务返回的通用响应消息。这就是 Soap UI 等工具的不足之处,要获取更多信息,您必须请求生产站点的管理员在服务的 *Web.Config* 文件中启用属性“IncludeExceptionDetailInFaults”。

服务器由于内部错误无法处理请求。有关错误的更多信息,请在服务器上启用 `IncludeExceptionDetailInFaults`(通过 `ServiceBehaviorAttribute` 或通过 `` 配置行为),以便将异常信息发送回客户端,或者按照 Microsoft .NET Framework SDK 文档打开跟踪并检查服务器跟踪日志。

使用 SOAP UI 传递参数

我添加了一个带参数的方法,只是为了向您展示发送到服务方法的请求信封的语法(图 65)。Employee 对象的类结构与字符串参数“Name”一起可见。

图 65

传入一个类对象数组后,服务方法的响应 (true)(图 66)。

图 66

注意:您必须复制并粘贴数组部分才能传入多个数组。

Soap UI 凭证

通常,在处理生产站点时,您需要为项目提供正确的 Windows 凭据,以通过站点安全设置,这可以在请求设置中完成(左下角)图 67。

图 67

WCF 测试客户端 

创建项目 

将 zip 文件解压到文件夹中,然后运行名为 WcfTestClient.exe 的文件。这将打开测试客户端的主窗体(图 68)。

图 68

通过点击“文件->添加服务”添加远程服务(图 69)。

图 69

输入与之前相同的远程服务 URL(图 70)并点击“确定”,将显示添加进度条(图 71)。

图 70

图 71

服务方法添加完成后,您将在左侧看到可用的方法(图 72)。

图 72

您会再次注意到与 Soap UI 项目中显示的方法相同,如果您双击方法“CallValidMethods”,然后单击左侧的“Invoke”按钮(请求服务方法)——接受警告消息(图 73)。然后您将看到服务调用的结果(图 74)。

图 73

图 74

返回故障异常  

双击服务方法“CallInvalidMethodWithFaultException”并点击“Invoke”按钮,您将看到错误对话框(图 75)——您会注意到异常本身中我们硬编码的错误消息“来自远程服务的 FaultException”。

图 75

返回一般错误消息 

双击服务方法“CallInvaldMethod”并单击“Invoke”按钮,以显示服务返回的通用错误消息(图 76)。同样,如果服务项目(在远程 IIS 服务器上)的 *Web.config* 中设置了属性,您将获得更好的错误消息。

图 76

向服务方法传递参数  

我快速添加了一个方法,该方法在其签名调用中带有参数,名为 `MethodWithParameters` – 命名恰当(图 77)。双击此方法以查看右侧窗格,现在它需要一个字符串和一个自定义类数组(图 78)。 

图 77

图 78

注意第二个参数期望一个数组,目前其长度设置为 0。

图 79

如果您将其更改为 1(图 79),然后展开参数,然后单击值字段,它应该显示相应类的下拉列表(图 80)。选择后,您会注意到类属性显示在其下方。

图 80

图 81 是“Invoke”调用的响应——返回布尔值 true。

图 81

编辑配置文件(实时) 

您可以编辑配置文件(不建议用于生产环境)。我这样做是为了扩展返回给客户端的缓冲区大小(图 82 和 83)。

图 82

图 83

WCF 客户端测试或 SOAPUI 总结 

简单来说,我会选择 SoapUI,因为它会在您保存项目时记住您为请求输入的参数。WCF Test Client 在输入类数组时有更好的 UI——但最终 SoapUI 的工作方式很容易理解,它都是 XML。此外,您可以在 SoapUI 中创建测试套件(下面我列出了发现结果)。

  • SoaupUI 会保留您输入的参数(保存项目后),而 WCF Test 则需要每次重新打开服务时重新输入参数(因为您无法将服务保存为项目)
  • Wcf Test 在输入数据数组方面拥有更友好的用户界面,而 SoapUI 则需要为每个数组条目进行剪切和粘贴 (XML) 操作。
  • SoaupUI 调用/异常不会显示在 Fiddler 中
  • WCF TestClient 调用/异常将显示在 Fiddler 中

有用链接

© . All rights reserved.