Optimizar el enlace Apache - Jboss
Por Javier Turégano

La arquitectura en capas para la tecnología de servidor de las soluciones web de Andago se encuentra dividida en los siguientes niveles: Acceso, Aplicación y Persistencia. La capa de aplicación, encargada de implenetar la lógica de negocio, estaba bastante definida desde el principio y la elección fué Jboss. Una vez determinada esta capa debíamos seleccionar la forma en que las peticiones web llegarían hasta las aplicaciones dentro de Jboss, es decir la capa de acceso, y para ello se fijaron unos criterios deseables: buen rendimiento, alta disponibilidad, balanceo de carga, flexibilidad, facilidad de integración con la infraestructura de cliente, etc... La conclusión a la que se llegó fué la de utilizar un servidor Apache para servir las peticiones web y que este se comunique con Jboss a través de mod_jk.
Pero, ¿porqué añadir otro software para esta tarea cuando Jboss ya dispone de su propio servidor web, que ha mejorado en gran medida en los últimos años, igualando prácticamente a Apache en su rendimiento? Aquí van algunas razones:
- Balanceo de carga y alta disponibilidad: Apache, a través de mod_jk, nos permite realizar estas dos tareas identificando un pool de servidores jboss a los que tiene que reenviar las peticiones.
- Seguridad: Jboss no dispone de separación de privilegios ni de una arquitectura modular destinada a separar el servidor web del de aplicaciones, por lo que ambos corren con los mismos privilegios. Si queremos que Jboss escuche en el puerto 80, puerto reservado y que tan sólo root puede utilizar, debemos correr Jboss con dicho usuario, lo que desde el punto de vista de la seguridad no es muy conveniente.
- Flexibilidad: Apache dispone de un gran número de opciones de configuración que te permiten personalizar el servicio así cómo un nutrido grupo de plugins que permiten ampliar su funcionalidad en caso necesario. Por poner un ejemplo, podemos aumentar la seguridad de nuestras webs con la ayuda de mod_security, que se encargará de realizar numerosos filtrados a las peticiones antes de dejar, o no, pasar a estas a nuestro servidor de aplicaciones. Otro módulo muy útil puede ser mod_rewrite que nos permita realizar reescrituras en las peticiones web que lleguen hasta nosotros.
Con esta arquitectura, Apache se encargaría de escuchar las peticiones web en el puerto 80, procesarlas en caso de que tengamos algún tipo de filtros, y enviarlas a Jboss a través de mod_jk utilizando el protocolo AJP. Este reenvio usando AJP optimiza el reenvío entre los dos servidores frente a la opción de hacer una nueva petición HTTP entre ambos.
Ahora bien, si no tenemos cuidado a la hora de configurar el enlace entre Apache y Jboss podemos convertir en una tremenda desventaja nuestra elección. Aquí vienen algunos consejos, a modo de ejemplo ya que podrían aplicarse muchos más, a tener en cuenta cuando configuramos el enlace a través de mod_jk, y más concretamente cuando usamos la versión de jboss4.2.3-GA:
- El primer paso será optimizar el número de conexiones entre Apache y Jboss. Para ello añadiremos los siguientes parámetros, adaptados a nuestras necesidades, en el fichero de configuración del workers.properties de mod_jk:
worker.ajp13_worker.socket_timeout=10
worker.ajp13_worker.connection_pool_timeout=600
worker.ajp13_worker.connection_pool_size=25
Estos parámetros son necesarios para evitar que el mod_jk vaya almacenando conexiones abiertas indefinidamente y finalmente se quede sin conexiones disponibles. El valor de socket_timeout no es necesario modificarlo, connection_pool_timeout depende del valor que se ponga en JBoss en el parámetro "connectionTimeout="600000" del conector AJP en $JBOSS_HOME/server/default/deploy/jboss-web.deployer/server.xml (deben coincidir, pero teniendo en cuenta que mod_jk lo mide en segundos y Jboss en milisegundos), y connection_pool_size coincide con el valor ThreadsPerChild del fichero de configuración de apache /etc/apache2/apache2.conf. Por otro lado debemos ajustar la configuración del conector AJP de nuestro Jboss a dichos parámetros:
$JBOSS_HOME/server/default/deploy/jboss-web.deployer/server.xml
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" address="${jboss.bind.address}" protocol="AJP/1.3"
emptySessionPath="true" enableLookups="false" redirectPort="8443"
maxThreads="200" connectionTimeout="600000" />
Podemos aprender más sobre cómo configurar estos parámetros en esta sección de la web de jboss.
- En segundo lugar es muy recomendable instalar el conector nativo para Jboss que se encargará de gestionar el protocolo AJP, ya que su rendimiento es muy superior al que viene por defecto con Jboss o Tomcat y por otro lado para evitar que se nos queden colgadas las conexiones entre Apache y Jboss, ya que este último está aquejado por el siguiente bug.
Nuestra recomendación sería que siempre copmilemos el conector nativo para la máquina en concreto en la que vamos a utilizarlo, ya que por ejemplo en instalaciones con Debian hemos descubierto que el conector binario se queda colgado al mismo arrancar, cosa que no sucede con la versión compilada en esa misma versión de Debian. El conector nativo podemos descargarlo de la web de jboss y la compilación bastará con instalar el paquete build-essential y tras lanzar el script build.sh incluido en el tar descargado copiar los ficheros de bin/META-INF/lib/linux2/x86/ , o x64 en caso de arquitectura de 64 bits, a $JBOSS_HOME/bin/native/ y volver a arranchar el jboss
- En caso que nuestras webs requieran de un gran número de conexiones SSL entre el navegador, en concreto desde Internet Explorer, y el servidor, por ejemplo si hacemos uso intensivo de AJAX en las mismas, nos podemos encontrar con una situación parecida a la anterior, es decir que se queden colgadas las conexiones entre Apache y Jboss. Para evitarlo añadimos estos parámetros a nuestra configuración de Apache, por ejemplo en la definición del VirtualHost:
BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
Podemos ver más ejemplos de cómo configurar estas conexiones teniendo en cuenta el navegador en este tutorial sobre tunning de Apache .
Cómo hemos visto, Apache puede ser un gran aliado de cara a implementar la capa de acceso a nuestras aplicaciones, pero debemos ser cuidadosos y aplicar una buena optimización en dicho enlace.
Javier Turégano