Servicio lento de ASMX Web Service primero

Tengo un montón de .NET Webservices ejecutándose en una aplicación IIS. Estos servicios web son consumidos por otra aplicación IIS (frontend). La primera llamada es bastante lenta, de 5 a 10 segundos. Después de eso solo son milisegundos. La primera llamada se considera un problema de rendimiento.

Hemos probado una aplicación que llama a todos estos servicios web, pero obviamente esto no resuelve nada. Por lo tanto, este no es el reciclaje de aplicaciones predeterminado. Creé una aplicación que simplemente inicializa el servicio varias veces y mide el tiempo que lleva crear una instancia. Antes de ejecutar esta aplicación, me aseguro de que mi aplicación de servicio web se inicie / recicle, luego ejecuto la aplicación. La primera inicialización demora entre 2 y 4 segundos, todas las demás solo son milisegundos.

Otro pensamiento es que creamos una página en la aplicación Frontend que inicia todos los servicios web y que llamamos a esta página antes de que ingresen los usuarios. No lo considero una solución elegante, ¿qué más podría probar?

La demora que se experimenta cuando un cliente está llamando a un servicio web por primera vez se debe al hecho de que, por defecto, se debe comstackr una DLL de XmlSerializers para el servicio web. Esto está causando los 2-4 segundos para la llamada inicial. Por supuesto, este es el caso cuando la aplicación del servicio web ya se está ejecutando, si no es así, tendría que reciclar. En ese caso, las otras respuestas podrían ayudar.

Para acelerar la llamada inicial, puede crear el dll XmlSerializers en tiempo de comstackción. Puede hacer esto configurando la creación del proyecto ‘Generar ensamblaje de serialización’ en on. Esto genera un MyApplication.XmlSerializers.dll que contiene la información del servicio web. Ahora la llamada inicial cayó a 300 ms, presumiblemente la carga del dll. Todas las llamadas allí después toman 0 ms.

En Visual Studio, haga clic derecho en su proyecto y seleccione ‘Propiedades’. Ve a la pestaña ‘Construir’. Allí tiene la opción ‘Generar ensamblaje de serialización’ en la sección ‘Salida’. Si cambia el valor a ‘Activado’, el ensamblaje de serialización se generará durante el tiempo de comstackción.

La primera vez que llame al servicio web, o la primera vez después de un largo retraso, el servicio web debe iniciarse. Aquí es donde estás viendo la demora. Después de eso, ya se inició y responderá muy rápido a las llamadas. Este es el comportamiento del servicio web estándar.

Puede configurar IIS para que tenga keepalive = true, lo que puede mejorar el rendimiento.

Más información según lo solicitado.

Podría ser que los ensamblajes de serialización se estén creando en tiempo de ejecución. Puede cambiar la configuración del conjunto de serialización utilizando el menú desplegable en la parte inferior del panel Generar de la ventana de propiedades del proyecto.

Podría ser que haya escrito su servicio web para realizar muchas operaciones al inicio de la aplicación, lo que ocurriría la primera vez que se llame a un método en el servicio.

Es posible que la operación sea muy lenta, pero está almacenando en caché la respuesta, lo que hace que las llamadas posteriores sean más rápidas.

Recientemente descubrí que en nuestros archivos ASMX solo nos referíamos al nombre de la clase. Obtuvimos la implementación del servicio en un ensamblaje diferente para cada archivo ASMX. Esto hace que .NET framework explore todo el bin-folder buscando el ensamblado que contiene la implementación. A medida que su aplicación de servicio web crezca, esto consumirá más tiempo. Esto se puede resolver no solo incluyendo el nombre de clase en su definición ASMX sino también el nombre del ensamblado.

Nuestro ASMX se veía así:

<%@ WebService Language=”C#” CodeBehind=”MyService.cs” Class=”MyWebservice” %>

Si lo cambia para incluir el ensamblado que contiene la implementación, se vería así. Esto nos ahorró alrededor del 10% de nuestra carga inicial de la aplicación del servicio web.

<%@ WebService Language=”C#” CodeBehind=”MyService.cs” Class=”MyWebservice, MyWebservice.Implementation.Assembly” %>

Eso es típico, ya que las aplicaciones ASP.NET comstackn y cargan el directorio bin \ en la memoria al solicitarlo por primera vez.

Cosas que hacer primero:

Elimine todos los dll innecesarios en su directorio bin. (He visto personas que envían nunit.dll)

Precompile su aplicación ASP.NET para que IIS no lo necesite. Consulte ” Lanzamiento del soporte del proyecto de implementación web VS 2008 ”

No estoy seguro de si esto solucionará el giro lento del WS en la “primera vez”, ya que supongo que hay una carga de DLL de comstackción y .NET cargadas, pero puede eliminar casi cualquier arranque en frío futuro asegurando que el grupo de aplicaciones el WS está en está configurado correctamente.

De forma predeterminada, IIS6 ha “reaparecido” en reposo, luego de varios minutos o eventos de “reciclaje” que reinician el WS cada vez. Si su feliz el servicio es estable, entonces estos no son necesarios.

Asegurar que el WS tenga su propio grupo de aplicaciones dedicado (no comparte un grupo inapropiado) es también una recomendación sólida.

Después de varias horas de pruebas insanas, he podido reducir el tiempo de ejecución del primer servicio de webservice al mínimo de dos hosts en la misma clase de IP (por debajo de 300 ms) …

Experimenté al principio un retraso inicial de 2-3 segundos en la primera llamada al servicio web, que cualquier llamada posterior del mismo proceso para ser muy rápido.

La clave para entender la demora en mi caso fue cómo el cliente maneja WEB PROXY !!

Este es mi nuevo enlace en el archivo app.config:

           

La primera ejecución de webcall supongo que es mucho más lenta porque el canal de transporte necesita descubrir la configuración de proxy en la inicialización, para conectarse de forma transparente a internet. Esto generalmente no es necesario en el entorno de la intranet, por lo tanto, he cambiado estas configuraciones de enlace para evitar el uso del proxy predeterminado (que se descubre automáticamente de la configuración del explorador):

bypassProxyOnLocal = “falso”

useDefaultWebProxy = “falso”

El tiempo de conexión de la primera llamada ahora se reduce en gran cantidad. Espero que esto ayude.

Perdón por el complemento Necro, pero esta ha sido una lucha constante para mí también, y quería agregar algo de información a la imagen. VisualStudio en sí mismo agrega un componente bastante grande al tiempo. Aquí está la prueba básica, que implica una aplicación básica de formularios y un servicio web ya en funcionamiento alojado internamente en un servidor de la empresa (con Generate Serialization Assembly establecido en true para todas las pruebas):

 Running in VS, Debug: First Call: 400 ms to set up client object, 450 to call function Second Call: 1 ms to set up client object, 14 to call function Running as .exe, Release: First Call: 20 ms to set up client object, 70 to call function Second call: 1 ms to set up client object, 4 to call function Running the Debug's .exe file outside of vs: First Call: 20 ms to set up client object, 80 to call function Second call: 1 ms to set up client object, 4 to call function Running as Release within VS: Similar results to Debug in VS -- very slow 

¿Cuento? Visual Studio está agregando un gran pedazo de tiempo a la imagen. En lugar de ~ 90 ms, tarda casi un segundo. Por lo tanto, si está afinando el rendimiento, asegúrese de realizar las pruebas fuera del entorno de VisualStudio.