gpt4 book ai didi

c# - 调用负载平衡的 Web 服务的偶发异常

转载 作者:太空狗 更新时间:2023-10-29 23:02:45 25 4
gpt4 key购买 nike

我有一个在三台负载平衡的 Web 服务器上运行的 Web 服务,但偶尔会出现错误。现在,我承认负载平衡部分可能有点转移注意力,但是当我只使用 1 个 Web 服务器进行测试时,我无法重现错误。如果我对所有三个 Web 服务器进行测试,我会得到错误(但它不是 100% 的时间,更像是 50%)。所有测试都是通过负载均衡器完成的,我们只需告诉负载均衡器我们想要部署多少台服务器。

代码是简单的单一请求代码。也就是说,没有状态。发出请求并返回响应。 Web 服务代码是在 IIS 7.5 上运行的 c# .NET 4。客户端代码既是网站又是桌面应用。

我得到两个异常之一:

System.ServiceModel.Security.MessageSecurityException: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail. ---> System.ServiceModel.FaultException: The security context token is expired or is not valid. The message was not processed.

或者我得到:

System.ServiceModel.Security.SecurityNegotiationException: Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint. ---> System.ServiceModel.FaultException: The request for security token has invalid or malformed elements.

正如您从我的 .config 文件的以下片段中看到的那样,我没有使用安全性,因为这严格来说是一项内部 Web 服务。 (名称已更改以保护无辜者——即我)。

服务器端:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Service Side web.config -->
...
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="InternalUseOnly.InternalUseOnlyServiceBehavior" name="InternalUseOnly.InternalUseOnlyService">
<endpoint address="" bindingNamespace="http://somecompany.com/webservices" binding="wsHttpBinding" contract="InternalUseOnly.IInternalUseOnlyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="InternalUseOnly.InternalUseOnlyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
...
</configuration>

客户端

<?xml version="1.0" encoding="UTF-8"?>
<!-- Client Side web.config -->
<configuration>
...
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IInternalUseOnlyService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://intranet.somecompany.com/InternalUseOnly/InternalUseOnlyService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IInternalUseOnlyService" contract="InternalUseOnlyService.IInternalUseOnlyService" name="WSHttpBinding_IInternalUseOnlyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
...
</configuration>

有什么想法吗?


附加信息:在查看下面的答案后,我尝试了两件事,但都没有成功。

最明显的变化(我一开始没有注意到)是更改客户端的一个属性以允许 cookie <system.serviceModel><bindings><wsHttpBinding><binding name="blah, blah, blah" ... other properties... allowCookies="true" />它默认为假。此外,我们的负载均衡器使用 cookie 来保持亲和性。但是,这并没有什么不同(还不知道为什么)。

接下来,我尝试了客户端 app.config 文件中的各种安全选项。这包括 <security mode="None" />和更详细的:

<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" />
<message clientCredentialType="None" establishSecurityContext="false" negotiateServiceCredential="false"/>
</security>

虽然最后一个设置只是我的猜测。我没有对 app.config 进行任何服务器端更改,因为我不知道要更改什么,遗憾的是,我只能在生产环境中进行测试,因为我们只有 1 个开发 Web 服务器,而不是三个。

最佳答案

我将在这里冒险并猜测所涉及的安全性是在客户端指定的消息安全性:

<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" />
</security>

如果您正在创建客户端并进行连接,则协商的 Windows 凭据 token 可能会被缓存。如果您没有启用粘性 session ,则 token 可能会传回错误的服务器并会失败。我的猜测是它总是在第二次通话中?

关于c# - 调用负载平衡的 Web 服务的偶发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6337350/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com