¿Cómo diseñar servicios web altamente escalables en Java?

15

Estoy creando algunos servicios web que tendrían 2000 usuarios simultáneos. Los servicios se ofrecen de forma gratuita y, por lo tanto, se espera que obtengan una gran base de usuarios. En el futuro, puede ser necesario escalar hasta 50,000 usuarios.

Ya hay algunas otras preguntas que tratan el tema como: enlace

Sin embargo, mis requisitos difieren de la pregunta anterior.

Por ejemplo, mi aplicación no tiene una interfaz de usuario, por lo que las imágenes, CSS, javascript no son un problema. Está en Java, por lo que sugerencias como usar HipHop para traducir PHP a código nativo son inútiles.

Por lo tanto, decidí hacer mi pregunta por separado.

Esta es la configuración de mi proyecto -

  1. Servicios web basados en el descanso utilizando Apache CXF
  2. Hibernate 3.0 (con optimizaciones relevantes como carga lenta y HQL personalizado para afinar)
  3. Tomcat 6.0
  4. MySql 5.5

¿Cuáles son las mejores prácticas a seguir para poder hacer que una aplicación basada en Java sea escalable?

    
pregunta Kshitiz Sharma 19.06.2012 - 07:56
fuente

3 respuestas

8

Traté el problema en el pasado, pero aún siento que tengo mucho que aprender en el campo. Considero que este es uno de los campos más interesantes que existen en el desarrollo de software hoy en día, aquí hay algunas ideas sobre esto:
MySQL es una base de datos lo suficientemente justa a menos que esté trabajando con una enorme cantidad de datos, y en este caso podría considerar la base de datos NoSQL, pero debería examinar cuidadosamente cuál es la mejor base de datos NoSQL para su necesita.

Debe implementar el almacenamiento en caché en su sistema; trate de almacenar en caché la mayor cantidad posible de datos de solo lectura, o defina algunas estrategias de almacenamiento en caché; por ejemplo, tuvimos un escenario en el que era válido para un usuario ver "datos antiguos" como siempre que la última actualización haya tenido lugar en la última hora. Me gustaría considerar JBoss Cache, o tal vez Infinispan (que es más como una estructura de datos distribuidos) u otro marco de almacenamiento en caché popular para esto.
Además, como mencionó Tomcat, asumo que trabaja en algún módulo de solicitud-respuesta. Trate de considerar el uso de un caché que exista en el alcance de una solicitud dada, esto puede ser incluso un simple HashMap asociado con el subprocesos de almacenamiento local .
Mi idea aquí se parece bastante a primer nivel en el caché Hibernate .   

Debe recordar que los archivos, las transacciones y otros recursos son costosos en términos de mantenerlos abiertos. Asegúrese de cerrar los archivos y las transacciones lo antes posible, o terminará con errores que se reproducirán en configuraciones a gran escala

Además, debe comprender lo que son 2000 usuarios simultáneos: ¿esto significa que 2000 usuarios acceden a su servidor a la vez o están utilizando su sistema? Distinga entre los casos en que 2000 usuarios intentan abrir un socket en su servidor, y un caso en el que solo 500 están, y 1500 actualmente están buscando resultados, para llenar los datos de entrada del lado del cliente.

Debería considerar el uso de clústeres: tendrá que lidiar con problemas como equilibrio de carga , sesión pegajosa (lo que significa el equilibrador de carga redireccionará una solicitud al mismo servidor para la misma sesión y más.

Si necesita tener un código de sincronización, elija la estrategia de sincronización con cuidado. Vi algunos sistemas en los que se usaba un bloqueo simple, pero a ReaderWriterLock podría haber mejorado las cosas, ya que la mayoría del acceso era de solo lectura.

Considere tener una caché y validación del lado del cliente si es posible, intente guardar las llamadas al servidor y enviar solo las diferencias de datos, en caso de que la mayor parte de su respuesta para una solicitud con el mismo parámetro no cambie.
Por ejemplo, en el proyecto de código abierto oVirt solicitamos obtener estadísticas de una máquina virtual determinada. algunos de los datos de la máquina virtual rara vez cambian, por lo que solo enviamos MD5, si los datos cambian, el valor de MD5 también cambia, realizamos una solicitud para obtener los datos completos, y no solo el MD5.

Antes mencioné hibernar. Le recomendaría que lo considere cuidadosamente. Si necesita realizar muchas escrituras y menos lecturas, tal vez Hibernate no sea ideal para usted y debería considerar trabajar con Spring-JDBC como envoltorio sobre JDBC.

Indexe su base de datos sabiamente, y use un esquema db correcto. Considere utilizar una capa de procedimientos almacenados ya que están precompilados y optimizados

Me gustaría indicar que en el pasado, traté con un sistema (nodo único) en mysql (en su mayoría solo acceso de lectura) con jboss 4.2.1 y logré llegar a 2000 usuarios concurrentes
(no accediendo a la vez en términos de apertura 2000 sockets contra nuestro servidor), pero utilizando / navegando nuestro sistema, usando JBoss Cache y precargando en la memoria caché algunos de los datos más accedidos, o los datos de los que nos dimos cuenta serán "populares y populares", pero nuestra solución fue buena para nuestra arquitectura y nuestros flujos,
así como lo digo en estos casos -
Hay más consejos y trucos, pero realmente depende de su arquitectura y de los flujos que necesite tener en su sistema. Buena suerte!

    
respondido por el zaske 22.06.2012 - 08:09
fuente
3

Buena pregunta. Probablemente sea difícil decir cuál es el mejor enfoque, pero lo intentaré a partir de mi experiencia.

La mejor manera de escalar la aplicación web basada en Java es escribirla sin estado como sea posible (si es posible). Esto le permite escalar horizontalmente la aplicación, donde puede agregar servidores Tomcat si hay más usuarios concurrentes.

Sin embargo, como observó, podría haber problemas con las conexiones de la base de datos. Pero la pregunta que tengo es, ¿cómo está obteniendo los datos? ¿Es generado por el usuario o usted obtiene los datos de terceros? Esto es muy importante porque, si está brindando un servicio a su usuario con los datos agregados de una aplicación de terceros (por ejemplo, FB, Twitter, etc.), lo que puede seguir es escribir en la base de datos principal y replicar los datos en las bases de datos secundarias que se asignan a cada instancias tomcat. Luego, cada servidor tomcat puede obtener de su propia base de datos esclava.

 Are there faster alternatives to Mysql?

Puede ir al clúster MySQL que tiene un almacén de datos en memoria. Pero tenga cuidado con el hecho de que la aplicación puede necesitar algunos cambios. El sql joins no está bien soportado en el clúster de MySQL, aunque en la última versión hay mejoras para el mismo. Si el costo no es un factor, puede probar Oracle.

La solución de almacenamiento en caché definitivamente mejorará el rendimiento. Pero entonces, todo depende de la arquitectura de toda la aplicación. Debe saber cuándo debe insertar datos en la memoria caché, cuándo debe ensuciarse (eliminar de la memoria caché).

Con respecto a la distribución de la carga en un entorno de varios servidores, le sugiero que use el equilibrador de carga en lugar de usar Apache para equilibrar la carga.

    
respondido por el Chandra 19.06.2012 - 08:49
fuente
2

Actualmente estoy configurando un sistema similar (a nivel profesional) y este es el diseño que elegí:

  • Dos equilibradores de carga Nginx (ambos activos, ambos conmutados por error para el otro, balanceados con DNS round robin)
  • Dos bases de datos MySQL en modo de replicación de master master
  • Dos instancias de Tomcat como un cluster tomcat
  • Dos instancias de Memcached para el almacenamiento en caché y el estado de la sesión para el clúster Tomcat

Esto logrará una solución redundante, de alta disponibilidad y escalable.

Los equilibradores de carga (en hardware decente) cargarán fácilmente una línea saturada de 1gbit cada uno. Este es también un gran lugar para la descarga de SSL.

Puedes guardar la información de tu sesión en memcached. En caso de que falle una instancia de Tomcat, otra instancia de Tomcat puede recuperar información relevante de la sesión y los clientes no notarán nada. No olvides combinar esto con sesiones pegajosas también. (Para reducir el tráfico de red)

Tomcat clustering también tiene una opción para compartir información de sesión entre el clúster en tiempo real, sin usar memcached. Aunque creo que en cuanto al rendimiento, el uso de Memcached será mejor.

Si necesita más potencia en cualquiera de estas aplicaciones:

  • Nginx: agregue más equilibradores de carga, aunque no creo que este sea el cuello de botella muy pronto.
  • Tomcat: puede aumentar fácilmente el tamaño del clúster de Tomcat o agregar más clústeres
  • Mysql: agregue algunos esclavos de solo lectura o aumente el tamaño del clúster (dependiendo de su aplicación, pero como escribió una aplicación basada en REST, esto no debería ser un problema)
  • Memcached: Agregar más nodos, Memcached se ajusta bastante bien, creo.

No sé cómo se construye su aplicación y cuáles son los grandes recursos de recursos, pero si ve una gran carga en la base de datos (¡durante sus pruebas de carga!), agregar un caché entre la aplicación y la base de datos podría mejorar mucho el rendimiento . Pero no olvide que no todo es almacenable en caché, si sus consultas son siempre diferentes, el almacenamiento en caché no ayudará (mucho)

Mi consejo sería descargar VMware Workbench (o un software de virtualización similar) e intentar crear una configuración simple. No hay balanceo de carga o agrupación, solo lo básico y el trabajo desde allí. Una por una, agregue más funciones (balanceo, almacenamiento en caché, agrupación en clústeres, etc.) y asegúrese de investigar un poco sobre cada tema, para que sepa que hizo la elección correcta.

Si continúa ejecutando las mismas pruebas de rendimiento durante este proceso, puede ver por sí mismo si usar X es mejor que usar Y en su configuración, o qué impacto tiene el almacenamiento en caché tendrá, etc.

Al final, una configuración como esta realmente depende de los requisitos de su aplicación y sus clientes, todo se puede hacer de varias maneras, cada una con sus propias fortalezas y debilidades.

¿Alguna pregunta más?

¡Buena suerte!

Wesley

    
respondido por el Wesley 25.06.2012 - 18:47
fuente

Lea otras preguntas en las etiquetas