2011-06-13 52 views
5

Tengo un servicio web que estoy ejecutando en tres servidores web con equilibrio de carga y recibo errores esporádicos. Ahora, admito que la parte de carga balanceada puede ser una pista falsa, pero cuando pruebo con solo 1 servidor web no puedo reproducir el error. Si pruebo con los tres servidores web, puedo obtener el error (pero no es el 100% del tiempo, más como el 50%). Todas las pruebas se realizan a través del equilibrador de carga, solo le informamos al equilibrador de carga cuántos servidores queremos explotar.Excepciones esporádicas al llamar a un servicio web con equilibrio de carga

El código es simple código de solicitud individual. Es decir, no hay estado. Se realiza una solicitud y se devuelve una respuesta. El código del servicio web es C# .NET 4 ejecutándose en IIS 7.5. El código del cliente es tanto un sitio web como una aplicación de escritorio.

consigo una de las dos excepciones:

System.ServiceModel.Security.MessageSecurityException: Un no garantizada o asegurada de forma incorrecta culpa fue recibida de la otra parte . Consulte la FaultException interna para conocer el código de error y los detalles. ---> System.ServiceModel.FaultException: El token de contexto de seguridad ha expirado o no es válido. El mensaje no se procesó .

O me sale:

System.ServiceModel.Security.SecurityNegotiationException: Canal seguro no se puede abrir porque negociación de seguridad con el extremo remoto ha fallado. Esto puede se debe a ausente o incorrectamente EndpointIdentity especificado en EndpointAddress utilizado para crear el canal . Verifique que EndpointIdentity especificado o implícito por EndpointAddress correctamente identifica el punto final remoto. ---> System.ServiceModel.FaultException: La solicitud de token de seguridad tiene elementos no válidos o mal formados.

Como puede ver en los siguientes snips de mis archivos .config, no estoy utilizando la seguridad ya que este es estrictamente un servicio web interno. (los nombres han sido cambiados para proteger a los inocentes, es decir, a mí).

el lado del servidor:

<?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> 

lado del cliente

<?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> 

Pensamientos alguien?


Información adicional: Después de revisar las respuestas a continuación he intentado dos cosas, ambas sin éxito.

El cambio más obvio (que no noté al principio) fue cambiar una de las propiedades en el cliente para permitir las cookies <system.serviceModel><bindings><wsHttpBinding><binding name="blah, blah, blah" ... other properties... allowCookies="true" /> Por defecto es falso. Además, nuestro equilibrador de carga usa cookies para mantener la afinidad. Pero, no marcó la diferencia (aún no se sabe por qué).

A continuación, probé varias opciones de seguridad en el archivo app.config del lado del cliente. Esto incluye tanto <security mode="None" /> y una más elaborada:

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

a pesar de los ajustes en el último fue sólo una conjetura de mi parte. No realicé ningún cambio en el servidor de la aplicación.config ya que no sé qué cambiar y, por desgracia, solo puedo probar con la producción ya que solo tenemos 1 servidor web de desarrollo, no tres.

+0

Utilizando CRM2013 y la clase CrmConnection de Developer Extensions, nos encontramos con el mismo problema hoy en día con un servicio web WCF que no tiene carga equilibrada. Fue en el pasado, pero lo desactivamos para eliminar el equilibrio de carga como una fuente de error. Antes de recibir estos errores, recibí muchos abortos de conexión (consulte aquí https://stackoverflow.com/questions/25644847/frequent-connection-aborted-exceptions-when-using-crm-2013-organization-service). Todavía no puedo resolver estos problemas, ¿tienes alguna idea? –

+1

@MichaelBarth Lo siento, no, no. – Jim

+0

Lástima, pero gracias por la respuesta :) –

Respuesta

1

Mientras que Chris y Jeff me ayudaron a encontrar una respuesta, lo que en realidad me solucionó fue este artículo que encontré de Microsoft en Load Balancing Web Services. En resumen, lo que tuvimos que hacer para resolver esto en nuestra granja de servidores web fue cambiar el valor predeterminado de wsHttpBinding a basicHttpBinding. Esto no fue difícil, pero fue un movimiento de todo o nada. El servicio web principal y cada cliente tenían que reconfigurarse al mismo tiempo o se rompería.

Mientras wsHttpBinding tiene una propiedad de allowCooikes que podría tener el valor true, que aparentemente no usarlos hasta después de realizada la conexión, momento en el que la solicitud podría saltar servidores en la primera solicitud y por lo tanto fallar.

2

Es un problema NTLM causado por el uso de equilibradores de carga sin sesiones adhesivas. Para corregir el problema, debe configurar la afinidad de sesión (sesión adhesiva). Si no lo hace, obtendrá un error porque parte del intercambio de información de NTLM ocurrió en un servidor y la otra parte en otro servidor.

+0

Sí, nuestro equilibrador de carga tiene afinidad de sesión activada. Entonces, a menos que crear el objeto del lado del cliente (por ejemplo 'client = new InternalUseOnlyServiceClient()') esté haciendo un saludo inicial, entonces eso no debería ser un problema porque falla en la primera llamada al servicio web. Si ** está ** haciendo un apretón de manos inicial, entonces tengo que averiguar si el código generado por VS 2010 para el servicio web se puede hacer para tratar con las cookies, ya que así es como se configura nuestro equilibrador. ¿Pensamientos? – Jim

+0

Todavía tengo los mismos problemas después de intentar un par de cosas. He agregado los detalles al final de la pregunta principal debido a la duración. Si puede revisarlo, lo agradecería. – Jim

+0

@Jim tiempo para descubrir el violinista o una herramienta de olfateo de red para ver exactamente lo que se envía desde el cliente y que recibe del servidor. Si todo se ve bien en el cliente, es hora de ir al servidor. ¿Es posible que el equilibrador de carga esté alterando el tráfico que está causando que WCF arroje un error de seguridad? – Jeff

4

Voy a salir a un miembro aquí y supongo que la garantía sea la seguridad de mensaje especificado en el lado del cliente:

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

Si va a crear un cliente y la conexión, el negociado de credenciales de Windows token puede ser almacenado en caché. Si no tiene habilitadas las sesiones adhesivas, es posible que el token se devuelva al servidor incorrecto y falle. ¿Supongo que siempre está en la segunda llamada?

+0

@Chris, ¿está diciendo que el recorte anterior está * implícito * o el valor predeterminado para la seguridad? Pregunto porque no tengo eso en mi archivo .config (como se ve arriba). ¿Hay alguna forma de seguridad para esto? Este proceso es interno e incluso si fue pirateado desde el exterior, no hay absolutamente nada que pueda devolverse que no esté disponible públicamente en otro lugar. Cuando dice "Sesiones adhesivas", ¿se refiere al equilibrador de carga? Si es así, sí, tenemos afinidad. Y no, está en la primera llamada, si falla. – Jim

+0

He copiado eso desde su configuración del lado del cliente ... –

+0

Duh. Cuando hice una búsqueda * antes * de mi publicación, debo haber buscado solo en el lado del servidor para "seguridad". Perdón y gracias por señalar eso. – Jim

Cuestiones relacionadas