6

全部,

我有一个使用服务帐户(VM,Windows 2003 SP2)在 IIS 下托管的 WCF Web 服务(我们称为服务“B”)。该服务公开了一个使用默认值的 WSHttpBinding 的端点,除了 maxReceivedMessageSize、maxBufferPoolSize、maxBufferSize 和一些已增加的超时。

Web 服务已使用 Visual Studio 负载测试框架对大约 800 个并发用户进行了负载测试,并成功通过了所有测试,没有引发异常。单元测试中的代理是从配置中创建的。

有一个 sharepoint 应用程序使用 Office Sharepoint Server Search 服务来调用 Web 服务“A”和“B”。应用程序将从服务“A”获取数据以创建将发送到服务“B”的请求。来自服务“B”的响应被编入索引以供搜索。代理是使用 ChannelFactory 以编程方式创建的。

当服务“A”花费不到 10 分钟时,对服务“B”的调用成功。但是,当服务“A”需要更多时间(约 20 分钟)时,对服务“B”的调用会引发以下异常:

异常消息:从另一方收到不安全或不正确安全的故障。有关故障代码和详细信息,请参见内部 FaultException 内部异常消息:无法处理消息。这很可能是因为操作 'namespace/OperationName' 不正确,或者因为消息包含无效或过期的安全上下文令牌,或者因为绑定之间存在不匹配。如果服务由于不活动而中止通道,则安全上下文令牌将无效。为了防止服务过早中止空闲会话,请增加服务端点绑定的接收超时。

绑定设置相同,客户端服务器和 Web 服务服务器的时间与 Windows 时间服务同步,时区相同。

当我查看托管 Web 服务“B”的服务器时,我可以看到正在记录以下安全错误:

资料来源:安全

类别:登录/注销

事件编号:537

用户 NT AUTHORITY\SYSTEM

登录失败:

原因:登录时出错

登录类型:3

登录过程:Kerberos

身份验证包:Kerberos

状态码:0xC000006D

子状态码:0xC0000133

在网上看了一些博客后,状态码表示STATUS_LOGON_FAILURE,子状态码表示STATUS_TIME_DIFFERENCE_AT_DC。但我已经检查了服务器和客户端时钟,它们是同步的。

我还注意到安全令牌似乎缓存在客户端服务器的某个位置,因为它们有另一个进程使用相同的服务帐户调用 Web 服务“B”并在第一次调用时成功获取数据。然后他们开始更新办公室共享点服务器搜索服务索引的过程,但它失败了。然后,如果他们再次调用第一个进程,它也会失败。

有没有人遇到过此类问题或有任何想法?

问候,

——达米安

4

4 回答 4

5

10 分钟是默认接收超时。如果您的代理闲置超过 10 分钟,则该代理的安全会话将被服务器中止。启用日志记录,您将在服务器的诊断日志中看到这一点。您报告的错误消息适合此行为。在系统诊断文件中搜索“SessionIdleManager”。如果你找到它,上面就是你的问题。

试一试,为客户端和服务器设置建立安全上下文=“假”。

于 2009-07-02T19:07:15.533 回答
3

不要在 using 语句中调用服务操作。而是使用诸如...的模式

client = new ServiceClient("Ws<binding>")
try
{
    client.Operation(x,y);
    client.Close();
}
catch ()
{
    client.Abort();
}

我不明白为什么会这样,但我猜当代理超出 using 语句的范围时,不会调用 Close。然后服务等待直到 receiveTimeout(在绑定上)过期,然后中止连接,导致后续调用失败。

于 2010-06-03T17:02:33.263 回答
1

我相信这里发生的是您的频道正在超时(正如您所怀疑的那样)。

如果我理解正确,在您调用操作之前,不是对服务 A 的调用超时,而是服务B的调用。

我猜您是在调用服务A之前创建频道,而不是及时(即在调用服务B之前)。您应该在使用它之前创建通道(代理,服务客户端),例如:

AResponse aResp = null;
BResponse bResp = null;
using (ServiceAProxy proxyA = new ServiceAProxy())
{
   aResp = proxyA.DoServiceAWork();
   using (ServiceBProxy proxyB = new ServiceBProxy())
   {
      bResp = proxyB.DoOtherork(aResp);
   }
}
return bResp;

但是,我相信,一旦您解决了问题(服务 B 超时),您将意识到共享点应用程序的代理(称为服务A)将超时。为了解决这个问题,您可能希望将服务模型从请求-响应更改为发布-订阅模型。

对于长期运行的服务,您将希望您的 sharepoint 应用程序订阅服务 A,并让服务 A 在准备就绪时发布其结果 - 无论需要多长时间。

Juval Lowey 的 Programming WCF Services (O'Reilly) 有一个很好的解释,IDesign(Juval 的公司)发布了一套很棒的 WCF 编码标准,以及一个很棒的Publish-Subscribe Framework的代码。

希望这会有所帮助,阿萨夫。

于 2009-05-27T07:50:43.567 回答
0

我刚才实际上是通过做一些愚蠢的事情触发了这个错误。我有一个修改系统日期的单元测试,以测试一些基于时间的功能。而且我猜我创建上下文和调用我的方法之间的明显时间差(由于系统日期的更改)导致某些内容过期。

于 2010-09-08T01:59:01.570 回答