Tuesday, November 01, 2011

El desafío - Implantar una plataforma SOA Open Source

Bien, pues con todo lo que he ido aprendiendo, leyendo y experimentando durante este tiempo ahora llega el momento de la verdad.
En la empresa donde estoy trabajando, desde que llegué, he intentado cambiar la metodología y la forma de trabajar. Hemos pasado del "vamos a apagar este fuego como sea para que funcione" que me encontré al "todo lo que hagamos tiene que ser reutilizable e independiente" (vamos, un componente).

Actualmente lo que tenemos es una plataforma grotesca que ha ido creciendo durante 3 o 4 años. Técnicamente tiene cosas interesantes, pero es muy dificil de evolucionar ya que el core no es opensource ni disponemos de los fuentes y todo lo que se va desarrollando se hace sobre este core con sus limitaciones y sus desventajas.

A lo que vamos es a rediseñar todo el modelo actual de la empresa, con los cambios y evoluciones que ha sufrido. Empezar a definir servicios según las necesidades que van surgiendo. Estos servicios de momento se van a servir de los datos con los que trabaja la actual plataforma. Es decir, la implementación de los DAOs van a obtener los datos con el core actual para poder migrar cuando sea posible con el mínimo impacto.

Lo primero que pretendo implantar será, como he dicho, unos servicios imprescindibles que permitan obtener ciertos datos que mostrar en un portal web de acceso a terceros, con lo que la interacción con los clientes se incrementa y dejamos de tener el cutre-portal-web para poder ofrecer contenidos dinámicos. Para esto utilizaremos Liferay, el contenedor de Portlets, y para diseñar los servicios Web voy a probar Apache Tuscany (http://tuscany.apache.org/).

Ya iré contando qué tal va evolucionando y qué otras soluciones OpenSource voy añadiendo, aunque en mi mente ya están jBPM para los procesos de negocio, Apache Synapse como ESB ligero y EsperTech para los eventos. Aunque también incorporaré otras en su versión Community como pueden ser Alfresco para la gestión documental y Liferay que ya he comentado.

Thursday, July 21, 2011

Acceso JMX remoto con JConsole a Tomcat

JConsole permite monitorizar en tiempo real el estado de la JVM que necesitemos y ejecutar operaciones JMX remotamente, incluso forzar GCs (Garbage Collections). Podemos acceder a nuestros procesos locales que estén ejecutando la JDK o procesos remotos que tengan habilitado el acceso remoto por JMX.

En mi caso he necesitado monitorizar un applet local y un Tomcat 6 situado en otra máquina.

JConsole es un programa que está situado en el bin de la JDK, basta con ejecutarlo para que aparezca un menú donde se elige el proceso local que está corriendo o el remoto.

Para conectarnos por JMX remotamente habrá que habilitar el servicio en la máquina virtual remota. Esto se hace incluyendo los siguientes atributos en el inicio de la JVM:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=%my.jmx.port%
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

Esta es la forma fácil e insegura, ya que estoy deshabilitando la autenticación, pero para habilitarla a partir de ficheros de configuración sería algo así:
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=jmxremote.password
-Dcom.sun.management.jmxremote.access.file=jmxremote.access

Fichero de acceso:
# The "monitorRole" role has password "QED".
# The "controlRole" role has password "R&D".
monitorRole QED
controlRole R&D

Fichero de passwords:
monitorRole tomcat
controlRole tomcat

Donde lo he probado ha sido en Windows XP, con la versión de Tomcat 6.0.20, instalada como servicio, por lo que he tenido que ejecutar tomcat6w.exe para editar, desde la pestaña Java las propiedades Java y añadir las que he comentado al principio.

Si queremos habilitar una conexión segura por SSL habría que configurar el keystore y el password, pero como no lo he probado dejo únicamente una referéncia:
http://download.oracle.com/javase/1.5.0/docs/guide/management/agent.html#remote

Aquí está la documentación para hacerlo en Tomcat 6
http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote

Saludos!

Friday, June 17, 2011

Mostrar los puertos escuchando relacionados con los procesos

Hoy me ha hecho falta saber qué proceso me estaba escuchando en el mismo puerto que me hacía falta y buscando he encontrado el cómo, por si a alguien le hace falta.
sudo netstat --tcp --udp --listening --program

rromero@madrid:~$ sudo netstat --tcp --udp --listening --program
Conexiones activas de Internet (solo servidores)
Proto Recib Enviad Dirección local Dirección remota Estado PID/Program name
tcp 0 0 localhost:64022 *:* ESCUCHAR 1445/novacomd
tcp 0 0 localhost:12311 *:* ESCUCHAR 1445/novacomd
tcp 0 0 localhost:ipp *:* ESCUCHAR 1173/cupsd
tcp 0 0 localhost:6968 *:* ESCUCHAR 1445/novacomd
tcp 0 0 localhost:6969 *:* ESCUCHAR 1445/novacomd
tcp 0 0 localhost:6970 *:* ESCUCHAR 1445/novacomd
tcp 0 0 localhost:6971 *:* ESCUCHAR 1445/novacomd
rromero@madrid:~$ ps -fea | grep novacomd
root 1445 1 5 16:59 ? 00:09:39 /opt/Palm/novacom/novacomd


Info extraída de aquí:
http://www.go2linux.org/which_service_or_program_is_listening_on_port

Thursday, May 19, 2011

Singletons en Java

Tras realizar un diseño de un servicio, me puse a definir las clases necesarias, con su esqueleto básico con lo que varias requerían ser Singletons, por lo que utilicé la implementación típica sacada de los libros de ingeniería de software.

public class DefaultSingleton {
private static DefaultSingleton instance = null;

private DefaultSingleton(){}

public synchronized DefaultSingleton getInstance() {
if(instance == null) {
instance = new DefaultSingleton();
}
return instance;
}

En teoría esto permite la inicialización única para accesos concurrentes ya que el getInstance() es sincronizado, pero cualquier objeto que necesite obtener la instancia deberá pasar por la sincronización, lo que puede no ser necesario y si no me equivoco también dará problemas de concurrencia.

Para intentar evitar esta situación, se ha confiado durante mucho tiempo en el doble chequeo de la sincronización (Double-Checked Locking), pero sin entrar en más detalle, decir que se ha demostrado que genera diversos errores en entornos altamente concurrentes, sin entrar en más detalles pongo un enlace.
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

A partir de aquí surgen dos alternativas, la inicialización impaciente (eager) o la perezosa (lazy). Los dos ejemplos anteriores son Lazy. La principal diferencia entre una y otra es cuándo se crea la instancia, si al iniciar la aplicación o al hacer el getInstance(). La elección de cada una dependerá de cada caso concreto, ya que si tienes pocos Singleton y requieren poco procesamiento, o simplemente te da igual lo que tarde en iniciarse la aplicación, optarás por la primera, si son muchos los Singleton que necesitas inicializar, algunos contienen un procesamiento complejo y/o lento, o simplemente prefieres que se vayan creando las instancias conforme vayan haciendo falta, por temas de recursos o lo que sea, tal vez prefieras la segunda opción. En mi caso me he decantado por la inicialización bajo demanda.

Ejemplo de inicialización impaciente.
public class EagerSingleton {
private static EagerSingleton instance = new EagerSingleton();

private EagerSingleton(){}

public EagerSingleton getInstance() {
return instance;
}

Se puede observar como evitamos el synchronized ya que es la JVM quien se encarga de inicializar la instancia. Al centralizar la inicialización en un único punto (la JVM) previenes cualquier inicialización concurrente.

Ejemplo de inicialización perezosa (o bajo demanda).
public class LazySingleton {
private static class InstanceHolder {
public static LazySingleton instance = new LazySingleton ();
}

private LazySingleton (){}

public LazySingleton getInstance() {
return InstanceHolder.instance;
}
Aquí no se instanciará la variable instance hasta que algún objeto haga el getInstance() de tal forma que igual que en el caso anterior, será la JVM quien creará la instancia cuando deba ser ejecutado.

Espero que este resumen rápido sirva para tener claro cómo utilizar un Singleton en Java.

Aquí dejo un par de fuentes
http://embarcaderos.net/2009/06/23/the-singleton-pattern-in-java-multi-threaded-applications/
http://www.rockstarprogrammer.org/post/2006/oct/19/java-singletons-without-locks/