2010-12-22 15 views
11

Sé que un contenedor de servlets, como Apache Tomcat, se ejecuta en una sola instancia de la JVM, lo que significa que todos sus servlets se ejecutarán en el mismo proceso.¿Los contenedores de servlet evitan que las aplicaciones web causen interferencia mutua y cómo lo hacen?

También sé que la arquitectura del contenedor servlet significa que cada aplicación web existe en su propio contexto, lo que sugiere que está aislada de otras aplicaciones web.

Como se representa aquí: alt text

Aceptando que se aísla cada aplicación web, yo esperaría que usted podría crear 2 copias de una aplicación Web idéntica, cambiar los nombres y las rutas de contexto de cada uno (así como cualquier otra configuración relevante), y ejecutarlos en paralelo sin que uno afecte al otro. Las respuestas a this question parecen ser compatibles con esta vista.

Sin embargo, un colega no está de acuerdo con su experiencia al intentar justamente eso.

Tomaron una aplicación web e intentaron ejecutar 2 instancias separadas (con diferentes nombres, etc.) en el mismo contenedor de servlets y problemas experimentados con las 2 instancias en conflicto (no puedo elaborar más ya que no participé en ese trabajo).

En base a esto, argumentan que dado que las aplicaciones web se ejecutan en el mismo espacio de proceso, no se pueden aislar y cosas como los atributos de clase terminarían siendo compartidas inadvertidamente. This answer parecen sugerir lo mismo

Los dos puntos de vista no parecen ser compatibles, así que pregunto: Haz contenedores de servlets impiden que las aplicaciones Web desplegadas al mismo recipiente entren en conflicto entre sí?

Si , ¿Cómo lo hacen?

Si no, ¿Por qué ocurre la interferencia?

y finalmente, ¿En qué circunstancias podrían las aplicaciones web separadas entrar en conflicto y causar interferencia mutua?, ¿quizás escenarios que involucren recursos en el sistema de archivos, código nativo o conexiones de bases de datos?

Respuesta

15

La respuesta corta es que el contenedor de servlets aísla las aplicaciones utilizando un cargador de clases separado para cada aplicación: las clases cargadas por cargadores de clases separados (incluso cuando proceden de los mismos archivos de clases físicas) son distintas entre sí. Sin embargo, los cargadores de clases comparten un cargador de clases padre común y el contenedor puede proporcionar una cantidad de otros recursos en todo el contenedor, por lo que las aplicaciones no están completamente aisladas entre sí.

Por ejemplo, si dos aplicaciones comparten un código común al incluir el mismo jar en su guerra, cada aplicación cargará su propia instancia de las clases del jar y una variable estática (por ejemplo, un singleton) de una clase en una aplicación será distinta de la variable estática de la misma clase en la otra aplicación.

Ahora, tome por ejemplo, que las aplicaciones intenten usar java.util.Logger (y presumiblemente no incluyan su propia instancia de las clases de Logger en sus archivos war). El cargador de clases propio de cada aplicación no encontrará la clase en el archivo war, por lo que se pospondrá a su cargador de clases principal, que probablemente sea el cargador de clases compartido de todo el contenedor. El cargador de clases padre cargará la clase Logger y ambas aplicaciones compartirán la misma clase Logger.

+1

+1 para ejemplos detallados para ilustrar su punto – chrisbunney

5

Los servlets en el mismo contenedor compartirán algunos recursos. Creo que debería ser posible implementar la misma aplicación web dos veces en el mismo contenedor, siempre que le dé a cada una un nombre diferente y no colisionen con un recurso en particular. En teoría, esto sería lo mismo que implementar dos servlets diferentes que tienen la misma implementación, lo que hacemos todo el tiempo.

Algunos recursos compartidos, de la parte superior de mi cabeza (y yo soy un experto así que no cita nada de esto!):

  • Bibliotecas (tarros) en Tomcat/common/lib (Tomcat 5) o tomcat/lib (Tomcat 6).
  • Ajustes en el server.xml, web.xml, tomcat-users.xml mundial
  • OS siempre cosas, como stdin/stdout/stderr, tomas de corriente de red, dispositivos, archivos, etc.
  • El sistema de registro .
  • Propiedades del sistema Java (System.getProperty(), System.setProperty())
  • Sospecho ... variables estáticas? No estoy seguro si el diseño de ClassLoader evitaría esto o no.
  • Memoria. Este es el problema más común: un servlet puede denegar la disponibilidad de otros al consumir toda la memoria.
  • CPU, especialmente con aplicaciones multiproceso. En HotSpot JVM, cada subproceso de Java es en realidad un subproceso de nivel de sistema operativo, que son caros y no desea más de unos miles de ellos.

Sin duda hay más.

Muchas de estas cosas están protegidas por un administrador de seguridad, si está utilizando una.

+3

variables estáticas son por classloader –

+0

+1 para la lista de recursos compartidos, y la aclaración sobre variables estáticas de Pangea es de particular relevancia para mí – chrisbunney

2

Creo que el aislamiento está en el cargador de clases. Incluso si dos aplicaciones usan el mismo nombre y paquete de clase, su cargador de clases cargará el que se implementó con la aplicación.

Cuestiones relacionadas