Tengo un componente de servidor que se ejecuta sobre Zeroc-ICE. Cuando quería cargar la prueba, pensé que usar la biblioteca paralela para crear múltiples solicitudes lo haría. Pero no terminará así. Usar la biblioteca Parallel (Parallel.For) de C # aparentemente fue más fácil, pero no parece estar generando exactamente todo en paralelo en el mismo instante. Por lo tanto, no puede ser la definición para crear N solicitudes por segundo. Cómo debería hacerlo ? Supongo que cualquiera que quiera hacer pruebas de carga primero pensaría en esto.
¿Cuál es la forma eficiente de crear realmente N solicitudes realmente por segundo?
Otro mito es sobre la programación paralela. Ilumínenos, si ha utilizado patrones de programación paralelos en C # o .Net en general. Imagina que tengo 5 procesos. Cómo comenzará los cinco procesos al mismo tiempo. ¿Qué significa para mi consumo de recursos? He intentado leer muchos de los materiales disponibles en la red, pero recibo más y más preguntas que la respuesta a mis preguntas.
Usé Parallel.For y creé N hilos y medí el tiempo. Luego intenté lo mismo usando Task.Factory.start para la enumeración de tareas. El tiempo medido fue diferente. Entonces, ¿cuál es exactamente la diferencia entre usar estos? ¿Cuándo debo usar las clases correspondientes y para qué fines exactamente? a menudo tenemos muchas riquezas, pero es solo que no sabemos exactamente cómo diferenciar una de la otra. Este es uno de esos casos para mí, no poder encontrar por qué no debería usar uno del otro.
Usé la clase de cronómetro para medir estos tiempos que dicen ser los mejores. En el escenario de prueba de carga de un componente, cuál sería la forma de medir el tiempo de respuesta. El cronómetro parece ser la mejor solución para mí. Cualquier opinión es bienvenida.
ps: hay muchas herramientas de prueba de carga para aplicaciones web. El mío es un caso personalizado de componentes del servidor. Y mi pregunta está más relacionada con la creación de N subprocesos por segundo.
Todas las opiniones son bienvenidas. Simplemente no pienses que no es tanto una cuestión de programación. Por supuesto que lo es. Debería sonar la campana para cualquier programador que quiera hacer QE por sí mismo para conocer el rendimiento de su producto, de primera mano por sí mismo. He probado muchas opciones y luego tuve que recurrir a cómo debería hacerlo.
fuente
Respuestas:
No tengo todas las respuestas. Espero poder arrojar algo de luz sobre ello.
Para simplificar mis declaraciones anteriores sobre los modelos de subprocesos de .NET, solo sepa que Parallel Library usa Tasks, y el TaskScheduler predeterminado para Tasks, usa ThreadPool. Cuanto más alto vayas en la jerarquía (ThreadPool está en la parte inferior), más sobrecarga tendrás al crear los elementos. Esa sobrecarga adicional ciertamente no significa que sea más lenta, pero es bueno saber que está ahí. En última instancia, el rendimiento de su algoritmo en un entorno de subprocesos múltiples se reduce a su diseño. Lo que funciona bien secuencialmente puede no funcionar tan bien en paralelo. Hay demasiados factores involucrados para darle reglas duras y rápidas, cambian dependiendo de lo que está tratando de hacer. Como se trata de solicitudes de red, intentaré dar un pequeño ejemplo.
Déjame decirte que no soy un experto en enchufes, y no sé casi nada sobre Zeroc-Ice. Sé un poco acerca de las operaciones asincrónicas, y aquí es donde realmente te ayudará. Si envía una solicitud síncrona a través de un socket, cuando llame
Socket.Receive()
, su subproceso se bloqueará hasta que se reciba una solicitud. Esto no es bueno Su hilo no puede hacer más solicitudes ya que está bloqueado. Usando Socket.Beginxxxxxx (), la solicitud de E / S se realizará y se colocará en la cola IRP para el socket, y su hilo continuará. ¡Esto significa que su hilo podría hacer miles de solicitudes en un bucle sin ningún bloqueo!Si lo entiendo correctamente, está utilizando llamadas a través de Zeroc-Ice en su código de prueba, en realidad no está tratando de llegar a un punto final http. Si ese es el caso, puedo admitir que no sé cómo funciona Zeroc-Ice. Quisiera, sin embargo, sugieren siguiendo el consejo que aparece aquí , sobre todo la parte:
Consider Asynchronous Method Invocation (AMI)
. La página muestra esto:Que parece ser el equivalente de lo que describí anteriormente usando sockets .NET. Puede haber otras formas de mejorar el rendimiento al intentar hacer muchos envíos, pero comenzaría aquí o con cualquier otra sugerencia que aparezca en esa página. Ha sido muy vago sobre el diseño de su aplicación, por lo que puedo ser más específico de lo que he sido anteriormente. Solo recuerde, no use más subprocesos de los absolutamente necesarios para obtener lo que necesita, de lo contrario, es probable que su aplicación se ejecute mucho más lentamente de lo que desea.
Algunos ejemplos en pseudocódigo (traté de hacerlo lo más cerca posible del hielo sin que realmente tuviera que aprenderlo):
Una mejor manera:
Tenga en cuenta que más subprocesos! = Mejor rendimiento al intentar enviar sockets (o realmente hacer algo). Los hilos no son mágicos ya que resolverán automáticamente cualquier problema en el que estés trabajando. Idealmente, desea 1 hilo por núcleo, a menos que un hilo pase mucho tiempo esperando, entonces puede justificar tener más. Ejecutar cada solicitud en su propio hilo es una mala idea, ya que ocurrirán cambios de contexto y desperdicio de recursos. (Si quieres ver todo lo que escribí sobre eso, haz clic en editar y mira las revisiones anteriores de esta publicación. Lo eliminé ya que solo parecía nublar el problema principal en cuestión).
Definitivamente puede realizar estas solicitudes en subprocesos, si desea realizar una gran cantidad de solicitudes por segundo. Sin embargo, no te excedas con la creación del hilo. Encuentre un equilibrio y manténgalo. Obtendrá un mejor rendimiento si utiliza un modelo asincrónico frente a uno sincrónico.
Espero que eso ayude.
fuente
Voy a saltar sobre la pregunta 1) y pasar directamente al n. ° 2, ya que generalmente es una forma aceptable de lograr lo que estás buscando. En el pasado, para lograr n mensajes por segundo, puede crear un solo proceso que luego lanzará p AppDomains. Básicamente, cada AppDomain comienza a ejecutar un ciclo de solicitud una vez que se alcanza un cierto punto en el tiempo (usando un Temporizador). Este tiempo debe ser el mismo para cada AppDomain para garantizar que comiencen a llegar a su servidor en el mismo momento.
Algo como esto debería funcionar para enviar sus solicitudes:
Esto probablemente reducirá el rendimiento en cualquier máquina en la que lo esté ejecutando, por lo que siempre podría implementar un tipo de bucle similar desde varias máquinas diferentes si tiene los recursos (usando procesos en lugar de dominios de aplicación).
Para su tercera pregunta, lea este enlace http://www.albahari.com/threading/
Finalmente, un cronómetro debe combinarse con un contador de visitas para rastrear tanto la duración como las visitas únicas en su servidor. Eso debería permitirle realizar un análisis después del hecho.
fuente
No se moleste con hilos, si N es razonablemente pequeño. Para generar N solicitudes por segundo, use el tiempo del reloj de pared (
DateTime.Now
). Tómese el tiempo antes y después de la solicitud, luego agregue unSleep
para retrasar la próxima solicitud.Por ejemplo, con N = 5 (200 ms):
Esto no es perfecto; Es posible que
Sleep
no sea exacto. Puede mantener un recuento de desviaciones (antes de las X solicitudes, el tiempo debe ser X-1 / N más tarde) y ajustar el período de suspensión en consecuencia.Una vez que N se vuelve demasiado grande, simplemente crea M hilos y deja que cada hilo genere solicitudes N / M de la misma manera.
fuente
La forma más fácil de lograr pruebas de carga para cualquier proyecto .NET es comprar la edición Ultimate de Visual Studio. Esto viene con herramientas de prueba integradas para ayudar a realizar todo tipo de pruebas, incluidas las pruebas de carga. Las pruebas de carga se pueden realizar mediante la creación de usuarios virtuales, ya sea en una sola PC o distribuidos en varios para un mayor número de usuarios, también hay un pequeño programa que se puede instalar en los servidores de destino para devolver datos adicionales durante la prueba.
Sin embargo, esto es costoso, pero la última edición viene con muchas características, por lo que si se usaran todas, sería un precio más razonable.
fuente
Si desea que todos los hilos X lleguen a su recurso exactamente al mismo tiempo, puede colocar cada hilo detrás de un cierre de cuenta atrás y especificar un breve período de espera entre las comprobaciones del semáforo.
C # tiene una implementación (http://msdn.microsoft.com/en-us/library/system.threading.countdownevent(VS.100).aspx).
Al mismo tiempo, si está haciendo una prueba de esfuerzo de su sistema, es posible que también desee verificar las condiciones de carrera, en cuyo caso desearía configurar períodos de suspensión de hilo en cada hilo que oscilan con el tiempo con frecuencia aleatoria y picos / licencias.
De manera similar, es posible que no desee enviar rápidamente múltiples solicitudes, puede tener más éxito al poner su servidor en un mal estado / probar su rendimiento en el mundo real al configurar un número menor de hilos que pasan más tiempo consumiendo y enviando mensajes de regreso y adelante sobre el zócalo, ya que su servidor probablemente necesitará girar sus propios hilos para manejar mensajes lentos en curso.
fuente