Bueno, cambié el nombre del blog y la url, los anteriores me gustaban tan poco que no voy a decir cuales eran.
Ahora es mi nombre y simplemente refleja que en este blog hay artículos sobre temas de los que me interesan. Por otro lado, el blog solía ser un tanto anónimo, capaz que por eso lo tenía descuidado, de repente de esta forma me comprometo más con el mismo.
En este blog escribo artículos sobre temas que me interesan, en particualar temas técnicos del área de informática.
martes, 14 de septiembre de 2010
viernes, 22 de enero de 2010
Comprimiendo el acceso a base de datos

Problema
Con aplicaciones win, a menudo ocurre que tenemos el servidor de base de datos en otro lugar fisico, conectado a traves de VPN o similar. Para este tipo de aplicaciones en Genexus se incorporó la posibilidad de generar en 3 capas, donde hay un servidor de aplicaciones que hace el trabajo pesado contra la base de datos y al cliente solo llegan los datos que se muestran al usuario (al menos en teoría).
Cuando se tiene una aplicacion 2 capas, pasar a 3 capas puede implicar muchos dolores de cabeza, principalmente por procesos que no se pueden ejecutar en el servidor porque interactuan con el usuario, ademas de pantallas que se quedan bloqueadas y otros problemas.
En más de un cliente fue necesario instalar aplicaciones Java 2 capas que se conectaban a un servidor en VPN, pero fue hace muy poco que me puse a investigar el volumen de datos que pasaba por la VPN para ver si habia forma de optimizar la performance. Ahí encontré que hay volúmenes grandes, por ejemplo reportes que trasmiten más de 1MB de datos o transacciones que dada la cantidad de consultas que hacen a la base de datos generan mucho tráfico.
Solución
Dado que Genexus es quien genera los programas, a simple vista parece que no hay mucho que podamos hacer para optimizar el tráfico en una aplicación win 2 capas, pero dimos con una solución sencilla y con un costo de implementación muy bajo, grandes beneficios y estable. Se trata de entunelar y comprimir la conexión entre la aplicación y la base de datos.
Del lado del cliente se precisa un programa que pueda escuchar una conexión TCP/IP común, comprimirla y trasmitirla a un servidor de compresión/descompresión, el primero a su vez se encarga de descomprimir la respuesta del servidor. En la otra punta de la conexión lenta (VPN) está el servidor de descompresión que hace las operaciones análogas, descomprimir las conexiones entrantes para mandarlas limpias al DBMS y comprimir la respuesta del DBMS para que vuelva al cliente.
Las 2 partes de la solución (servidor y cliente) fueron implementadas en Java, que gracias a su excelente manejo de streams y threads obtuvo una implementación muy sencilla, estable y de buen rendiminto. El algoritmo de compresión fue zlib que es parte de la api de Java, lo cual también ayudo a no agregar dependencias.
Cliente
El cliente está embebido en la aplicación y levanta automáticamente al poner el parámetro compression=true en la url de conexión. Simplemente parsea la url buscando el parámetro y si lo encuentra levanta una instancia del cliente en la PC cliente y cambia la url de conexión para que se conecte a esta instancia en vez de conectarse al servidor real.
Servidor
Se instala en el servidor de DBMS o en otro servidor que esté en la misma LAN. Para que esté siempre disponible se instaló como servicio de Windows utilizando JSL (altamente recomendable). El único requerimiento es tener una JVM instalada.
Resultados
Los resultados fueron muy buenos, en términos generales puede decirse que se bajaron a la tercera parte los tiempos de respuesta y como ya se anticipó, con una solución muy estable y con un costo bajo. Hay que tener en cuenta que en todos los clientes la velocidad no superaba los 256kbps es de suponer que a medida que se mejora la velocidad los beneficios disminuyen.
También hay que notar que estos algoritmos agregan procesamiento, especialmente al servidor que escucha las peticiones de todos los clientes. En nuestro caso no era un problema, en una parte porque los clientes no son muchos y en otra parte porque los servidores tienen buena capacidad de procesamiento.
Links de interés
IPTunnelManager - Una herramienta paga que permite hacer túneles comprimidos y encriptados, instalando uno en cada punta de la conexión lenta se podrían comprimir las conexiones al DBMS.
miércoles, 13 de mayo de 2009
Memory leaks en Java
Hace poco tuve un inconveniente desarrollando una aplicación web con Genexus/Java, la memoria que consumía el tomcat crecía hasta que daba un error java.lang.OutOfMemoryError: Java heap space.
El problema se daba durante la ejecución de un proceso batch muy largo y era claro que una vez que terminaba no liberaba la memoria que había utilizado, entonces ¿Como identificar que es lo que está quedando colgado?
Lo primero que usé fue JConsole, que una vez habilité JMX en el tomcat, me permitió ver el consumo de memoria global, como crecía y decrecía, pero seguía sin ver que objetos eran los que estaban quedando colgados.
Busqué varios profilers para Java y encontré que principalmente apuntan a mostrar los tiempos de ejecución de las operaciones, así que en este caso no me servían y me di cuenta que tenía que buscar alguna herramienta para analizar la memoria. Estoy seguro de que existen muchas y hay mejores soluciones que la que utilicé, pero lo que encontré sirvió a mis propósitos y tiene la ventaja y contra de no tener que estar analizando los datos en tiempo real.
Solución: JConsole + jhat (Java Heap Analysis Tool), ambas son herramientas que vienen con el JDK de SUN, simplemente hay que buscarlos en la carpeta bin.
jhat es un programa que dado un "memory dump" levanta un servidor web que permite navegar la memoria en dicho dump, además de presentar útiles histogramas de instancias y cantidad de memoria por clase. Pero hay que tener en cuenta que para un dump grande 100MB+ hay que pasarle parámetros para agrandar el heap del propio jhat, sino se queda sin memoria y hay que sentarse a esperar porque se toma su tiempo para procesar los datos.
Entonces los pasos a seguir son:
Ahora llegamos al punto en el que identificamos cuales son los objetos que están ocupando más memoria, al hacer click en la clase que nos interesa analizar, podemos ver algunos datos interesantes de la misma y debajo una lista de todas las instancias de dicha clase, así que elegimos una instancia cualquiera y podemos empezar a navegar a través de sus referencias, para encontrar el objeto raíz que está dejando las instancias colgadas.
Una vez identificado el objeto, estamos listos para corregir el error, o como en mi caso quejarnos a soporte y tratar de encontrar un workaround!
El problema se daba durante la ejecución de un proceso batch muy largo y era claro que una vez que terminaba no liberaba la memoria que había utilizado, entonces ¿Como identificar que es lo que está quedando colgado?
Lo primero que usé fue JConsole, que una vez habilité JMX en el tomcat, me permitió ver el consumo de memoria global, como crecía y decrecía, pero seguía sin ver que objetos eran los que estaban quedando colgados.
Busqué varios profilers para Java y encontré que principalmente apuntan a mostrar los tiempos de ejecución de las operaciones, así que en este caso no me servían y me di cuenta que tenía que buscar alguna herramienta para analizar la memoria. Estoy seguro de que existen muchas y hay mejores soluciones que la que utilicé, pero lo que encontré sirvió a mis propósitos y tiene la ventaja y contra de no tener que estar analizando los datos en tiempo real.
Solución: JConsole + jhat (Java Heap Analysis Tool), ambas son herramientas que vienen con el JDK de SUN, simplemente hay que buscarlos en la carpeta bin.
jhat es un programa que dado un "memory dump" levanta un servidor web que permite navegar la memoria en dicho dump, además de presentar útiles histogramas de instancias y cantidad de memoria por clase. Pero hay que tener en cuenta que para un dump grande 100MB+ hay que pasarle parámetros para agrandar el heap del propio jhat, sino se queda sin memoria y hay que sentarse a esperar porque se toma su tiempo para procesar los datos.
Entonces los pasos a seguir son:
- Habilitar JMX en el Tomcat, agregar a la configuración los siguientes parámetros:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=”9004″
-Dcom.sun.management.jmxremote.authenticate=”false”
-Dcom.sun.management.jmxremote.ssl=”false” - Ejecutar los procesos que se sabe que dejan memoria colgada o usar la aplicación hasta que la memoria crezca considerablemente.
- Iniciar JConsole y conectarse al servidor en el puerto 9004.
- En el tab MBeans ejecutar com.sun.management.HotSoptDiagnostic.dump usando como parámetro "C:\dump.bin" (o la ruta que venga bien).
- Ejecutar jhat pasando como parámetro el archivo a procesar, opcionalmente se le puede agrandar la memoria de heap porque con archivos grandes puede caer.
jhat -J-Xmx400m dump.bin - Entrar a la url http://localhost:7000/ donde debería aparecer la página de bienvenida de jhat, con un resumen de las clases que hay en memoria y al final unos links a consultas preparadas. La que me resultó más útil es el histograma.
Ahora llegamos al punto en el que identificamos cuales son los objetos que están ocupando más memoria, al hacer click en la clase que nos interesa analizar, podemos ver algunos datos interesantes de la misma y debajo una lista de todas las instancias de dicha clase, así que elegimos una instancia cualquiera y podemos empezar a navegar a través de sus referencias, para encontrar el objeto raíz que está dejando las instancias colgadas.
Una vez identificado el objeto, estamos listos para corregir el error, o como en mi caso quejarnos a soporte y tratar de encontrar un workaround!
jueves, 11 de diciembre de 2008
Streaming en Genexus
Bueno, en serio, prometo escribir más seguido. Hace unos meses un colega me dijo que tenía que empezar a escribir, que es sencillo, todos los días uno siempre resuelve algún problema y bueno escribir sobre eso.
Ahora escribo sobre algo que me pareció importante hace unos meses, no se si el término Streaming aplica totalmente, pero pienso que se acerca bastante.
Cuando usamos Genexus para realizar reportes en web, lo más común es realizar los reportes en PDF, ya que de está forma el usuario puede verlo y después decidir que hacer con él, guardarlo, imprimirlo o descartarlo.
Ahora, las aplicaciones que hacemos no son de juguete, son de negocio y a veces tenemos reportes de algunos cientos de páginas.
Por suerte Genexus nos ofrece la opción de generar los reportes directo por el protocolo HTTP y uno piensa, ¡que suerte! no tengo que guardar un archivo grandecito en el servidor, para que después el usuario lo baje, lo cual generaría un overhead bastante grande en el servidor.
Lamentablemente, si vien Genexus nos ofrece la opción de generar los reportes por HTTP, no hace streamming. ¿Que quiero decir con esto? Bueno, Genexus calcula todo el reporte en memoria y luego lo devuelve de un saque, lo cual puede ser aún peor para la escalabilidad del servidor. ¡Por favor corriganmé si me equivoco, pero busqué por todos lados y aparentemente este siempre es el comportamiento!
Lamentablemente esto no se limita sólo a los reportes PDF, supongamos que queremos exponer un procedimiento que devuelve un XML "gigante" para hacer interfaz con otro sistema. Bueno lógicamente empezamos por abrir un stream XML en el Response HTTP y luego vamos escribiendo ese XML, en este caso sería muy lógico que el XML se fuera mandando al cliente a medida que se va generando, pero nuevamente Genexus genera todo el XML en memoria y luego lo devuelve.
De repente lo ideal no es que el comportamiento siempre sea hacer streaming, ya que una de las principales virtudes de Genexus es ocultar tecnicismos al programador. Y por ejemplo cuando se trabaja con streaming hay que tener cuidado de escribir los cabezales antes de empezar a hacer el streaming. Pero si estaría bueno tener una opción de streaming (debidamente documentada con esos tecnicismos).
Ahora escribo sobre algo que me pareció importante hace unos meses, no se si el término Streaming aplica totalmente, pero pienso que se acerca bastante.
Cuando usamos Genexus para realizar reportes en web, lo más común es realizar los reportes en PDF, ya que de está forma el usuario puede verlo y después decidir que hacer con él, guardarlo, imprimirlo o descartarlo.
Ahora, las aplicaciones que hacemos no son de juguete, son de negocio y a veces tenemos reportes de algunos cientos de páginas.
Por suerte Genexus nos ofrece la opción de generar los reportes directo por el protocolo HTTP y uno piensa, ¡que suerte! no tengo que guardar un archivo grandecito en el servidor, para que después el usuario lo baje, lo cual generaría un overhead bastante grande en el servidor.
Lamentablemente, si vien Genexus nos ofrece la opción de generar los reportes por HTTP, no hace streamming. ¿Que quiero decir con esto? Bueno, Genexus calcula todo el reporte en memoria y luego lo devuelve de un saque, lo cual puede ser aún peor para la escalabilidad del servidor. ¡Por favor corriganmé si me equivoco, pero busqué por todos lados y aparentemente este siempre es el comportamiento!
Lamentablemente esto no se limita sólo a los reportes PDF, supongamos que queremos exponer un procedimiento que devuelve un XML "gigante" para hacer interfaz con otro sistema. Bueno lógicamente empezamos por abrir un stream XML en el Response HTTP y luego vamos escribiendo ese XML, en este caso sería muy lógico que el XML se fuera mandando al cliente a medida que se va generando, pero nuevamente Genexus genera todo el XML en memoria y luego lo devuelve.
De repente lo ideal no es que el comportamiento siempre sea hacer streaming, ya que una de las principales virtudes de Genexus es ocultar tecnicismos al programador. Y por ejemplo cuando se trabaja con streaming hay que tener cuidado de escribir los cabezales antes de empezar a hacer el streaming. Pero si estaría bueno tener una opción de streaming (debidamente documentada con esos tecnicismos).
sábado, 1 de marzo de 2008
Nuevo Celular
Bueno, pasó un año, ya era hora de agregar algo más.
Hace una semana firmé con ancel, un contrato con el cual me regalaron un LG KU250, es un celular 3G barato, en realidad el más barato del mercado y ganador del concurso 3G for all.
En realidad los planes de datos 3G todavía son muy caros, así que por ahora solo lo voy a usar como un celular GSM común y corriente, excepto que hasta hoy me dejaban hacer videollamadas gratis.
Otra funcionalidad que me gusta, es que soporta bluetooth, lo malo es que me costó mucho encontrar la aplicación para sincronizar con la PC (el sitio de LG deja mucho que desear), así que aprovecho a pasarles un link por si a alguien le hace falta: http://www.smart.com.ph/Buddy/promos/LG_KU250.htm
Por ahora la peor contra es la duración de batería, a los que conozco que tienen el mismo celular les ha pasado que les dura muy poco. Pero todos lo tienen hace poco tiempo, capaz que se debe simplemente al uso intensivo o a que son las primeras cargas.
Bueno esto es todo amigos, capaz que les escribo más seguido.

Hace una semana firmé con ancel, un contrato con el cual me regalaron un LG KU250, es un celular 3G barato, en realidad el más barato del mercado y ganador del concurso 3G for all.
En realidad los planes de datos 3G todavía son muy caros, así que por ahora solo lo voy a usar como un celular GSM común y corriente, excepto que hasta hoy me dejaban hacer videollamadas gratis.
Otra funcionalidad que me gusta, es que soporta bluetooth, lo malo es que me costó mucho encontrar la aplicación para sincronizar con la PC (el sitio de LG deja mucho que desear), así que aprovecho a pasarles un link por si a alguien le hace falta: http://www.smart.com.ph/Buddy/promos/LG_KU250.htm
Por ahora la peor contra es la duración de batería, a los que conozco que tienen el mismo celular les ha pasado que les dura muy poco. Pero todos lo tienen hace poco tiempo, capaz que se debe simplemente al uso intensivo o a que son las primeras cargas.
Bueno esto es todo amigos, capaz que les escribo más seguido.
viernes, 2 de febrero de 2007
Hoy arranco
Este es mi primer blog, y lo hice solo por curiosidad. Así que hoy digo "Hoy arranco", pero mañana capaz que lo dejo. El tiempo dirá.
Suscribirse a:
Entradas (Atom)