2011-02-09 16 views
6

Tengo un servlet de Java que se está sobrecargando por las solicitudes de los clientes durante las horas punta. Algunos clientes abarcan solicitudes simultáneas. A veces, el número de solicitudes por segundo es demasiado grande.¿Impide que el cliente sobrecargue el servidor?

¿Debo implementar la lógica de la aplicación para restringir el número de solicitudes que el cliente puede enviar por segundo? ¿Esto se debe hacer en el nivel de la aplicación?

+3

Tirar más hardware en él. –

+0

Siempre que todas las solicitudes sean válidas, entonces estoy de acuerdo con Anon, le tiro más hardware (más fácil) u optimizo su servlet de Java. Si las solicitudes son de tipo spam, puedes bloquearlas en una capa inferior usando algo como iptables o un bloque de nivel apache – Nick

+1

Su pregunta es válida. Siempre puede haber más solicitudes de las que el hardware puede manejar. Un servidor necesita una forma de limitar las solicitudes y ahora bajar el sistema durante cargas excesivas. –

Respuesta

1

Las dos formas más comunes de manejar esto son rechazar las solicitudes cuando el servidor está demasiado ocupado o manejar cada solicitud más lentamente.

Desactivar solicitudes es fácil; solo ejecuta un número fijo de instancias. El sistema operativo puede o no hacer cola para algunas solicitudes de conexión, pero en general los usuarios simplemente no podrán conectarse. Una manera más elegante de hacerlo es hacer que el servicio devuelva un código de error que indique que el cliente debe volver a intentarlo más tarde.

El manejo de solicitudes más lentas es un poco más laborioso, ya que requiere separar el servlet que maneja las solicitudes de la clase que realiza el trabajo en un hilo diferente. Puede tener una mayor cantidad de servlets que las abejas obreras. Cuando llega una solicitud, la acepta, espera a una abeja obrera, la agarra y la usa, la libera y luego devuelve los resultados.

Los dos se pueden comunicar a través de una de las clases en java.util.concurrent, como LinkedBlockingQueue o ThreadPoolExecutor. Si quieres ser realmente elegante, puedes utilizar algo como PriorityBlockingQueue para atender a algunos clientes antes que a otros.

mí, me gustaría echar más hardware en ella como Anon dijo;)

1

Algunas respuestas sólidas aquí. Creo que más hardware es el camino a seguir. Tener demasiados clientes o tráfico es generalmente un buen problema.

Sin embargo, si debe restringir absolutamente a los clientes, existen algunas opciones.

Las soluciones más escalables que he visto giran en torno a un sistema de caché distribuido, como Memcached, y el uso de enteros para mantener los conteos.

Calcule la velocidad a la que su sistema puede manejar el tráfico. Ya sea en general, o por cliente. Luego ponga una cuenta en memcached que represente esa tasa. Cada vez que recibe una solicitud, disminuya el valor. Periódicamente incremente el contador para permitir más tráfico.

Por ejemplo, si puede manejar 10 solicitudes/segundo, ponga un conteo de 50 en cada 5 segundos, hasta un máximo de 50. De esa manera no lo estará recargando todo el tiempo, pero también puede manejar un poco de estallido limitado a una ventana. Deberá experimentar para encontrar una buena frecuencia de actualización. La clave para este contador puede ser una clave global o basada en la identificación del usuario si necesita restringirlo de esa manera.

Lo bueno de este sistema es que funciona en todo un clúster Y el mecanismo que rellena los contadores no necesita estar en uno de sus servidores actuales. Puedes dedicarle un proceso separado. Los servidores cargados solo necesitan verificarlo y disminuirlo.

Dicho todo esto, primero investigaría otras opciones. Estrangular a sus clientes suele ser una buena manera de molestarlos. Probablemente NO sea la mejor idea. :)

+0

si tiene éxito en estrangular a un cliente, tendrá que explicarle el cadáver. Pero ya no se molestarán más :-) –

+1

Hay más de una manera de despellejar a un cliente ... gato. – rfeak

1

Supongo que no está en posición de aumentar la capacidad (ya sea a través de hardware o software), y realmente solo necesita limitar la carga externamente impuesta en su servidor.

Debe evitarse lidiar con esto desde su aplicación a menos que tenga necesidades muy especiales que no se cumplan con las soluciones existentes que operan a nivel de servidor HTTP. Se ha pensado mucho en este problema, por lo que vale la pena analizar las soluciones existentes en lugar de implementar una tú mismo.

Si está utilizando Tomcat, puede configurar la cantidad máxima de solicitudes simultáneas permitidas a través de las configuraciones maxThreads y acceptCount. Lea la introducción en http://tomcat.apache.org/tomcat-6.0-doc/config/http.html para obtener más información sobre estos.

Para obtener controles más avanzados (como restricciones por usuario), si utiliza proxy a través de Apache, puede utilizar una variedad de módulos para ayudar a manejar la situación. Algunos módulos para google for son limitipconn, mod_bw y mod_cband. Estos son un poco más difíciles de configurar y comprender que los controles básicos que probablemente ofrece su servidor de aplicaciones, por lo que es posible que solo quiera mantenerlos.

Cuestiones relacionadas