Mejora del rendimiento de HttpWebRequests multiproceso en .NET

Estoy tratando de medir el rendimiento de un servicio web.

Para hacer eso, he escrito una pequeña herramienta que continuamente envía solicitudes y lee respuestas de varios hilos.

El contenido del bucle interno de cada hilo se ve así:

public void PerformRequest() { WebRequest webRequest = WebRequest.Create(_uri); webRequest.ContentType = "application/ocsp-request"; webRequest.Method = "POST"; webRequest.Credentials = _credentials; webRequest.ContentLength = _request.Length; ((HttpWebRequest)webRequest).KeepAlive = false; using (Stream st = webRequest.GetRequestStream()) st.Write(_request, 0, _request.Length); using (HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse()) using (Stream responseStream = httpWebResponse.GetResponseStream()) using (BufferedStream bufferedStream = new BufferedStream(responseStream)) using (BinaryReader reader = new BinaryReader(bufferedStream)) { if (httpWebResponse.StatusCode != HttpStatusCode.OK) throw new WebException("Got response status code: " + httpWebResponse.StatusCode); byte[] response = reader.ReadBytes((int)httpWebResponse.ContentLength); httpWebResponse.Close(); } } 

Parece que funciona bien, excepto que algo parece estar limitando la herramienta. Si ejecuto dos instancias de la herramienta con cada 40 subprocesos, obtengo mucho más rendimiento que una instancia con 80 subprocesos.

Encontré la propiedad ServicePointManager.DefaultConnectionLimit, que configuré en 10000 (y no hay diferencia si configuro a través de app.config como lo sugirió Jader Dias ).

¿Hay alguna otra configuración en .NET o en mi máquina que pueda influir en el rendimiento? (Estoy ejecutando Vista, pero veo el mismo problema en Windows Server 2003).

¿Tal vez algunas restricciones sobre cuántas conexiones puede hacer un solo proceso?

Debe establecer el parámetro maxconnection en el archivo app.config o web.config:

 < ?xml version="1.0" encoding="utf-8" ?>        

Los valores de hasta 100 funcionan muy bien con Windows XP.

Actualización: descubrí que el método anterior es una forma alternativa de configurar System.Net.ServicePointManager.DefaultConnectionLimit

¿Has intentado boost las conexiones máximas en la configuración de red?

http://msdn.microsoft.com/en-us/library/fb6y0fyc.aspx

Tenga en cuenta que el código multiproceso siempre puede causar contención en los recursos compartidos e, incluso si no está compartiendo explícitamente algo, es posible que esté utilizando clases que comparten recursos ocultos.

Si realmente está obteniendo un mejor rendimiento con 2 40 ex exs de 1 80 subprocesos, tendrá que comenzar su investigación con los recursos compartidos. Y si ese es el caso, el código que citó es mucho menos interesante que el código que crea y administra los hilos.

La otra cosa que arrojaría es que hay varias herramientas que puede obtener que le harán este tipo de cosas genéricamente. Vea http://support.microsoft.com/kb/231282 . También se incluye en Visual Studio (no estoy seguro de qué skus) es una nueva generación de herramientas de prueba de rendimiento de aplicaciones web. Y estoy seguro de que si buscaste podrías encontrar algunas cosas que no sean de MS también.

Hay dos aspectos importantes del rendimiento de wrt:

  1. Un aspecto es el sugerido por todos, la cantidad de conexiones TCP utilizadas por el cliente (generalmente mejor si estas conexiones son persistentes (keep alive = true)) para más detalles, consulte: http://msdn.microsoft.com/en-us /library/system.net.servicepoint.connectionlimit(v=vs.110).aspx , cómo y dónde se ha creado la conexión TCP en httpwebrequest, y cómo se relaciona con el punto de servicio? , ¿Por qué System.Net.ServicePoint.ConnectionLimit utiliza ‘7FFFFFFF’ (Int32.MaxValue / 2147483647) cuando un cliente se conecta a un servicio en ‘localhost’? , System.Net.ServicePointManager.DefaultConnectionLimit y .MaxServicePointIdleTime )

  2. Segundo aspecto en lugar de usar múltiples hilos nuevos / o usar hilos de trabajo para hacer el trabajo en paralelo usando llamadas síncronas (como httpwebrequest.getrequeststream) en el fragmento de código, adoptando completamente el modelo asíncrono (por ejemplo, begin / endrequeststream, o nuevas variaciones de tareas) . De esta forma, la CPU siempre estará ocupada y permitirá que el subproceso del puerto de terminación de E / S simplemente envíe la respuesta en un subproceso de trabajo (grupo de subprocesos) invocando la callback. (puede consultar: ¿Cómo utiliza .NET los subprocesos IO o los puertos de finalización IO?, http://blog.marcgravell.com/2009/02/async-without-pain.html , HttpWebRequest y puertos de finalización de E / S )

Saludos.

¿Cómo estás creando tus hilos? Supongo que, como sabe que tiene 80 hilos, no está utilizando el administrador de subprocesos, porque con el administrador de subprocesos puede solicitar tantos subprocesos como desee y obtendrá solo 25 subprocesos activos a la vez. Si crea los subprocesos manualmente con una matriz, obtendrá realmente tantos como necesite, sin embargo, aún se encuentran en el mismo espacio de proceso, por lo que podría limitarlos a los subprocesos que se ejecutan en procesos separados.

También puede ver en qué estilo de apartamento se crean los subprocesos, creo que el ctor de clase Thread usa STA de forma predeterminada. Pruebe MTA y vea si afectan el rendimiento.