Manual JBoss
1
Índice
Capítulo I : Instalación de JBoss...........................................................................4
Introducción.....................................................................................................4
Pasos Previos...................................................................................................4
Instalación del JDK (JSE) ..............................................................................4
Instalación de JBoss ....................................................................................4
Estructura ................................................................................................5
Ejecución ........................................................................................................6
Configuración ..............................................................................................7
Capítulo II: Despliegue de Aplicaciones...............................................................9
Introducción.....................................................................................................9
Despliegue en caliente....................................................................................9
Estructura del descriptor de despliegue..........................................................9
Estructura de un paquete de aplicación........................................................10
Capítulo III: Integración de JBoss con Eclipse....................................................12
Introducción...................................................................................................12
Obtener Eclipse..............................................................................................12
Configurar Eclipse con JBoss..........................................................................14
Capítulo IV : Monitorización...............................................................................19
Introducción...................................................................................................19
Arquitectura de JMX.......................................................................................19
Monitorización de JBoss.................................................................................20
Monitorización con JConsole .........................................................................21
Monitorización con ManageEngine Applications Manager.............................23
Monitorización con Munin..............................................................................30
Instalación de munin-master......................................................................31
Instalación en Debian/Ubuntu................................................................31
Instalación en CentOS............................................................................31
Configuración del munin-master................................................................32
Instalación de munin-node.........................................................................33
Instalación en Debian/Ubuntu................................................................33
Instalación en CentOS............................................................................33
Arrancar el servicio munin-node................................................................34
Informes.....................................................................................................35
Escribir plugins para munin utilizando JMX................................................37
Formato de un plugin munin..................................................................39
Conclusión..................................................................................................42
Monitorización con Nagios.............................................................................43
Introducción...............................................................................................43
Requisitos...................................................................................................43
Instalación.....................................................................................................43
Escribir plugins para nagios utilizando JMX................................................46
Capítulo V: JAAS.................................................................................................50
Configuración de la seguridad estándar en la aplicación web.......................50
Configurar un módulo de login JAAS..............................................................50
Configuración de la seguridad específica de JBoss en la aplicación web.......51
Creación de tablas y carga de datos en SQL.................................................51
Definición del datasource y configuración de la política de seguridad en
2
JBoss..............................................................................................................53
Capítulo VI : Clustering......................................................................................55
Configuración de JGroups...............................................................................55
Ejecución del cluster......................................................................................56
Apache mod_jk..............................................................................................57
Propiedades Globales.................................................................................59
Propiedades de los workers........................................................................60
Variables, Variables de entorno..............................................................60
Propiedad de herencia............................................................................60
Lista de directivas de los workers...........................................................61
Directivas de balanceo de carga............................................................62
Cluster HA......................................................................................................64
Capítulo VII: Optimización de JBoss...................................................................70
Elección de la JVM..........................................................................................70
JVM Heap ...................................................................................................71
Optimización de Tomcat.................................................................................71
Eliminar directorios de trabajo.......................................................................72
Comportamiento de la carga de clases..........................................................72
Optimización de JSP........................................................................................72
Optimización de Log4J...................................................................................73
El mbean de registro..................................................................................73
Deshabilitar el registro por consola........................................................73
Cambiar el nivel de registro...................................................................74
3
Capítulo I : Instalación de JBoss
Introducción.
JBoss es un servidor de aplicaciones J2EE de código abierto
implementado en Java puro. Al estar basado en Java, JBoss puede ser utilizado
en cualquier sistema operativo que lo soporte. Los principales desarrolladores
trabajan para una empresa de servicios, JBoss Inc., adquirida por Red Hat en
Abril del 2006, fundada por Marc Fleury, el creador de la primera versión de
JBoss. El proyecto está apoyado por una red mundial de colaboradores. Los
ingresos de la empresa están basados en un modelo de negocio de servicios.
JBoss implementa todo el paquete de servicios de J2EE.
Pasos Previos.
Instalación del JDK (JSE)
La base para operar cualquier producto que utiliza "Java" es el "JDK" de la
plataforma correspondiente, puede encontrar instrucciones para plataformas
Linux así como Windows, en http://java.sun.com
Instalación de JBoss
Una vez obtenido el archivo tar o exe (depende del sistema operativo) de
http://www.jboss.org que contiene el binario, este debe ser instalado (o
descomprimido en Linux) en un directorio temporal (/tmp por lo general) para
poder iniciar la instalación.
El paso anterior genera un directorio por nombre JBoss-
<numero_de_version> dentro del directorio temporal (/tmp) si desciende a
este directorio observará el directorio jboss el cual contiene la distribución de
Jboss.
Cabe mencionar que la versión de Tomcat incluida en JBoss es idéntica a
la proporcionada en http://jakarta.apache.org/tomcat , la única diferencia es
que los archivos de configuración para JBoss se encuentran adaptados a
Tomcat.
Se recomienda movilizar el directorio jboss al directorio /usr/local,
además se recomienda definir la variable ambiental JBOSS_HOME al archivo
/etc/bashrc , si no esta familiarizado con ambientes *nix, esto significa agregar
la linea: export JBOSS_HOME=/usr/local/jboss;; para instalaciones Windows esta
variable ambiental puede ser definida de la misma manera que CLASSPATH,
descrita en las instrucciones del JDK.
4
Estructura
bin
Este directorio contiene los ejecutables utilizados por JBoss, el más
importante siendo el "script" de arranque utilizado por éste (run.sh)
client
Contiene los diversos archivos JAR's que serán utilizados por los distintos
clientes de los EJB's utilizados en JBoss. Dichos archivos deben ser agregados a
la variable CLASSPATH del sistema donde radica el cliente; el cliente
generalmente siendo un JSP/Servlet que accesa el EJB, este paradigma gira
alrededor de Stubs/Skeletons de RMI una parte central de EJB's.
docs
Este directorio contiene documentación acerca de JBoss.
lib
Este directorio contiene los archivos JAR's empleados por JBoss
requeridos en cualquier modalidad.
server
Este directorio contiene tres sub-directorios nombrados: all, default y
minimal; cada sub-directorio contiene los distintos archivos de configuración
necesarios para ejecutar JBoss en diferentes modalidades.
La modalidad all incluye la ejecución de JBoss para emplearse como
cluster, ejecución de webservices y otras funcionalidades más; el directorio
default como su nombre lo implica, incluye la configuración para ejecutar
JBoss de manera básica, mientras el directorio minimal contiene los valores de
configuración necesarios para ejecutar JBoss con requerimientos mínimos; el
script de arranque proporcionado con JBoss emplea los valores del directorio
default, para emplear otra modalidad es necesario modificar dicho script de
arranque (run.sh).
A continuación se describen los directorios residentes en la modalidad de
arranque default:
conf
Este directorio contiene las diferentes secciones de configuración
utilizadas por JBoss, dependiendo de la modalidad utilizada este directorio
puede contener distintos archivos , sin embargo, sus detalles serán descritos
5
en configuración de JBoss .
data
Contiene distintos parámetros y archivos de configuración para las Bases
de Datos proporcionadas con Jboss, generalmente utilizada para aplicaciones
demo.
deploy
Este directorio es ampliamente utilizado ya que aquí se colocan los EJB's
para que sean ejecutados por JBoss, una vez colocado el archivo JAR (en forma
de EJB) en este directorio, JBoss automáticamente expande y ejecuta el EJB.
lib
Contiene los archivos JAR's empleados por JBoss en base a la modalidad
tratada.
log
Contiene los distintos registros generados por JBoss.
tmp
Contiene archivos creados por JBoss y utilizados de manera temporal.
work
Contiene las clases y archivos utilizados por JBoss para ejecución.
Ejecución
La ejecución de JBoss es relativamente sencilla, dentro del directorio bin
de la instalación de JBoss se encuentran los archivos de arranque en forma de
scripts para Shell. El archivo de ejecución run.sh es utilizado para iniciar JBoss
en ambientes *nix con los parámetros encontrados en el directorio
server/default/conf, de igual manera, el archivo run.bat lo hace para
ambientes Windows.
Debe observar algo similar al siguiente desplegado; los detalles de estos
parámetros son aquellos definidos en la configuración de JBoss e incluyen:
bases de datos para trabajar con JBoss, ubicación de registros, parámetros
JNDI, EJB's disponibles y cargados, entre otra información.
[root@jboss]$ ./run.sh
=========================================================================
JBoss Bootstrap Environment
JBOSS_HOME: /tmp/jboss5.0.0
JAVA: /usr/local/jdk1.6.0//bin/java
6
JAVA_OPTS: server Dprogram.name=run.sh
CLASSPATH: /tmp/jboss5.0.0/bin/run.jar:/usr/local/jdk1.6.0//lib/tools.jar
=========================================================================
12:55:10,608 INFO [Server] Starting JBoss (MX MicroKernel)...
12:55:10,610 INFO [Server] Home Dir: /tmp/jboss
12:55:10,610 INFO [Server] Home URL: file:/tmp/jboss/
12:55:10,623 INFO [Server] Library URL: file:/tmp/jboss/lib/
12:55:10,625 INFO [Server] Patch URL: null
........
< 5070 lineas >
.......
.......
12:55:31,862 INFO [Http11Protocol] Starting Coyote HTTP/1.1 on http0.0.0.0
8080
12:55:32,074 INFO [ChannelSocket] JK2: ajp listening on /0.0.0.0:8010
12:55:32,192 INFO [JkMain] Jk running ID=1 time=0/149 config=null
12:55:32,216 INFO [Server] JBoss (MX MicroKernel)
Started in 21s:146ms
Esta pantalla donde se ejecuta JBoss permanecerá congelada por el
término en que este activo JBoss, a esta pantalla se enviarán entre otras cosas:
• Los errores de ejecución
• Resultados de agregar EJB's al directorio deploy de Jboss
Desde luego este comportamiento es modificable pero por ahora es el
comportamiento default de Jboss.
Para finalizar JBoss basta ejecutar Ctrl-C bajo la pantalla en cuestión y
JBoss será terminado, en el proceso desplegando ciertos mensajes de
terminación.
Configuración
JBoss esta compuesto por diversos archivos de configuración los cuales
se encuentran bajo el directorio /server/<modalidad>/conf de la instalación
de JBoss, este directorio a su vez puede contener varios subdirectorios (como
fue mencionado en la instalación y estructura ), esta sección se basa en el
contenido del directorio default.
A continuación se mencionan los parámetros de los principales archivos
para la modalidad default, lo cual equivale al contenido del directorio /server/
default/conf.
jboss-minimal.xml
Archivo que contiene los parámetros principales para la configuración
default de JBoss; este archivo XML define los valores para la variable
CLASSPATH, el puerto para el servidor JNDI y el directorio donde serán
colocados los distintos EJB's para ser ejecutados, entre otros parámetros.
7
jboss-service.xml
Archivo que contiene los parámetros principales del Servidor JBoss; este
archivo XML define los valores para la variable CLASSPATH, el puerto para el
servidor JNDI y el directorio donde serán colocados los distintos EJB's para ser
ejecutados, entre otros parámetros como usuarios y roles disponibles para
emplear el sistema messaging proporcionado con JBoss.
jndi.properties
Contiene las Clases que serán utilizadas ("Factory's") para realizar
búsquedas JNDI.
log4j.xml
Contiene los parámetros empleados por el mecanismo Log4J utilizado en
JBoss para generar registros.
login-config.xml
Contiene los parámetros JAAS empleados por JBoss para
verificar/autentificar usuarios.
server.policy
Parámetros de seguridad empleados por JBoss.
standardjaws.xml
JAWS es el motor de mapeo Objeto/Relacional empleado por JBoss en
CMP (Container Managed Persistence) EJB's, este archivo contiene sus valores
default.
standardjbosscmp-jdbc.xml
Contiene los valores para ser empleados en CMP (Container Managed
Persistence) EJB's.
standardjboss.xml
Contiene los parámetros estándar de configuración para JBoss tales
como: Tamaño de pools para EJB's, valores de cache, numero de pools para
bases de datos, clases empleadas para control de transacciones, entre otros
parámetros.
8
Capítulo II: Despliegue de Aplicaciones.
Introducción.
A continuación se explican los distintos procedimientos para desplegar
aplicaciones JEE en el servidor JBoss.
Despliegue en caliente.
En el capítulo anterior, dentro de la lista de directorios vistos que
componen la estructura de JBoss, pudimos observar el siguiente:
server/default/deploy.
Mientras que otros servidores de aplicaciones requieren procesos que
impliquen el reinicio del servidor o simplemente utilizar interfaces Web para tal
caso, JBoss ofrece una técnica bastante mas sencilla para el despliegue de
aplicaciones.
Suponiendo que la aplicación ya está construida y empaquetada en el
archivo app.jar, basta con copiar este archivo al directorio antes mencionado,
de la siguiente forma:
[root@jboss]$ cp <directorio aplicacion>/app.war server/default/deploy
Por lo que a continuación veremos un mensaje en la salida de Jboss como
el siguiente:
deploy, ctxPath = /app
Al ver este mensaje, podemos entonces afirmar que la aplicación app.jar
fue correctamente desplegada en el servidor. Cualquier otro mensaje nos dará
la información necesaria para ver el por qué no se produjo el proceso de
despliegue.
La comprobación de la aplicación depende del contexto en el cual se
requiera ejecutar la aplicación, ya que puede ser una aplicación JSP, Servlet,
EJB, etc.
Estructura del descriptor de despliegue.
Un descriptor de despliegue (en inglés Deployment Descriptor) (DD) es
un componente de aplicaciones JEE que describe cómo se debe desplegar (o
implantar) una aplicación web. Esto dirige una herramienta de despliegue (o
publicación) para desplegar un módulo o aplicación con opciones de
contenedor específicas y describe requisitos de configuración específicos que
9
puede resolver un desplegador.
En aplicaciones JEE, XML se usa para la sintaxis del fichero descriptor de
despliegue. Debe ser llamado web.xml, y debe ser colocado en un
subdirectorio llamado WEB-INF, directamente debajo de la raíz de la aplicación
web.
La estructura de este archivo, en su forma mas mínima es la siguiente:
<?xml version="1.0"?>
<webapp version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd">
<description>Descripcion de la aplicacion</description>
<servlet>
<servletname>Servlet</servletname>
<servletclass>servlet</servletclass>
</servlet>
<servletmapping>
<servletname>Servlet</servletname>
<urlpattern>/ruta</urlpattern>
</servletmapping>
</webapp>
Como se puede apreciar, la estructura del archivo contiene información
sobre la aplicación, sus clases y las rutas de acceso desde el servidor.
Claramente, esta configuración es mínima y tiene muchos mas
parámetros que son precisos para levantar las aplicaciones correctamente.
A lo largo de este documento, se irán agregando nuevos parámetros de
configuración a este archivo descriptor.
Estructura de un paquete de aplicación.
Una aplicación JEE, en su forma mas mínima, debe contener la siguiente
estructura de directorio:
METAINF/
manifest.mf
WEBINF/
classes/
src/
lib/
web.xml
El contenido de los directorios es el siguiente:
10
El directorio META-INF, relacionado con archivos .jar contiene el archivo
manifest.mf, el cual contiene la lista de contenidos del archivo, y son
generados al momento de crear el archivo.
El directorio WEB-INF contiene todo lo necesario para ejecutar la
aplicación, se divide en las siguientes secciones:
classes: Donde se almacenan todas las clases compiladas de la aplicación.
lib: Donde se almacenan las librerias necesarias para ejecutar la aplicación.
src: (optativo) Contiene el código fuente de la aplicación.
Empaquetado de la aplicación.
Una vez que la aplicación JEE está correctamente construida y cumple
con el estándar descrito anteriormente, el empaquetado ser realiza con el
siguiente comando.
[root@jboss]$ jar cvf app.war app
Y posteriormente, este archivo WAR se copia al directorio deploy visto
anteriormente para desplegar la aplicación.
11
Capítulo III: Integración de JBoss con Eclipse.
Introducción.
Eclipse es un entorno de desarrollo integrado de código abierto
multiplataforma para desarrollar lo que el proyecto llama "Aplicaciones de
Cliente Enriquecido", opuesto a las aplicaciones "Cliente-liviano" basadas en
navegadores. Esta plataforma, típicamente ha sido usada para desarrollar
entornos de desarrollo integrados (del inglés IDE), como el IDE de Java llamado
Java Development Toolkit (JDT) y el compilador (ECJ) que se entrega como parte
de Eclipse (y que son usados también para desarrollar el mismo Eclipse). Sin
embargo, también se puede usar para otros tipos de aplicaciones cliente, como
BitTorrent Azureus.
Eclipse es también una comunidad de usuarios, extendiendo
constantemente las áreas de aplicación cubiertas. Un ejemplo es el
recientemente creado Eclipse Modeling Project, cubriendo casi todas las áreas
de Model Driven Engineering.
Eclipse fue desarrollado originalmente por IBM como el sucesor de su
familia de herramientas para VisualAge. Eclipse es ahora desarrollado por la
Fundación Eclipse, una organización independiente sin ánimo de lucro que
fomenta una comunidad de código abierto y un conjunto de productos
complementarios, capacidades y servicios.
Obtener Eclipse.
Para obtener Eclipse, es preciso visitar la siguiente página web:
http://www.eclipse.org/downloads/
En la lista de descargas, se puede apreciar lo siguiente:
12
La primera opción a descargar corresponde precisamente al IDE que se
necesita para trabajar de forma integrada con JBoss.
Una vez descargado y descomprimido el archivo correspondiente a la
plataforma deseada (Linux, Windows, MacOS X), se aprecia un contenido de
directorio como el siguiente:
Para ejecutar la aplicación, basta con hacer doble clic sobre el icono
eclipse delimitado en la imagen.
Una vez ejecutada la aplicación, se observa la siguiente pantalla de
13
inicio:
Los apartados se describen de la siguiente forma:
A la izquierda aparecerá la lista de proyectos creados y/o abiertos
actualmente, con el árbol de contenidos respectivo.
Al centro se presentará tanto el código fuente de la aplicación como su
ejecución.
Al costado derecho aparecerá información relativa a los objetos que se
vayan seleccionado.
En el costado inferior aparecerá toda la información relativa con el
entorno de ejecución, tanto como la lista de servidores, la consola de
ejecución, las fuentes de datos, etc.
Configurar Eclipse con JBoss.
Para agregar un nuevo servidor JBoss, es preciso seleccionar la viñeta
Servers en este apartado (como se aprecia en la figura) y luego hacer clic con
el botón derecho del ratón en el fondo. La vista será como la siguiente imagen:
14
Seleccionamos entonces New y luego Server, donde se aprecia la
siguiente ventana de diálogo:
En la lista se pueden apreciar todos los servidores JEE compatibles con
esta versión de Eclipse. En esta ocasión, como se aprecia en la figura, se
escoge el servidor JBoss versión 4.2
Al hacer clic sobre el botón Next, aparece el siguiente cuadro de diálogo:
15
En la primera parte seleccionamos el entorno JRE (Java Runtime
Enviroment) con que deseamos ejecutar nuestro servidor, y luego damos la
ruta donde está instalado nuestro JBoss.
Al hacer clic en el botón Next aparecerá el siguiente cuadro de diálogo:
16
Dado que podemos tener mas de un servidor JBoss en ejecución en
nuestro sistema o entorno de desarrollo, podemos indicar a Eclipse que
arranque nuestro servidor de aplicaciones con otros parámetros, tales como la
IP de escucha, el puerto del frontend web, el puerto del JNDI (Java Naming and
Directory Interface) etc.
En este caso, no modificamos ningún parámetro y simplemente damos
clic en el botón Finish. Las pantallas siguientes son solamente para la
inclusión de otros módulos y/o librerías para ejecutar aplicaciones que no
incluiremos en este manual.
Finalizada la configuración, la vista Servers de Eclipse tendrá el siguiente
aspecto:
17
Para arrancar JBoss, podemos hacer clic en el icono Play ubicado en la
esquina superior derecha o simplemente crear una aplicación e indicar que
vamos a ejecutarla con esta versión del servidor.
18
Capítulo IV : Monitorización.
Introducción.
La Java Management eXtensions (JMX) API es un estándar de Sun para la
gestión y monitorización remota de recursos java como:
• Aplicaciones y dispositivos
• Servidores y servicios
• JVM
que nos permite entre otras cosas consultar o cambiar una determinada
configuración, conocer estadísticas y comportamiento de una aplicación,
conocer cambios de estado (y notificarlo, iniciar acciones, etc), crear nuestros
manejadores de recursos y publicarlos en una API, interoperar con otras
tecnologías...
JMX se integró pronto en la J2EE y más tarde en la JSE, concretamente
desde la JDK 5. Su jerarquía de subpaquetes se encuentran bajo
javax.management, y esta es su API pública. Asimismo existe una API privada
bajo com.sun.jmx, a la que sólo debería tener acceso las propias librerías de la
JDK, puesto que esta implementación puede evolucionar y ser cambiada en
futuras versiones.
A partir de la JDK 5.0 se incluye Jconsole para monitorizar la JVM y
aplicaciones que implementen JMX. Es un ejecutable con interfaz gráfica que se
encuentra en la carpeta bin de la instalación de la distribucion de Sun JDK.
Arquitectura de JMX.
Arquitectura basada en 3 capas:
1. Capa de aplicación (o nivel de instrumentación), la capa de más bajo
niveles donde residen los componentes (MBean) que facilitan la
información necesaria para la gestión de una aplicación. Estos
componentes son desarrollados según las necesidades de gestión
específicas de cada parte de una aplicación.
2. Nivel de agente: facilita una interfaz para el manejo de los MBean del
nivel de instrumentación.
3. Nivel de Adaptadores: uno o más conectores (o adaptadores de
protocolo) que proporcionan acceso desde los sistemas de monitorización
remotos.
19
Monitorización de JBoss
JBoss implementa JMX en su microkernel. El propio servidor dispone de un
una consola JMX accesible por la URL http://localhost:8080/jmx-console que
muestra los MBeans públicos accesibles por ella o programáticamente por
código Java:
20
Algunas acciones útiles:
• Mostrar el árbol JNDI .
• Forzar un volcado de memoria .
• Mostrar el uso del pool de memoria .
• Gestionar el escáner de despliegues .
• Redesplegar una aplicación .
• Acceder a la base de datos Hypersonic .
• Detener JBoss
• Conocer estado de los EJB desplegados e instanciados
Monitorización con JConsole
JConsole (www.servletsuite.com) usa el JMX de JBoss para monitorizar el
servidor: estado, logs, despliegues, uploads y visor de los Mbeans:
Para poder trabajar con JConsole debemos seguir los siguientes pasos:
• Descargar jconsole.war desde
http://www.servletsuite.com/jmx/jconsole.htm
• Copiar jconsole.war en la carpeta deploy del servidor utilizado, para su
despliegue (habitualmente en server/default/deploy)
• Con JBoss en ejecución, acceder a http://localhost:8080/jconsole
21
Cuando accedamos a la pestaña JMX se nos presentará una casilla para
introducir un patrón que determinará los MBeans que visualizaremos en la lista
inferior. Los patrones son los habituales:
• Nombre totalmente cualificado
por ejemplo: boss.j2ee:service=EARDeployer
• Wildcard: *, ?
por ejemplo: jboss.jm?:*, jboss:*, jboss.*:*, *:*
22
Monitorización con ManageEngine Applications Manager
ManageEngine Applications Manager es un potente monitor
comercial con una versión libre (limitación: máximo 5 monitores) aplicable a
servidores, BBDD, aplicaciones, websites, ERP, transacciones y mucho más. Ha
sido diseñada con una interfaz muy completa y ofrece múltiples estadísticas,
que pueden asociarse acciones al seguimiento de recursos, como alarmas y
notificaciones por correo electrónico. Permite la monitorización de recursos
remotos (los anteriores monitores se limitaban al servidor local) y la
monitorización de MBeans de JMX, por supuesto.
Para instalar, debemos descargar la aplicación desde
http://manageengine.adventnet.com/products/applications_manager/download.
html y ejecutar el instalable.
23
Para continuar, hacemos clic en el botón next.
Una vez aceptados los términos de la licencia, hacemos clic en el botón
next.
24
Luego de escoger la versión Free Edition que nos permitirá operar hasta
30 días (para luego transformarse en la versión libre) hacemos clic en el botón
next.
25
En esta ventana, se nos pide escoger el idioma de la instalación. En el
ejemplo se utilizará el inglés (English). Para continuar, debemos hacer clic en el
botón next.
En esta ventana se nos pide escoger el puerto donde levantará la
aplicación web. Por defecto se utiliza el 9090. Para continuar, clic en el botón
next.
26
Para coleccionar las estadísticas, la aplicación nos pide elegir entre
MySQL (el cual viene incluido en la aplicación) o Microsoft SQL Server. En el
caso del ejercicio, escogemos MySQL. Continuamos la instalación haciendo clic
en el botón next.
En esta ventana se nos pide escoger la ruta de la instalación.
Continuamos la instalación haciendo clic en el botón next.
27
En esta última ventana, se nos presenta el resumen de la instalación.
Hacemos clic en el botón next para continuar o en back si queremos hacer
algún cambio antes de terminar.
Una vez finalizada la instalación, al dirigirnos a la ruta escogida para la
instalación de la aplicación, nos encontraremos con los siguientes íconos.
Para arrancar, entonces debemos hacer clic en el ícono
startApplicationsManager.sh y luego en startWebConsole.sh. El primero
arrancará la aplicación. El segundo arrancará el entorno web.
Para acceder a la aplicación entonces, debemos abrir la siguiente URL en
nuestro navegador: http://localhost:9090, lo cual se verá como la siguiente
pantalla:
28
Como se indica en las instrucciones, el usuario por defecto es admin, y
la contraseña por defecto es admin.
Como podemos ver, ManageEngine Applications Manager nos permite
inclusive configurar alertas a través de correo electrónico.
Una vez configurado el nodo de monitorización, observamos la siguiente
ventana:
29
Monitorización con Munin
A pesar de que las herramientas previamente descritas permiten
monitorizar JBoss de manera óptima, en un gran porcentaje de los casos es
preciso monitorizar en conjunto a otras variables, tales como la memoria, el
espacio en disco, la carga del servidor, etc.
Para tal caso, a continuación se describirá como instalar la herramienta
Munin en el servidor.
Munin opera sobre la base de recolector de información (munin-master) y
de nodo (munin-node) como se aprecia en la siguiente figura:
Podríamos entonces eventualmente dejar un equipo o un servidor como
recolector de información munin-master e instalar en cada nodo de un posible
clúster JBoss solamente el munin-node. Claramente, en un mismo equipo o
servidor pueden coexistir tanto munin-master como munin-node.
30
Instalación de munin-master.
Antes de instalar el munin-master en nuestro equipo o servidor, es
preciso contar con un servidor web para poder visualizar los gráficos. Se
explicarán entonces los comandos necesarios para instalar munin-master o el
recolector en conjunto con el servidor web Apache o de forma unitaria si ya se
cuenta con los paquetes instalados.
Instalación en Debian/Ubuntu
Si se utiliza Debian o Ubuntu como distribución Linux, es tan fácil como
ejecutar el siguiente comando:
Sin Apache instalado:
# aptget install apache munin
Con Apache instalado:
# aptget install munin
Recordamos que el carácter almohadilla (#) por convención se refiere a
que es preciso contar con privilegios de administrador (root) en el equipo y/o
servidor.
Instalación en CentOS
La forma mas sencilla de instalar munin-master en un servidor es
precisamente agregando un repositorio YUM que lo contenga. El repositorio
mas popular y completo para tal caso corresponde a Dag Wieers YUM.
Una vez que el repositorio es instalado, solo debemos utilizar YUM para
instalar el munin-master.
Para indicar a YUM que debe buscar además de lo cotidiano los paquetes
a instalar en el repositorio Dag Wieers, debemos crear un archivo en la
ubicación /etc/yum.repos.d/dag.repo con el siguiente contenido.
[dag]
name=Dag RPM Repository for Red Hat Enterprise Linux
baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag
gpgcheck=1
gpgkey=http://dag.wieers.com/rpm/packages/RPMGPGKEY.dag.txt
enabled=1
31
Luego, basta con ejecutar el siguiente comando:
Sin Apache instalado:
# yum y install httpd munin
Con Apache instalado:
# yum y install munin
Configuración del munin-master.
El paso siguiente, luego de haber instalado correctamente la aplicación,
es configurar el recolector donde debemos indicar la ruta donde debe generar
las páginas web con las estadísticas recolectadas e indicarle en que rutas se
encuentran los distintos nodos que debe monitorizar. Para ello, debemos editar
el archivo /etc/munin/munin.conf donde debemos encontrar las siguientes
línea:
# The next three variables specifies where the location of the RRD
# databases, the HTML output, and the logs, severally. They all
# must be writable by the user running munincron.
dbdir /var/lib/munin
htmldir /var/www/munin
logdir /var/log/munin
rundir /var/run/munin
En el caso de Debian/Ubuntu, por defecto se instala el servidor Web
Apache indicando que el DocumentRoot (o ruta de documentos) por defecto es
/var/www, para el caso de CentOS, esta ruta corresponde a /var/www/html.
Por lo tanto, debemos dejar tal como está la configuración en el
parámetro htmldir o cambiarlo por el valor correspondiente, dependiendo de
la ruta del VirtualHost, la distribución de Linux, etc.
Para mayor información, es preciso referirse a la documentación
oficial de Apache.
Para configurar la lista de nodos que estarán entregando la información
necesaria para recolectar, debemos ubicar la siguiente línea en el archivo de
configuración:
# a simple host tree
[localhost]
address 127.0.0.1
use_node_name yes
32
En esta vista, se configura el nombre del nodo que vamos a utilizar
(localhost) y la dirección IP donde está eventualmente escuchando nuestro
munin-node. El recolector se comunicará con el nodo y le pedirá que le
entregue toda la información necesaria.
Suponiendo que contamos con 3 nodos en las direcciones IP
192.168.1.10, 192.168.1.11 y 192.168.1.12, una configuración podría ser como
la siguiente:
[equipo1]
address 192.168.1.10
use_node_name yes
[equipo2]
address 192.168.1.11
use_node_name yes
[equipo3]
address 192.168.1.12
use_node_name yes
Instalación de munin-node.
Debido a que el nodo levanta un servicio totalmente independiente, es
preciso ejecutar uno de los siguientes comandos, dependiendo de la
distribución que se utiliza:
Instalación en Debian/Ubuntu
# aptget install muninnode
Instalación en CentOS
Una vez repetidos los pasos descritos en la instalación del repositorio Dag
Wieers, debemos entonces ejecutar el siguiente comando:
# yum y install muninnode
Ahora debemos entonces configurar el nodo para indicar que información
deseamos que publique a nuestro munin-master. Para tal caso, debemos
dirigirnos al directorio /etc/munin/plugins, donde en su interior se puede
apreciar lo siguiente:
cpu iostat open_inodes
df irqstats processes
33
df_inode open_files sendmail_mailqueue
entropy interrupts sendmail_mailstats
forks load sendmail_mailtraffic
hddtemp_smartctl memory swap
if_err_eth0 netstat vmstat
if_eth0
Esta lista corresponde a todos los scripts que ejecuta el nodo para
recolectar la información y entregarla de forma correcta al munin-master.
Al revisar con detalle la lista (por ejemplo, ejecutando ls -all), podemos
ver información como la siguiente:
cpu > /usr/share/munin/plugins/cpu
Como se puede apreciar entonces, los archivos listados corresponden
simplemente a enlaces duros a un script ubicado en la ruta /usr/share/munin/
plugins. Por lo tanto, para habilitar o deshabilitar un script es tan sencillo
como crear o eliminar el enlace duro según sea necesario.
En caso de necesitar parámetros adicionales para la ejecución de un
script, debemos revisar los archivos contenidos en la ruta /etc/munin/plugin-
conf.d, como por ejemplo, el archivo munin-node.
Dentro de este fichero, podemos apreciar lo siguiente:
[mysql*]
#env.mysqlopts u someuser
Para munin-node, esto quiere decir que todos los scripts que comiencen
con mysql, deben ejecutarse utilizando el parámetro -u someuser. Al estar
precedido de una almohadilla (#), simplemente es una línea comentada.
Arrancar el servicio munin-node
Para que nuestro recolector entonces pueda conectarse al nodo y
comenzar a graficar la información, es preciso arrancar el servicio utilizando el
siguiente comando:
# /etc/init.d/muninnode start
Una prueba de que la configuración es correcta, puede ser la siguiente:
# telnet localhost 4949
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
# munin node at jboss1.linuxcenter.frog.cl
34
fetch load
load.value 0.09
.
Como se aprecia, el nodo informó de que el sistema actualmente tiene
una carga de servidor de 0.09.
Informes
Para poder visualizar entonces los informes, una vez configurados todos
los nodos y establecidos todos los enlaces duros a los scripts que deseamos
que ejecute, debemos abrir una ventana del navegador hacia la URL del
recolector.
Claramente, al principio debemos esperar entre 10 a 15 minutos a que se
ejecute tranquilamente la recolección de información para poder apreciar
gráficas del sistema.
Para poder levantar el Servidor Web Apache, debemos ejecutar uno de
los siguientes comandos, dependiendo de la distribución que estamos
utilizando:
Debian/Ubuntu
# /etc/init.d/apache2 start
CentOS
# /etc/init.d/httpd start
Suponiendo que nuestro recolector tiene la dirección IP 192.168.2.114,
debemos entonces visitar la URL http://192.168.2.114/munin
35
Como se aprecia en el dibujo, munin está perfectamente configurado y
está recolectando información en tres equipos: equipo1, equipo2 y localhost.
Para ver las gráficas, basta con visitar cualquiera de los enlaces, donde
se puede apreciar la siguiente página:
36
Escribir plugins para munin utilizando JMX
Como el objetivo es monitorizar JBoss en conjunto con las otras variables
del sistema, utilizando plugins personalizados para nuestro caso, debemos
saber escribir éstos para munin, donde recolectaremos la información
necesaria.
JBoss, como servidor de aplicaciones que cumple con el estándar JEE,
está provisto de la API JMX (visto anteriormente), donde además nos ofrece de
una aplicación llamada twiddle.sh ubicada dentro del directorio bin de su
instalación (junto con run.sh).
Supongamos que necesitamos monitorizar la memoria libre de JBoss
utilizando JMX. El atributo que nos devuelve esta información lo podemos
obtener desde la siguiente ruta (utilizando jmx-console para tal caso)
Dentro de los atributos del dominio jboss.system del tipo ServerInfo
encontramos lo siguiente:
37
Como se aprecia en el dibujo, el atributo FreeMemory nos devuelve,
expresado en bytes, la cantidad de memoria libre de este servidor JBoss.
Para obtener este parámetro entonces, debemos ejecutar el siguiente
comando utilizando twiddle:
# cd /opt/jboss/bin
# ./twiddle.sh s localhost get jboss.system:type=ServerInfo FreeMemory
La salida de consola de este comando es el siguiente:
FreeMemory=100091928
Por lo tanto, el valor que deseamos obtener y que deseamos que munin-
node informe a munin-master es 100091928.
Necesitamos entonces, de algún modo, poder utilizar este valor
utilizando algún lenguaje de programación para que este plugin se pueda
ejecutar sin problemas. El lenguaje que utilizaremos en este ejemplo
corresponde al lenguaje bash.
Para obtener el valor, claramente vemos que está separado por el
símbolo “=”, entonces, debemos utilizar un comando que nos permita separar
esta cadena en dos partes (FreeMemory y 100091928) y utilizar lo
correspondiente.
Un comando útil es cut, donde podemos indicar por parámetro como
queremos cortar la cadena y que posición queremos utilizar.
38
Para el caso del ejemplo, el comando debería ser el siguiente:
# ./twiddle.sh s localhost get jboss.system:type=ServerInfo FreeMemory | cut f2 d'='
Donde el comando cut captura la salida dada por el comando twiddle, la
separa por el carácter '=' (-d) y nos devuelve la segunda posición (-f2). La
salida es la siguiente:
100091928
Formato de un plugin munin.
Para escribir un plugin munin, debemos implementar dos cosas:
a) La configuración del gráfico.
b) El resultado de la ejecución.
La configuración del gráfico es utilizada por munin-master para dibujar el
mismo, donde debemos indicar el título, el grupo al que pertenece, la unidad
de medida, etc.
El resultado de la ejecución debería ser entonces el valor visto
anteriormente (100091928)
Al hacer nuevamente telnet al puerto 4949 del munin-node, podemos
obtener el formato de configuración de un gráfico cualquiera de la siguiente
forma:
# telnet localhost 4949
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
# munin node at jboss1.linuxcenter.neno2.frog.cl
config load
graph_title Load average
graph_args base 1000 l 0
graph_vlabel load
graph_scale no
graph_category system
load.label load
load.warning 10
load.critical 120
graph_info The load average of the machine describes how many
processes are in the runqueue (scheduled to run "immediately").
load.info Average load for the five minutes.
.
Como se aprecia, la configuración nos indica varios parámetros como por
ejemplo:
39
graph_title : Título del gráfico.
graph_vlabel : Etiqueta vertical
graph_category : Categoría del gráfico.
var.label : Etiqueta
var.warning : Valor de advertencia
var.critical : Valor crítico
Esta información el munin-node la obtiene al ejecutar los scripts ubicados
dentro de la carpeta /etc/munin/plugins:
# cd /etc/munin/plugins
# ./load config
graph_title Load average
graph_args base 1000 l 0
graph_vlabel load
graph_scale no
graph_category system
load.label load
load.warning 10
load.critical 120
graph_info The load average of the machine describes how many
processes are in the runqueue (scheduled to run "immediately").
load.info Average load for the five minutes
Y el valor de la medición se obtiene ejecutando el siguiente comando:
# ./load
load.value 0.59
Comparando ambas situaciones entonces, podemos apreciar que se
define una variable llamada load donde tiene una etiqueta (load.label) y un
valor (load.value)
Por lo tanto entonces, se debería crear un script que al ejecutarse
ofrezca, al menos, la siguiente información:
# ./jbossmemory config
graph_title JBoss Free Memory
graph_vlabel Free Memory
graph_category JBoss
freemem.label Free Memory
graph_info JBoss Free Memory
freemem.info Free Memory.
# ./jbossmemory
freemem.value 103326568
40
El siguiente script, escrito en lenguaje bash, realiza lo anteriormente
descrito:
#!/bin/sh
if [ "$1" = "config" ]; then
echo 'graph_title JBoss Free Memory'
echo 'graph_vlabel Free Memory'
echo 'graph_scale no'
echo 'graph_category JBoss'
echo 'freemem.label Free Memory'
echo 'totmem.label Total Memory'
echo 'graph_info JBoss Free Memory'
echo 'freemem.info Free Memory.'
exit 0
fi
cd /opt/jboss/bin
echo n "freemem.value "
./twiddle.sh s localhost get jboss.system:type=ServerInfo FreeMemory | cut f2 d'='
Para instalar el plugin, basta entonces con copiarlo en la ruta /usr/share/
munin/plugins bajo el nombre jboss_memory, dar privilegios de ejecución y
luego crear el enlace duro en el directorio /etc/munin/plugins.
# cp jboss_memory /usr/share/munin/plugins
# chmod +x /usr/share/munin/plugins/jboss_memory
# ln sn /usr/share/munin/plugins/jboss_memory /etc/munin/plugins/jboss_memory
Y finalmente, incluirlo en el archivo munin-node dentro de /etc/munin/
plugin-conf.d indicando que todos los plugins que comiencen con “jboss”
deben ser ejecutados con un parámetro, como por ejemplo:
[jboss*]
user root
Luego de unos minutos, veremos entonces que la gráfica de este
recolector se parecerá a la siguiente:
41
El período de ejecución de nuestro munin-master viene dado por la
siguiente configuración en el archivo munin dentro del directorio /etc/cron.d.
*/5 * * * * munin test x /usr/bin/munincron && /usr/bin/munincron
Donde cada 5 minutos, con privilegios de usuario munin intentará
ejecutar el script /usr/bin/munin-cron, el cual en su interior contiene lo
siguiente:
#!/bin/sh
[ x /usr/share/munin/muninupdate ] && /usr/share/munin/muninupdate $@;
[ x /usr/share/munin/muninlimits ] && /usr/share/munin/muninlimits $@;
[ x /usr/share/munin/muningraph ] && nice /usr/share/munin/muningraph $@;
[ x /usr/share/munin/muninhtml ] && nice /usr/share/munin/muninhtml $@;
Que como se puede apreciar, son una serie de scripts que tienen por
objetivo actualizar la información, calcular los límites, crear los gráficos y
generar el código HTML necesario para visualizar las estadísticas.
Conclusión.
Luego de toda la explicación para instalar munin-master, munin-node,
configurar y programar plugins, vemos que el gran responsable de una correcta
recolección de estadísticas, recae en el administrador que debe saber ubicar el
atributo JMX necesario para la situación.
42
Monitorización con Nagios
Introducción.
Para extender la monitorización de nuestro JBoss, es preciso no contar
solamente con herramientas de recolección de información, si no que además
que “se nos avise” mediante un correo electrónico cuando una situación es
“anormal”.
Supongamos que deseamos que se active una alarma de advertencia
cuando el porcentaje de memoria libre corresponda al 20% de la memoria
total. Y supongamos además que deseamos una alarma crítica cuando este
porcentaje llegue al 10%. Esto es posible instalando Nagios como herramienta
de monitorización y escribiendo plugins para el mismo utilizando JMX.
A continuación se procederá a explicar la instalación de Nagios desde el
código fuente:
Requisitos.
Antes de comenzar con la instalación de Nagios, para permitir la vista de
las estadísticas y ver el estado actual de los servicios, es preciso contar con el
siguiente software instalado:
• Servidor Web Apache
• Lenguaje de programación PHP
• Compilador GCC
• Librería GD
Podemos instalar estos paquetes con los siguientes comandos:
Debian/Ubuntu
# aptget install apache2 php gcc glibc glibccommon gd gddevel
CentOS
# yum install httpd php gcc glibc glibccommon gd gddevel
Instalación.
Creamos un usuario llamado nagios y le damos una contraseña:
43
# /usr/sbin/useradd m nagios
# passwd nagios
Creamos un nuevo grupo llamado nagcmd para permitir la ejecución
segura de algunos comandos desde la interfaz web. Además, indicamos que los
usuarios apache o www-data (para el caso de Debian/Ubuntu el usuario por
defecto de apache es www-data y para CentOS el usuario es apache) y
nagios pertenecen a este grupo.
Ambas distribuciones
# /usr/sbin/groupadd nagcmd
# /usr/sbin/usermod a G nagcmd nagios
Debian/Ubuntu
# /usr/sbin/usermod a G nagcmd wwwdata
CentOS
# /usr/sbin/usermod a G nagcmd apache
Creamos un directorio para descargar el código fuente necesario:
# mkdir ~/downloads
# cd ~/downloads
Descargamos el código fuente de Nagios y de Nagios Plugins desde
http://www.nagios.org/download/ donde debemos descargar las últimas
versiones para cada paquete:
# wget http://osdn.dl.sourceforge.net/sourceforge/nagios/nagios3.2.0.tar.gz
# wget http://osdn.dl.sourceforge.net/sourceforge/nagiosplug/nagiosplugins1.4.11.tar.gz
Para compilar e instalar nagios, debemos entonces descomprimir el
código fuente desde el paquete descargado:
# cd ~/downloads
# tar xzf nagios3.2.0.tar.gz
# cd nagios3.2.0
Ejecutamos el script configure dándole el nombre del grupo que
acabamos de crear para su ejecución:
# ./configure withcommandgroup=nagcmd
Compilamos el código fuente:
# make all
44
Instalamos los binarios, los scripts de inicio, los archivos de configuración
por defecto y establecemos los privilegios para la ejeución:
# make install
# make installinit
# make installconfig
# make installcommandmode
Aún no debemos ejecutar Nagios, antes es preciso realizar algunos
ajustes.
Los archivos de configuración de ejemplo han sido instalados en el
directorio /usr/local/nagios/etc. Estos ejemplos nos servirán para comenzar a
trabajar con Nagios. Necesitamos realizar solo un cambio a estos archivos
antes de proceder.
Editamos el archivo /usr/local/nagios/etc/objects/contacts.cfg
cambiando la línea donde aparece el correo electrónico de contacto. Debemos
entonces dejar el nuestro o el que deseamos se utilice para tal práctica.
Instalamos ahora el archivo de configuración necesario para que apache
pueda ejecutar el entorno web de nagios con el siguiente comando:
# make installwebconf
Creamos una cuenta llamada nagiosadmin para poder identificarse en
la interfaz web. El proceso nos pedirá además establecer una contraseña:
# htpasswd c /usr/local/nagios/etc/htpasswd.users nagiosadmin
Reiniciamos Apache para que los cambios surtan efecto:
Debian/Ubuntu
# /etc/init.d/apache2 restart
CentOS
# /etc/init.d/httpd restart
A continuación procederemos a instalar los plugins de nagios. Para ello,
debemos extraer el paquete con el código fuente:
# cd ~/downloads
# tar xzf nagiosplugins1.4.11.tar.gz
# cd nagiosplugins1.4.11
Compilamos e instalamos los plugins:
45
# ./configure withnagiosuser=nagios withnagiosgroup=nagios
# make
# make install
Antes de arrancar nagios, vamos a marcar el script de arranque para
ejecución automática cuando el sistema se inicie:
# chkconfig add nagios
# chkconfig nagios on
Verificamos el archivo de configuración antes de partir (se recomienda
ejecutar esto cada vez que se haga un cambio en dicho archivo)
# /usr/local/nagios/bin/nagios v /usr/local/nagios/etc/nagios.cfg
Si no hay errores, entonces arranquemos nagios:
# service nagios start
Para finalizar, entonces debemos entrar a la interfaz web de nagios
visitando la siguiente dirección: http://localhost/nagios/
Hacemos clic en el enlace Service Detail para ver que es lo que está
siendo monitorizado en nuestro sistema.
Escribir plugins para nagios utilizando JMX
Como el objetivo es monitorizar JBoss en conjunto con las otras variables
del sistema, utilizando plugins personalizados para nuestro caso, debemos
saber escribir éstos para nagios, donde recolectaremos la información
necesaria.
Antes de continuar, es preciso contar con un lenguaje de programación
idóneo para tal situación. El lenguaje escogido para tal caso es el lenguaje Perl,
ya que cuenta con librerías de fácil uso para la programación.
Perl viene por defecto instalado en la mayoría de las distribuciones de
linux, por lo que su instalación no será tratada en este manual.
Para instalar la librería necesaria, es preciso ejecutar el siguiente
comando:
# cpan i Nagios::Plugin
Por ser la primera vez que estamos ejecutando cpan (Comprehensive
Perl Archive Network) nos pedirá alguna información adicional, sobre todo lo
relacionado con nuestra ubicación actual y el espejo mas cercano, para
46
realizar las descargas de paquetes de manera rápida.
La creación de un plugin nagios necesita, generalmente, de dos
argumentos que deben ser pasados al mismo, el valor warning y critical que
corresponden al valor de advertencia y de criticidad del evento
respectivamente.
Supongamos que la alarma dice lo siguiente:
Normal: de 0 a 80
Advertencia: de 80 a 90
Critico: de 90 a 100
Entonces nuestro script debe estar programado de tal forma que el valor
a medir sea definido en porcentaje y ser capaz de recibir estos dos
argumentos. Esto es debido a que nagios para poder reconocer este script
como un plugin, debe estar incluido en sus archivos de configuración.
Revisemos entonces el archivo commands.cfg ubicado en
/usr/local/nagios/etc/objects, en su interior podemos ver como se configura
un comando, como por ejemplo, aquel que chequea la carga del servidor.
Encontramos entonces una línea como la siguiente:
# 'check_local_load' command definition
define command{
command_name check_local_load
command_line $USER1$/check_load w $ARG1$ c $ARG2$
}
Como podemos observar, al referirnos al comando check_local_load se
ejecuta un script llamdo check_load con dos parámetros: -w para warning y -c
para critical.
Si ejecutamos el comando en forma local, desde la ubicación
/usr/local/nagios/libexec (ruta donde se almacenan los plugins) vemos lo
siguiente:
# ./check_load w 2 c 3
OK load average: 0.05, 0.18, 0.13
La salida del script nos indica que todo está OK, puesto que el valor de
carga está entre 0 y 2. De haber estado entre 2 y 3 hubiese marcado WARNING
y sobre 3 hubiese marcado CRITICAL
Nuestro objetivo entonces es crear un script que nos permita indicar
estos parámetros y tener una salida similar.
El siguiente código cumple con el objetivo:
47
#!/usr/bin/perl
use strict;
use warnings;
use Nagios::Plugin ;
use vars qw($VERSION $PROGNAME $verbose $warn $critical);
$VERSION = '1.0';
use File::Basename;
$PROGNAME = basename($0);
my $p = Nagios::Plugin>new(
usage => "Usage: %s
[ c|critical=<critical threshold> ]
[ w|warning=<warning threshold> ]",
version => $VERSION,
blurb => 'test'
);
$p>add_arg(
spec => 'warning|w=s',
help => 'warning value'
);
$p>add_arg(
spec => 'critical|c=s',
help => 'critical value',
);
$p>getopts;
unless (defined $p>opts>warning || defined $p>opts>critical ) {
$p>nagios_die("not enough arguments");
}
#####
my $return = `/opt/jboss/bin/twiddle.sh s localhost get jboss.system:type=ServerInfo FreeMemory`;
my @arr = split("=", $return);
my $free = $arr[1];
$return = `/opt/jboss/bin/twiddle.sh s localhost get jboss.system:type=ServerInfo TotalMemory`;
@arr = split("=", $return);
my $total = $arr[1];
my $result = 0;
if (int $total > 0)
{
$result = int (($free / $total) * 100);
}
#####
$p>nagios_exit(
return_code => $p>check_threshold($result),
message => "Free memory $result%"
);
Como podemos observar, el único código que debemos modificar es
aquel que se encuentra delimitado por #####, ya que es ahí donde utilizando
twiddle y JMX podemos saber el valor total de memoria, la memoria disponible
y luego se calcula el porcentaje.
Para agregar este plugin a los comandos reconocidos por nagios,
debemos editar el archivo indicado anteriormente y agregar lo siguiente:
#JBoss
define command{
command_name check_jboss_memory
command_line $USER1$/check_jboss_memory w $ARG1$ c $ARG2$
}
48
Y para poder chequear este valor contra un servidor, debemos editar el
archivo localhost.cfg dentro de /usr/local/nagios/etc/objects agregando las
siguientes líneas:
#JBoss
define service{
use localservice
host_name localhost
service_description JBoss Memory
check_command check_jboss_memory!80!90
}
Donde claramente vemos que el primer argumento corresponde al valor
warning (80) y el segundo argumento corresponde al valor critical (90).
49
Capítulo V: JAAS
A continuación se describe la forma de asegurar el acceso a una
aplicación web en JBoss, se describe la forma más simple, con la obtención de
usuarios desde un archivo de texto, pero sirve como base para autenticar
contra bases de datos o servidores LDAP.
Configuración de la seguridad estándar en la aplicación web.
Se debe modificar el descriptor XML de la aplicación web (el archivo es
WEB-INF/web.xml dentro del war) para agregar los tag security-constraints y
login-config:
<webapp>
<securityconstraint>
<webresourcecollection>
<webresourcename>Application Name</webresourcename>
<urlpattern>/*</urlpattern>
<httpmethod>GET</httpmethod>
<httpmethod>POST</httpmethod>
</webresourcecollection>
<authconstraint>
<rolename>Admin</rolename>
</authconstraint>
</securityconstraint>
<loginconfig>
<authmethod>BASIC</authmethod>
<realmname>Application Name</realmname>
</loginconfig>
<securityrole>
<rolename>Admin</rolename>
</securityrole>
</webapp>
Configurar un módulo de login JAAS
Se debe configurar el módulo contra el cual se realizará la validación,
estos módulos se declaran en /server/<tipo>/conf/login-config.xml. El
módulo más simple de autenticación es basado en archivos
(UserRolesLoginModule).
Este módulo se declara como un nuevo application-policy en este
archivo:
<applicationpolicy name="fileLoginModule">
<authentication>
<loginmodule
code="org.jboss.security.auth.spi.UsersRolesLoginModule"
flag="required"/>
</authentication>
</applicationpolicy>
50
Requiere dos archivos de propiedades, llamados users.properties y
roles.properties que deben ubicarse en el directorio WEB-INF/classes del
WAR.
El formato del archivo users.properties es el de un archivo de
propiedades donde la clave es el nombre de usuario y el valor la clave de
acceso:
admin=adminpwd
En el archivo roles.properties la clave es el nombre del usuario y el
valor la lista de roles de ese usuario, separados con ","
admin=Admin
Configuración de la seguridad específica de JBoss en la aplicación
web.
Se debe agregar al WAR un descriptor de aplicación web para JBoss, este
descriptor es un archivo META-INF/jboss-web.xml dentro del war, y contiene
configuraciones específicas de JBoss, por ejemplo el nombre del login module a
utilizar para la validación de usuarios.
Ejemplo de WEB-INF/jboss-web.xml:
<jbossweb>
...
<securitydomain>java:/jaas/fileLoginModule</securitydomain>
...
</jbossweb>
Notar que el nombre después de java:/jaas/ debe coincidir con el nombre
declarado en el application-policy, en el archivo login-config.xml
Creación de tablas y carga de datos en SQL.
Si la autenticación la vamos a realizar contra base de datos, lo primero
que necesitamos es crear las tablas en un motor de bases de datos, como por
ejemplo MySQL.
Ni el nombre de las tablas es fijo, ni el nombre de los campos de cada
tabla, con lo que si ya tenemos un modelo de datos que responde a esta
estructura no será necesario migrarlo. Veremos que, tanto la consulta de
usuario, como la consulta de perfil se realizan a través de una sentencia sql
parametrizable.
51
El siguiente script crea dos tablas:
• role: con una clave única y un nombre. El campo nombre será
importante a la hora de definir la autorización.
• user: con una clave única, un login, una contraseña y una clave foránea
que vincula un usuario a un rol.
DROP TABLE IF EXISTS `user`;
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`id` int(10) unsigned NOT NULL,
`name` varchar(64) collate utf8_spanish_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL auto_increment,
`login` varchar(128) collate utf8_spanish_ci NOT NULL,
`password` varchar(128) collate utf8_spanish_ci NOT NULL,
`roleId` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `ndx_user_roleId` (`roleId`),
CONSTRAINT `fk_user_roleId`
FOREIGN KEY (`roleId`) REFERENCES `role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
El siguiente script inserta dos usuarios y dos roles:
• admin, con contraseña admin, asociado al rol "ADMINISTRATOR"
• user, con contraseña password, asociado al rol "USER"
INSERT INTO `role` (`id`,`name`) VALUES
(1,'ADMINISTRADOR'),
(2,'USER');
INSERT INTO `user` (`id`,`login`,`password`,`roleId`) VALUES
(1,'admin','ISMvKXpXpadDiUoOSoAfww==',1),
(2,'user','X03MO1qnZdYdgyfeuILPmQ==',2);
Las contraseñas están encriptadas usando el algoritmo MD5 en Base64.
52
Definición del datasource y configuración de la política de seguridad en
JBoss.
La definición de una fuente de datos en JBoss se realiza añadiendo un
fichero con extensión -ds.xml en el directorio /server/<tipo>/deploy, con el
siguiente contenido:
<?xml version="1.0" encoding="UTF8"?>
<datasources>
<localtxdatasource>
<jndiname>simpleDS</jndiname>
<connectionurl>jdbc:mysql://localhost:3306/test</connectionurl>
<driverclass>com.mysql.jdbc.Driver</driverclass>
<username>test</username>
<password>test</password>
</localtxdatasource>
</datasources>
Tenemos que configurar:
• jndi_name: con un id único para nuestro datasource, que usaremos para
invocarlo desde nuestra política de seguridad.
• connection-url: con la dirección y el nombre de nuestra base de datos
MySQL
• user-name: con el login de un usuario para acceder a la base de datos.
Claro está que no se refiere a uno de los usuarios de las tablas antes
creadas, sino a un usuario de MySQL con permisos de lectura para
acceder a la base de datos.
• password: con la contraseña de acceso del usuario anterior.
En nuestro caso tenemos un fichero /server/<tipo>/deploy/test-
ds.xml para el acceso a la base de datos MySQL de test, con un usuario de
MySQL test con contraseña test.
JBoss no viene con el driver para MySQL preinstalado, con lo que, si aún
no lo tenemos, deberemos obtenerlo y copiar el jar, mysql-connector-
java.jar, en /server/<tipo>/lib.
En el fichero /server/<tipo>/conf/login-config.xml debemos introducir
la siguiente política de seguridad:
53
<!#simpleWeb_config >
<applicationpolicy
name="simpleWebAuthenticationPolicy">
<authentication>
<loginmodule
code="org.jboss.security.auth.spi.DatabaseServerLoginModule"
flag="required">
<moduleoption name="dsJndiName">
java:/simpleDS
</moduleoption>
<moduleoption name="principalsQuery">
SELECT password FROM user WHERE login=?
</moduleoption>
<moduleoption name="rolesQuery">
SELECT role.name, 'Roles'
FROM user , role
WHERE user.roleId=role.id AND
login=?
</moduleoption>
<moduleoption name="hashAlgorithm">MD5</moduleoption>
<moduleoption name="hashEncoding">base64</moduleoption>
</loginmodule>
</authentication>
</applicationpolicy>
Tenemos que configurar:
• <application-policy name="simpleWebAuthenticationPolicy">:
con un id único que identifica nuestra política de seguridad, que
usaremos desde la aplicación web para enlazarla.
• <module-option name="dsJndiName">java:simpleDS<module-
option>: con el nombre del datasource que hemos definido en el punto
anterior.
• <module-option name="principalsQuery"></module-option>: con
la sentencia SQL para la obtención de la contraseña del usuario que
recibe como parámetro. Como comentaba, si vuestro modelo de datos no
se corresponde con el de este ejemplo, aquí asignaríamos la sentencia
correspondiente.
• <module-option name="rolesQuery"></module-option>: con la
sentencia SQL para la obtención del nombre del perfil asociado al
usuario, con las mismas consideraciones que en el punto anterior.
• <module-option name="hashAlgorithm"></module-option>:
indica el nombre de algoritmo que hemos usado para guardar nuestras
contraseñas en la tabla de usuarios.
• <module-option name="hashEncoding"></module-option>: indica
el tipo de encoding que usará el algoritmo para comprobar la contraseña.
En este punto hemos configurado el módulo JAAS de JBoss para que
acceda a nuestra base de datos a través de un datasource, el mismo que
debería usar nuestra aplicación web.
Cambiar de base de datos, para pasar a un entorno de producción, por
ejemplo, es sencillo, basta con modificar el vínculo (el nombre del datasource)
entre la política de seguridad y el datasource, o lo que es más común, al tener
varios datasources (uno por entorno), tendríamos varias políticas de seguridad
(una por cada uno de ellos).
54
Capítulo VI : Clustering.
Configuración de JGroups.
Para aproximarnos a un entorno real hay que añadir otros parámetros en
el comando de arrancada. Además en este post se utiliza la configuración all
para preparar un entorno clusterizable.
Para ver los posibles valores de arranca del servidor de aplicaciones
podemos ejecutar los siguiente:
sh run.sh –help
Que devuelve las posibles opciones de arranque:
h, –help Show this help message
V, –version Show version information
D<name>[=<value>] Set a system property
d, –bootdir=<dir> Set the boot patch directory; Must be absolute or url
p, –patchdir=<dir> Set the patch directory; Must be absolute or url
n, –netboot=<url> Boot from net with the given url as base
c, –configuration=<name> Set the server configuration name
B, –bootlib=<filename> Add an extra library to the front bootclasspath
L, –library=<filename> Add an extra library to the loaders classpath
C, –classpath=<url> Add an extra url to the loaders classpath
P, –properties=<url> Load system properties from the given url
b, –host=<host or ip> Bind address for all JBoss services
g, –partition=<name> HA Partition name (default=DefaultDomain)
u, –udp=<ip> UDP multicast address
l, –log=<log4j|jdk> Specify the logger plugin type
Como el propósito del ejemplo es montar un cluster empezamos
utilizando la configuración all (que permite arrancar el servidor de aplicaciones
en modo cluster, arrancar los web services, HA-JNDI, y otros).
Para arrancar el servidor de aplicaciones con las funcionalidades de
cluster:
sh run.sh c all b <host or ip>, –host=<host or ip>
Este parámetro es importante tenerlo en cuenta pues cambia dos
propiedades del sistema jboss.bind.address y bind.address.JGroups -estos
parámetros sobreescriben los por defecto en la configuración xml del propio
servidor-
jboss.bind.address: indica la dirección donde los servicios Tomcat,
jrmp/pooled invokers services,…etc escucharán.
bind.address.JGroups: utilizada para indicar a JGroups con que IP se hace el
bind del cluster.
Se puede fijar a 0.0.0.0 como dirección IP para bindar a todas las
55
direcciones.
Para nuestro ejemplo utilizamos la ip 192.168.0.1 para levantar los
servicios:
sh run.sh c all b 192.168.0.1
Finalmente podemos probar en el navegador si el arranque ha sido
correcto con http://192.168.0.1:8080
Para parar el servidor de aplicaciones hay que indicar en que dirección IP
está arrancado con el parametro -s y utilizar -S para indicar el shutdown:
sh shutdown.sh s 192.168.0.1 S
Ejecución del cluster.
Arrancar JBoss en ambiente cluster es bastante sencillo, ya que fue
construido pensando en ambientes distribuidos que requieren de esta
característica.
Por defecto, JBoss está configurado para arrancar en modo standalone o
nodo único.
Para arrancar el servicio a modo cluster, debemos seguir los siguientes
pasos.
Vamos a llamar a las máquinas node1 y node2
Para arrancar el servicio escuchando sobre una IP en particular, debemos
arrancar JBoss con los siguientes parámetros:
sh run.sh c all b 192.168.0.1
Suponemos que el node1 tiene IP 192.168.0.1 y que el node2 tiene la IP
192.168.0.2. Con lo que el arranque del nodo2 será
sh run.sh c all b 192.168.0.2
Si ejecutamos los comandos anteriores en las máquinas correspondientes
aún no tenemos el cluster en funcionamiento. Para habilitarlo seguimos
los siguientes pasos para la instalación:
• Debemos asegurarnos que las dos máquinas se ven entre si
(indispensable para la comunicación del cluster)
• JBoss utiliza JGroups para la comunicación para la comunicación entre las
máquinas y se puede realizar a través de UDP o TCP. El modo de
56
comunicación se puede modificar en server/all/deploy/cluster-
service.xml, y debemos especificar una grupo para evitar acoplamiento.
• Para que nuestro cluster no se acople con otros miembros de la red (en el
caso de que existan) debemos dar un nombre
Finalmente los comandos de arranque para los nodos del cluster son:
sh run.sh c all b 192.168.0.1 Djboss.partition.name=TestCluster
Djboss.partition.udpGroup=230.10.0.1
sh run.sh c all b 192.168.0.2 Djboss.partition.name=TestCluster
Djboss.partition.udpGroup=230.10.0.1
Donde -Djboss.partition.name fija el nombre del cluster y
-Djboss.partition.udpGroup fija el grupo UDP en el caso de escoger el modo
de comunicación de red UDP.
Si se escoje el modo TCP este segundo parámetro de configuración no es
necesario. Se utiliza el protocolo UDP por su mejor rendimiento.
Para comprobar que los dos nodos están arrancados:
http://192.168.0.1:8080
http://192.168.0.2:8080
Para parar los servidores de aplicaciones:
sh shutdown.sh s 192.168.0.1 S
sh shutdown.sh s 192.168.0.1 S
Apache mod_jk
mod_jk es un conector que permite JBoss interactuar con servidores web
como Apache e incluso IIS usando el protocolo AJP.
La principal funcionalidad de este módulo es permitir a servidores de
aplicaciones enlazarse con un servidor web. Este servidor web, típicamente el
servidor HTTP Apache, introduce una mayor gestión en las conexiones de los
clientes y mayor la seguridad en las transacciones del sistema. Así mismo se
puede enlazar varias instancias al servidor web permitiendo así una mayor
tolerancia a errores y aligerar la carga en los servidores Java.
Para configurar entonces, debemos descargar el archivo mod_jk.so desde
http://tomcat.apache.org/download-connectors.cgi
57
Debemos entonces copiar el archivo a la ruta donde se almacenan los
módulos de apache, generalmente está en /usr/lib/apache2/modules para
Debian/Ubuntu y en /usr/lib/httpd/modules para CentOS.
Entonces, para que se ejecute, dentro del directorio conf.d (dentro del
directorio de apache) debemos crear los siguientes archivos:
jk.conf
LoadModule jk_module modules/mod_jk.so
JkWorkersFile "conf.d/workers.properties"
JkLogFile "logs/mod_jk.log"
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%S %Y] "
<Location /jkstatus/>
JkMount status
Order deny,allow
Allow from all
</Location>
JkMount /jmxconsole loadbalancer
JkMount /jmxconsole/* loadbalancer
workers.properties
ps=/
worker.list=loadbalancer,status
worker.nodo1.port=8009
worker.nodo1.host=192.168.1.2
worker.nodo1.type=ajp13
worker.nodo1.lbfactor=1
worker.nodo2.port=8009
worker.nodo2.host=192.168.1.3
worker.nodo2.type=ajp13
worker.nodo2.lbfactor=1
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=nodo1,nodo2
worker.status.type=status
El primer archivo (jk.conf) le indica a apache que debe cargar el módulo
mod_jk.so, utilizar el archivo workers.properties como adjunto y que debe
crear una ruta a jmx-console, que será la aplicación que vamos a chequear.
El segundo archivo (workers.properties) le indica al módulo donde están
los distintos nodos, sus direcciones IP y el factor de balanceo de carga que
58
tendrán.
Una vez recargado apache, basta con acceder a la dirección indicada
para comprobar que el cluster está funcionando y balanceando la carga.
El estado del cluster se puede ver accediendo a la siguiente dirección
(suponiendo que apache está corriendo en 192.168.1.1): http://192.168.1.1/jkstatus
Un worker es una instancia que está esperando para ejecutar servlets por
cuenta de algún servidor web. Por ejemplo, podemos tener un servidor web,
como las solicitudes de reenvío servlet de Apache a un proceso JBoss (el
trabajador) corriendo detrás de él.
El escenario descrito anteriormente es muy simple, de hecho, uno puede
configurar varios workers para servir servlets por cuenta de un servidor web
seguro. Las razones de esta configuración pueden ser:
• Queremos que diferentes contextos para ser servido por los diferentes
workers para proporcionar un entorno de desarrollo donde todos los
desarrolladores compartir el mismo servidor web propio, sino un worker
propio.
• Queremos que diferentes hosts virtuales servidos por diferentes procesos
JBoss para proporcionar una separación clara entre los sitios
pertenecientes a diferentes empresas.
• Queremos proporcionar equilibrio de carga, lo que significa ejecutar
múltiples workers de JBoss cada uno en una máquina de su propia y
distribuir las solicitudes entre ellos
Las razones son probablemente más por tener varios workers, pero se
supone que esta lista es suficiente.
Propiedades Globales.
El formato general es
<nombre> = <valor>
Los puntos son utilizados como parte del nombre para representar una
jerarquía de configuración.
Las directivas no válidas se registrarán durante el inicio del servidor web
y evitarán que el servidor web funcione correctamente. Algunas directivas han
sido desaprobadas. A pesar de que todavía funcionan, debe reemplazarlas por
sus sucesores.
59
Algunas directivas se permiten varias veces. Esto se señala
explícitamente en las tablas siguientes.
Directiva Predeterminado Descripción
worker.list ajp13 Comprende una lista separada por comas de los nombres de
los workers que el JK van a utilizar. Al arrancar, el plugin de
servidor Web creará una instancia de los workers, cuyo
nombre aparece en la propiedad worker.list, estos son también
los workers a los que puede asignar las solicitudes.
Esta directiva puede ser usada varias veces.
worker.maintain 60 Corresponde al intervalo de tiempo en segundos que se
validarán los workers.
Propiedades de los workers.
Cada directiva de configuración de los trabajadores se compone de tres
palabras separadas por un punto:
worker.<nombre>.<directiva>=<valor>
La primera palabra es siempre workers. La segunda palabra es el nombre
del worker que puede elegir.
El nombre del worker sólo puede contener caracteres alfanuméricos [AZ]
[AZ] [0-9] [_ \ -] y es sensible a mayúsculas.
Variables, Variables de entorno.
Se pueden definir y usar variables en el archivo workers.properties.
Para definir una variable se utiliza la sintaxis:
<nombre_variable> = <valor>
Los puntos están permitidos en el nombre de variable, pero hay que
tener cuidado de no utilizar nombres de variables, que chocan con las
directrices estándar. Por lo tanto los nombres de variable no debe comenzar
con "worker".
Para utilizar una variable, se puede insertar "$ (nombre)" en cualquier
lugar en el lado de valor de una línea de propiedad. Si una variable no se ha
definido antes de su uso, se busca en el entorno de proceso una variable con el
mismo nombre y el uso de su valor.
Propiedad de herencia.
A menudo se quiere utilizar el valor de la propiedad misma de varios
60
workers. Para reducir la duplicación de las líneas de configuración y facilitar el
mantenimiento del archivo, se pueden heredar propiedades de un worker a
otro, o incluso de una plantilla a los workers.
La directiva de referencia que permite copiar configuraciones entre los
workers de una manera jerárquica. Si la configuración de nodo2 establece
worker.nodo2.reference = worker.nodo1 entonces hereda todas las
propiedades de nodo2, a excepción de los que se establecen explícitamente
de nodo2.
Lista de directivas de los workers.
Directiva Predeterminado Descripción
type ajp13 Tipo de worker (puede ser uno de ajp13, ajp14, JNI, libras o
de estado). El tipo de worker define las directrices que
pueden aplicarse al worker.
Ajp13 es el tipo de worker que se prefiere que JK utilize
para la comunicación entre el servidor web y JBoss. Este
tipo de worker usa sockets como canal de comunicación.
host localhost Nombre de host o dirección IP del servidor JBoss. El
servidor JBoss remoto debe tener soporte para ajp13. El
nombre de host puede tener un número de puerto
incrustado separados por los dos puntos (:).
port 8009 Número de puerto remoto. El valor por defecto depende
del tipo de worker. Para los workers ajp13 el puerto por
defecto es 8009, mientras que para el ajp14 el valor es
8011.
socket_timeout 0 Tiempo de espera en segundos empleados por el canal de
comunicación entre JK y host remoto. Si el host remoto no
responde dentro del tiempo especificado, JK generará un
error, y vuelva a intentarlo de nuevo. Si se pone a cero
(por defecto) JK esperará a una infinita cantidad de tiempo
en todas las operaciones.
socket_connect_timeout socket_timeout*1000 Tiempo de espera en milisegundos utilizado por el canal
de comunicación entre JK y host remoto. Si el host remoto
no responde dentro del tiempo especificado, JK generará
un error, y vuelva a intentarlo de nuevo.
socket_timeout está expresado en segundos, y
socket_connect_timeout en milisegundos, por lo que en
términos absolutos, el socket_connect_timeout defecto es
igual a socket_timeout.
socket_keepalive False Esta directiva debe ser utilizada cuando se tiene un
cortafuegos entre su servidor web y JBoss, que tienden a
interrumpir las conexiones inactivas. Este indicador le dirá
al sistema operativo para enviar mensajes KEEP_ALIVE en
las conexiones inactivas (intervalo dependerá de la
configuración global de sistema operativo, en general, 120
minutos), y evitar así que el servidor de seguridad para
reducir las conexiones inactivas. Para habilitar keepalive
debe establecer este valor de propiedad en True.
ping_mode Este indicador determina las condiciones en que se
sondean las conexiones para asegurarse de que siguen
trabajando. La sonda se realiza con un paquete de ajp13
vacío (ping) y espera recibir una respuesta adecuada
(pong) dentro de algún tiempo de espera.
El valor puede ser cualquier combinación de las siguientes
banderas (varios valores se combinan sin separadores):
C (connect): Si se establece, la conexión se probará una
61
vez después de conectar con el servidor. El tiempo de
espera puede ser fijado por connect_timeout. Si no se
establece, el valor de ping_timeout se utilizará en su
lugar.
P (prepost): Si se establece, la conexión se probará antes
de enviar cada petición al servidor. El tiempo de espera
puede ser fijado por prepost_timeout. Si no se establece,
el valor de ping_timeout se utilizará en su lugar.
I (interval): Si se establece, la conexión será probada
durante el ciclo regular de mantenimiento interno, pero
sólo si está inactivo más de connection_ping_interval.
El tiempo de espera puede ser fijado por ping_timeout.
A Si se activa, todas las formas anteriores se utilizarán.
ping_timeout 10000 Tiempo de espera en milisegundos utilizado cuando se
espera de la respuesta.
connection_ping_interval (ping_timeout/1000)*10 Cuando se activa el chequeo de nodos, las conexiones
inactivas durante más tiempo que este intervalo en
segundos se sondean por CPing si todavía funcionan.
connection_pool_size Esto define el número de conexiones que se realizan al
backend AJP que se mantiene como una agrupación de
conexiones. Esta propiedad de conexión sólo se utiliza
para múltiples hilos de servidores web como Apache, IIS y
Netscape. La propiedad connection_pool_size debe reflejar
el número de solicitudes de un proceso de servidor web
debe ser capaz de enviar a un backend en paralelo.
Normalmente este es el mismo que el número de hilos por
el proceso de servidor web. JK descubrirá este número
para el servidor web Apache automáticamente y
establecerá el tamaño del grupo a este valor.
No deben utilizarse valores superiores a 1 en
Apache 2.x prefork o Apache 1.3.x
connection_pool_minsize (pool+1)/2 El número mínimo de conexiones que se mantendrá.
No deben utilizarse valores superiores a 1 en
Apache 2.x prefork o Apache 1.3.x
connection_acquire_timeout retries*retry_interval Tiempo de espera de que el worker va a esperar para una
toma libre en la memoria caché antes de desistir.
lbfactor 1 Sólo se utiliza para un worker miembro de un balanceador
de carga.
El factor de balanceo de carga es la cuota de trabajo del
worker. El Factor comparado con los otros workers que
hacen el balanceador de carga. Por ejemplo, si un worker
tiene un lbfactor 5 veces superior a otros, entonces
recibirá cinco veces más solicitudes.
Directivas de balanceo de carga.
Directiva Predeterminado Descripción
balance_workers Una lista separada por comas de los workers que el
balanceador de carga necesita manejar.
Esta directiva puede ser usada varias veces para el
balanceador de carga.
Estos workers no deben aparecer en la propiedad worker.list.
sticky_session True Especifica si las solicitudes de ID de la sesión debería ser
redirigida hacia el worker mismo. Si sticky_session se
establece en True las sesiones son pegajosas, de lo contrario
sticky_session se establece en False. Sticky_session
establece en false cuando JBoss está utilizando un
62
administrador de sesión que pueden persistir los datos de
sesión a través de varias instancias.
sticky_session_force False Especifica si las solicitudes de ID de sesión, para los workers
que se encuentran en estado de error deben ser rechazados.
Si sticky_session_force se establece en True y el worker
que coincide con el ID de la sesión está en estado de error, el
cliente recibirá 500 (Error de servidor). Si se establece a
False otro worker se publicará con la correspondiente pérdida
de sesión de cliente. Esta directiva se utiliza sólo cuando se
establece sticky_session = True.
method Request Especifica qué método de balanceo de carga se utiliza para
elegir a los mejores workers. Tenga en cuenta que el período
de sesiones y el balanceo de carga perfecto son objetivos en
conflicto, especialmente cuando el número de sesiones es
pequeño, o el uso de sesiones es extremadamente variable
para un gran número de sesiones de esta por lo general no es
un problema.
Algunos métodos de nota, que se agregan en una ventana de
tiempo de deslizamiento. Se suman los accesos, y en cada
carrera de mantener el método, los contadores de carga se
dividen por 2. Generalmente, esto sucede una vez por minuto,
dependiendo de la configuración de worker.maintain. El
valor de los contadores de carga pueda ser inspeccionado con
el status de los workers.
Si el método se establece en [R]equest el balanceador
utilizará el número de peticiones para encontrar el mejor
worker. Los accesos serán distribuidos de acuerdo con el
lbfactor Este es el valor por defecto y debería ser el
apropiado para la mayoría de las aplicaciones.
Si el método se establece en [S]ession el balanceador
utilizará el número de sesiones para encontrar el mejor
worker. Los accesos serán distribuidos de acuerdo con el
lbfactor. Debido a que el balanceador de no mantiene ningún
tipo de estado, en realidad no sabe el número de sesiones. En
su lugar, cuenta cada solicitud, sin una cookie de sesión o
codificación de direcciones URL como una nueva sesión. Este
método no sabrá, cuando un período de sesiones es inválido,
ni va a corregir sus cifras de carga de acuerdo a los tiempos
de espera de sesión o de conmutación por error de los
workers. Este método debe utilizarse, si las sesiones son la
limitación de recursos, por ejemplo, la memoria cuando sólo
se han limitado y las sesiones necesitan mucha memoria.
Si el método se establece en [T]raffic el balanceador utilizará
el tráfico de red entre JK y JBoss para encontrar el mejor
worker. Los accesos serán distribuidos de acuerdo con el
lbfactor. Este método debe utilizarse si la red hacia y desde
los backends es el recurso limitante.
Si se establece a [B]usyness el balanceador escogerá al
worker con la carga más actual, basado en cuántas peticiones
el worker está cumpliendo actualmente. Este número se
divide por el lbfactor de los workers, y el valor más bajo
(menos ocupados) de los workers. Este método es
especialmente interesante, si su solicitud de tomar un tiempo
para procesar, como para una aplicación de descarga.
lock Optimistic Especifica el método de bloqueo que el balanceador de carga
utiliza para la sincronización de datos de tiempo de ejecución
de la memoria compartida. Si el bloqueo se establece en O
[ptimistic], el balanceador no bloqueará el uso compartido
de memoria para encontrar el mejor worker. Si se pone a P
[essimistic] el balanceador bloqueará el uso compartido de
la memoria. El balanceador trabajará con más precisión en
estado Pessimistic, pero pueden ralentizar el tiempo medio
de respuesta.
retries 2 Si el balanceador de carga no puede obtener un worker válido
o en caso de conmutación por error, se intentará de nuevo un
número de veces dado por reintentos. Antes de cada reintento
63
de envío, se hará una pausa. Se debe definir el parámetro
retry_interval.
La lista completa de configuraciones para este módulo la puede
encontrar en la documentación oficial de mod_jk.
Cluster HA.
Supongamos que parte del proyecto consiste en que, diariamente, se ha
de comunicar a la central desde una sucursal quizás la cantidad de ventas del
dia. El departamento de contabilidad pide estudiar la posibilidad de
informatizar este proceso, e informa de la importancia de que este proceso no
falle. Se sabe además que el departamento de informática de la empresa
dispone de un webservice a través del cual se puede notificar esta información
(no haremos esta parte, ya que no es el objetivo). De esta pequeña
información podemos extraer las siguientes conclusiones:
• Necesitamos un proceso que se ejecute recursivamente a modo de cron.
• Sabemos, que nuestro proceso debe recoger la información de la base de
datos y enviar dicha información diariamente al cierre. Si suponemos que
nuestro cierre es a las 20:00 horas y la apertura es a las 10:00 horas,
podemos suponer, que nuestra tarea recursiva debe conseguir enviar la
información cada día durante el periodo de tiempo que va desde las
20:00 horas del día actual hasta las 10:00 horas del día siguiente. Una
vez que lo consigue, rellena la información enviada en alguna tabla de
base de datos indicando que ese día ya ha sido notificado. Toda esta
parte la podemos resolver mediante un algoritmo sencillo.
• También nos han indicado la importancia que tiene que este proceso no
falle. Evidentemente el departamento de contabilidad no sabe que lo que
está pidiendo es que el proceso se realice en "alta disponibilidad". Es
decir, necesitamos que el proceso se ejecute en dos máquinas distintas.
• Del apartado 3. Intuimos un problema. ¿Podemos notificar dos veces a la
central la misma información? La respuesta es no. Es necesario, que de
alguna manera los procesos se sincronicen. Evidentemente, podríamos
usar la base de datos como punto de sincronización y mediante algún
algoritmo más o menos complejo lo conseguiríamos, pero ¿no existe
alguna manera más sencilla?. Ahí es donde entra la alta disponibilidad de
JBoss. Realmente lo que nosotros necesitamos es que nuestra tarea
planificada se despliegue en ambos servidores de aplicaciones, pero sólo
uno de ellos debe estar activo, es decir en modo activo-pasivo, o mejor
dicho "maestro-esclavo", lo que JBoss denomina HA-Singleton.
Empezaremos creando un interfaz que llamaremos INotificadorCentral:
64
package com.linuxcenter.jboss;
public interface INotificadorCentral {
public boolean diaNotificado();
public boolean isPeriodoNotificacion();
public void notificayGuarda();
}
Crearemos ahora la clase NotificadorCentral:
package com.linuxcenter.jboss;
import java.util.Date;
import org.jboss.varia.scheduler.Schedulable;
public class NotificadorCentral implements INotificadorCentral, Schedulable {
public boolean diaNotificado() {
System.out.println("COMPRUEBO SI EL DÍA YA HA SIDO NOTIFICADO");
return false;
}
public boolean isPeriodoNotificacion() {
System.out.println("COMPRUEBO SI ESTOY EN PERIODO DE NOTIFICACION");
return true;
}
public void notificayGuarda() {
System.out.println("RECOJO INFORMACIÓN DE BASE DE DATOS.");
System.out.println("NOTIFICO A LA CENTRAL.");
System.out.println("GUARDO EN BASE DE DATOS.");
}
public void perform(Date arg0, long arg1) {
if(diaNotificado()) {
return;
}
if(!isPeriodoNotificacion()) {
return;
}
65
notificayGuarda();
}
}
Crearemos a continuación el descriptor del servicio: (jboss-service.xml)
<?xml version="1.0" encoding="UTF8"?>
<server>
<mbean code="org.jboss.varia.scheduler.Scheduler" name="notificador:service=Scheduler">
<attribute name="StartAtStartup">true</attribute>
<attribute name="SchedulableClass">com.linuxcenter.jboss.NotificadorCentral</attribute>
<attribute name="InitialStartDate">NOW</attribute>
<attribute name="SchedulePeriod">15000</attribute>
<attribute name="InitialRepetitions">1</attribute>
</mbean>
</server>
Finalmente, debemos compilar las clases y generar el archivo SAR para la
ocasión.
Este fichero, lo vamos a desplegar en la carpeta server/all/farm al igual
que una aplicación común y corriente.
Como los servidores están trabajando en modo cluster, veremos en
ambas consolas la siguiente salida:
INFO [STDOUT] COMPRUEBO SI EL DIA YA HA SIDO NOTIFICADO
INFO [STDOUT] COMPRUEDO SI ESTOY EN PERIODO DE NOTIFICACION
INFO [STDOUT] RECOJO INFORMACION DE BASE DE DATOS
INFO [STDOUT] NOTIFICO A LA CENTRAL
INFO [STDOUT] GUARDO EN BASE DE DATOS
Para preparar el cluster de alta disponibilidad, debemos considerar el
siguiente diagrama:
66
Como se puede observar, al fallar el nodo maestro, se traspasa la
responsabilidad a uno de los nodos esclavos. Y los otros nodos esclavos siguen
estando como tal. JBoss denomina esta configuración como HA Singleton.
Para configurar a los nodos de este modo, debemos entonces modificar el
archivo server/all/deploy/cluster-service.xml.
Comentamos el apartado de conexión UDP del siguiente modo:
67
<!
<Config>
<UDP mcast_addr="${jboss.partition.udpGroup:228.1.2.3}"
mcast_port="${jboss.hapartition.mcast_port:45566}"
tos="8"
ucast_recv_buf_size="20000000"
ucast_send_buf_size="640000"
mcast_recv_buf_size="25000000"
mcast_send_buf_size="640000"
loopback="false"
discard_incompatible_packets="true"
enable_bundling="false"
max_bundle_size="64000"
max_bundle_timeout="30"
use_incoming_packet_handler="true"
use_outgoing_packet_handler="false"
ip_ttl="${jgroups.udp.ip_ttl:2}"
down_thread="false" up_thread="false"/>
<PING timeout="2000"
down_thread="false" up_thread="false" num_initial_members="3"/>
<MERGE2 max_interval="100000"
down_thread="false" up_thread="false" min_interval="20000"/>
<FD_SOCK down_thread="false" up_thread="false"/>
<FD timeout="10000" max_tries="5" down_thread="false" up_thread="false" shun="true"/>
<VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
<pbcast.NAKACK max_xmit_size="60000"
use_mcast_xmit="false" gc_lag="0"
retransmit_timeout="300,600,1200,2400,4800"
down_thread="false" up_thread="false"
discard_delivered_msgs="true"/>
<UNICAST timeout="300,600,1200,2400,3600"
down_thread="false" up_thread="false"/>
<pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
down_thread="false" up_thread="false"
max_bytes="400000"/>
<pbcast.GMS print_local_addr="true" join_timeout="3000"
down_thread="false" up_thread="false"
join_retry_timeout="2000" shun="true"
view_bundling="true"/>
<FRAG2 frag_size="60000" down_thread="false" up_thread="false"/>
<pbcast.STATE_TRANSFER down_thread="false" up_thread="false" use_flush="false"/>
</Config>
>
Suponiendo que los nodos tienen direcciones IP 192.168.1.2 y
192.168.1.3. En el primer nodo, cambiamos la configuración descomentando
el apartado TCP y lo dejamos de la siguiente forma:
<Config>
<TCP bind_addr="192.168.1.2" start_port="7800" loopback="true"
tcp_nodelay="true"
recv_buf_size="20000000"
send_buf_size="640000"
discard_incompatible_packets="true"
enable_bundling="false"
max_bundle_size="64000"
max_bundle_timeout="30"
use_incoming_packet_handler="true"
use_outgoing_packet_handler="false"
down_thread="false" up_thread="false"
use_send_queues="false"
sock_conn_timeout="300"
skip_suspected_members="true"/>
<TCPPING initial_hosts="192.168.1.2[7800],192.168.1.3[7800]" port_range="3"
timeout="3000"
down_thread="false" up_thread="false"
num_initial_members="3"/>
<MERGE2 max_interval="100000"
down_thread="false" up_thread="false" min_interval="20000"/>
<FD_SOCK down_thread="false" up_thread="false"/>
<FD timeout="10000" max_tries="5" down_thread="false" up_thread="false" shun="true"/>
<VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
<pbcast.NAKACK max_xmit_size="60000"
68
use_mcast_xmit="false" gc_lag="0"
retransmit_timeout="300,600,1200,2400,4800"
down_thread="false" up_thread="false"
discard_delivered_msgs="true"/>
<pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
down_thread="false" up_thread="false"
max_bytes="400000"/>
<pbcast.GMS print_local_addr="true" join_timeout="3000"
down_thread="false" up_thread="false"
join_retry_timeout="2000" shun="true"
view_bundling="true"/>
<pbcast.STATE_TRANSFER down_thread="false" up_thread="false" use_flush="false"/>
</Config>
Para el segundo nodo, se hacen las mismas modificaciones, pero
colocando la dirección IP correspondiente en los puntos marcados en negrita.
Al arrancar ambos servidores, vemos que en el primer nodo se produce la
secuencia de mensajes:
INFO [STDOUT] COMPRUEBO SI EL DIA YA HA SIDO NOTIFICADO
INFO [STDOUT] COMPRUEDO SI ESTOY EN PERIODO DE NOTIFICACION
INFO [STDOUT] RECOJO INFORMACION DE BASE DE DATOS
INFO [STDOUT] NOTIFICO A LA CENTRAL
INFO [STDOUT] GUARDO EN BASE DE DATOS
Mientras que el segundo nodo sigue quieto.
Al parar el primer nodo, apreciamos como en el segundo nodo se toma el
control de la aplicación a los pocos segundos de caído el primer servidor.
INFO [STDOUT] COMPRUEBO SI EL DIA YA HA SIDO NOTIFICADO
INFO [STDOUT] COMPRUEDO SI ESTOY EN PERIODO DE NOTIFICACION
INFO [STDOUT] RECOJO INFORMACION DE BASE DE DATOS
INFO [STDOUT] NOTIFICO A LA CENTRAL
INFO [STDOUT] GUARDO EN BASE DE DATOS
69
Capítulo VII: Optimización de JBoss.
Para optimizar el entorno JBoss, debemos preocuparnos de los siguientes
puntos:
Optimizar el front-end
Peticiones HTTP.
Compilación de JSP
Optimizar el back-end
Conexiones a la base de datos.
Optimizar los recursos de memoria.
Recolectores de basura.
La performance de una aplicación JBoss es altamente dependiente del
entorno donde se está ejecutando. Este entorno incluye tanto el hardware
como el software. Cada uno de esos componentes tienen un efecto en la
performance de dicha aplicación.
El árbol de jerarquía entonces es el siguiente:
- Hardware (CPU, RAM, Discos, etc)
- Sistema Operativo
- Java Virtual Machine
- Servidor JBoss
- Aplicación
Elección de la JVM.
La elección de la Java Virtual Machine, como se puede observar en el
árbol, incide directamente en el comportamiento del servidor y de la
aplicación.
Existen muchas alternativas de JVM, pero lo que debemos considerar es
lo siguiente:
El uso de una máquina con procesador de 64 bits y una JVM para esta
arquitectura permite utilizar grandes tamaños de heaps.
El uso de varios procesadores (dos o más) y el uso de varios
70
recolectores de basura (y en paralelo) permiten una alta performance y un
rápido proceso de recoleción. Sin embargo, lo que realmente debemos
entender es el proceso de recoleción. Para eso, se recomiendo la actualización
al menos de la JDK versión 5, la cual ya viene con auto ajuste.
De todos modos, cada JVM incluye opciones que pueden afectar a la
performance. Las mas relevantes son las siguientes:
• Tamaño del heap.
• Recoleción de basura.
• Hilado (Threading)
JVM Heap
El tamaño del head se traduce como la cantidad de memoria que el JVM
utilizará para trabajar.
Un servidor JBoss y una aplicación crea instancias de clases java que son
alojadas en esta memoria. Por defecto, JBoss se ejecuta con un heap inicial de
64MB. Para modificar el tamaño del heap, debemos modificar el archivo run.s
con la siguiente opción:
Set JAVA_OPTS = %JAVA_OPTS% xms128m xmx512m
Optimización de Tomcat.
JBoss utiliza tomcat como contenedor de servlets, por lo que debemos
modificar el archivo ubicado en /server/<modo>/deploy /jboss-
web.deployer/server.xml
En este fichero, buscaremos la siguiente línea:
<Connector port="8080"
address="${jboss.bind.address}"
maxThreads="150"
minSpareThreads="25"
maxSpareThreads="75"
enableLookups="false"
redirectPort="8443"
acceptCount="100"
connectionTimeout="20000"
disableUploadTimeout="true"/>
Donde entonces debemos tener las siguientes consideraciones:
El valor minSpareThreads debe ser un poco menor a la carga normal.
71
El valor maxSpareThreads debe ser un poco mayor al peak de carga.
Esto se deduce, debido a que minSpareThreads significa "al partir,
siempre mantiene esta cantidad de hilos esperando”. maxSpareThreads
significa "si siempre se mantiene sobre minSpareThreads, entonces conserva
esta cantidad de hilos esperando”.
Eliminar directorios de trabajo.
Tomcat generalmente no elimina los directorios de trabajo cuando las
aplicaciones son undeployed. Esto causa problemas en la compilación de JSP
sobre todo cuando se re-despliega una aplicación. Podemos usar el atributo
DeleteWorkDirs para que se elimine el directorio durante el undeployment.
<mbean
code="org.jboss.web.tomcat.tc5.Tomcat5"
name="jboss.web:service=WebServer">
attribute name=”DeleteWorkDirs”> true</attribute>
...
</mbean>
Comportamiento de la carga de clases.
Tomcat normalmente usa el cargador de clases padre para cargar las
clases antes del correspondiente al WAR. Esto es un estándar de Java2
classloading behavior. Sin embargo, desde la especificación de servlet 2.3
se requiere que primero se ejecute el cargador del WAR buscando dentro de
/WEB-INF/classes y /WEB- INF/lib.
<mbean code="org.jboss.web.tomcat.tc5.Tomcat5"
name="jboss.web:service=WebServer">
<attribute name=”Java2ClassLoadingCompliance”> true</attribute>
...
</mbean>
Optimización de JSP.
El compilador de páginas JSP se encuentra en modo development por
defecto.
Para aumentar la performance, se pueden realizar las siguientes
operaciones:
• Reducir el tamaño de log.
• Eliminar la revisión de is-modified en cada petición.
• Precompilar las páginas JSP.
72
Optimización de Log4J
El registro del sistema es uno de los aspectos principales de una
aplicación de nivel empresarial. JBoss usa Log4J como interfaz de registro del
sistema.
El mbean de registro.
JBoss provee de un mbean que puede ser utilizado para configurar las
opciones del registro.
Este mbean generalmente está definido en el siguiente archivo:
/conf/jboss-service.xml.
<mbean code=“org.jboss.logging.Log4jService”
name=“jboss.system:type=Log4jService.service=Logging”>
<attribute name=“ConfigurationURL”>resource:log4j.xml</attribute>
<attribute name=“Log4jQuietMode”>true</attribute>
</mbean>
Esto cargará la configuración desde el archivo /conf/log4j.xml
Existen 3 componentes que debemos observar en esta configuración:
- Loggers : Que registrar.
- Appenders : Donde registrar.
- Layouts : Formato del registro.
El proceso de registro tiene grandes efectos en la performance de un
servidor. Por lo cual, podemos realizar lo siguiente:
Deshabilitar el registro por consola
Editamos el archivo server/<tipo>/conf/log4j.config , cambiando el
siguiente codigo XML:
<root>
<appenderref ref=CONSOLE"/>
<appenderref ref="FILE"/>
</root>
por
<root>
<appenderref ref="FILE"/>
</root>
73
Cambiar el nivel de registro.
Editamos el archivo server/<tipo>/conf/log4j.config , cambiando los
siguientes fragmentos:
<category name="org.apache">
<priority value="INFO"/>
</category>
<category name="org.jgroups">
<priority value="INFO"/>
</category>
Los valores de prioridad son los siguienes:
• ERROR: mensajes de error.
• WARN: mensajes de advertencia.
• INFO: mensajes de estado.
• DEBUG: mensajes de depuración.
• TRACE: mensajes de depuración mas explícito.
74