SafeChildren Banner

Havoc Oracle Solaris Experts

jueves, 24 de diciembre de 2009

Diferencias entre LDOM, Dynamic System Domains y Solaris Zones

Introducción
En la actualidad el tema de la virtualización está más de moda que nunca, sin embargo, cuando hablamos de las diferentes tecnologías que Sun Microsystems nos aporta tenemos algunos problemas para ver las diferencias. Por ello, he creado este post con la intención de mostrar todos los tipos de virtualización que nos ofrecen y las principales diferencias entre ellos.

Tipos de Virtualización
Antes de comenzar con el post sobre las diferentes soluciones, vamos a definir qué tipos de virtualización o particionamiento disponemos. Yo las he clasificado en tres tipos:
  • Electrical. Particionamiento a nivel más bajo de máquina que se produce por una división eléctrica de los componente de forma que son completamente independientes
  • Firmware. Particionamiento a nivel de firmware que produce una separación lógica dentro del controlador del sistema (sin entrar en el Sistema Operativo)
  • Software. Particionamiento o Virtualización de los recursos del sistema mediante la separación lógica por software dedicado
Partición Eléctrica, Dynamic System Domains
Este tipo de particionamiento está incluido en la gama alta de Sun y también es conocido como Dominios <en el argot castellano>. Cada servidor está compuesto de una o varias Physical System Board  (PSB) y cada una de estas PSB puede estar lógicamente dividida en 1 unidad (no dividida) o lógicamente dividida en cuatro unidades. Si no está dividida, entonces se hace referencia como Uni-XSB; si está lógicamente dividida en cuatro, se hace referencia como Quad-XSB. Cada una de las divisiones lógicas se llama Extended System Board (XSB).

Un dominio puede estar compuesto con cualquier combinación de XSB disponibles en el sistema. Debemos tener en cuenta, que esta definición de partición lógica por PSB se aplica a high-level (M8000/M9000) en entry-level(M3000/M4000) una PSB siempre es Uni-XSB, en definitiva, una XSB debe ser CPU+RAM+IO.

Vamos a ver si podemos explicar este detalle con mayor claridad. Si tenemos una M4000 con dos SysB cada una de ellas con 2 CPU UltraSPARC VII QuadCore y 32Gb cada una (un total de 64Gb), como hemos explicado antes, es necesario tener CPU+RAM+IO y no es divisible, así que en el caso de la M4000 al contar con 2SysB es como si la máquina estuviese partida en dos partes simétricas y por lo tanto, eléctricamente divisibles, así que esta máquina soporta hasta 2 dominios siendo las configuraciones posibles las siguientes:
  • Un único dominio
1[2]SysB+32[64]GB RAM+IO (Dominio1)
  • Dos dominios
1SysB + 32GB RAM + IO (Dominio1)
1SysB + 32GB RAM + IO (Dominio2)
Si por el contrario sólo disponemos de una única SysB, únicamente podemos hacer un dominio, además las configuraciones mezcladas no están soportadas, por ejemplo, dominioA 3CPU+(32+16GB RAM), dominioB 1CPU + 16GB RAM, ya que la división tiene que ser "lineal"



 Así mismo, cada máquina que soporta Dynamic System Domains tiene sus propias limitaciones y os recomiendo leer la documentación específica de cada una de ellas.

Este tipo de particionamiento nos proporciona redimensionado en caliente de los recursos de los dominios y, además, una separación completa de máquinas. En definitiva, hemos partido nuestro chasis en n máquinas completamente independientes, por lo tanto, con diferentes kernel, parches, etc.

Firmware, LDOMS Logical Domains
Un escalón por encima nos encontramos LDOMS <Logical Domains> que nos proporciona una virtualización a nivel de firmware y por lo tanto, en teoría muy estable. Este tipo de virtualización nos proporciona aislamiento e independencia de kernel ya que estamos exponiendo un boot enviroment diferente para cada uno de los dominios.

Este tipo de virtualización está compuesta de una parte a nivel de firmware y una instalación de Solaris especial llamada Domain Controller que será la encargada de gestionar los Logical Domains creados. Podemos comparar <aunque no es exactamente igual> este tipo de vitualización a la que se realiza con VMWare ESX ya que nuesto SPOF <Single Point Of Failure> se encuentra en esta instalación concreta de Solaris que hace de Controlador, puesto que si se produce un panic en él, los Logical Domains dejarán de ser operativos.

Dentro de esta arquitectura, nuestro hypervisor se encuentra a nivel de firmware, y nuestro control domain <primary> a nivel de Sistema Operativo, en definitiva, podemos decir que nuestro Control Domain es el encargado de gestionar los dominios y comunicarse con el firmware.

Existe diferentes tipos de Logical Domains, como ya hemos comentado siempre debe existir como mínimo el Domain Controller y a partir de aquí podemos tener los siguientes tipos:
  • Control Domain. Gestiona los Dominios y se comunica con el Firmware. Siempre debe existir uno.
  • Service Domain. Proporciona servicios al resto de los dominios, como por ejemplo, red virtual, discos virtuales, etc. Este tipo de dominios son los productores de servicios
  • IO Domain. Este tipo de dominio tiene acceso directo al IO, por ejemplo, PCI, NIC, etc. y puede compartir <exportar> el servicio si quiere
  • Guest Domain. Este tipo de dominio hace uso de los servicios proporcionados por los demás, es decir, es un consumidor y es gestionado por el Domain Controller
Este tipo de virtualización nos permite redimensionado en caliente, y diferentes versiones de kernel, parches, etc. El comportamiento del firmware proporciona un OpenBoot diferente para cada uno de los lógical domains y, teóricamente, es posible instalar "cualquier" Sistema Operativo con arquitectura SPARC.

Además, el soporte de LDOMS en la actualidad sólo está disponible para los procesadores UltraSPARC T1, T2 y T2+.

Software, Solaris Zones
Aunque es el método de virtualización probablemente más conocido de Sun, como ya hemos comentado antes no es el único. Las Zonas de Solaris nos permiten instanciar el Sistema Operativo con diferente configuración de: Hostname, ip, users, devices

De esta forma, tenemos un único kernel  compartido aunque aislado. Un panic en una zona "no tiene" por qué afectar a otra. Sin embargo, seguimos teniendo el mismo SPOF, en este caso, la instalación base del sistema.

Esta funcionalidad es la suma de Resource Manager más Kernel Isolation introducida en la versión 10 de Solaris. Cada instalación de Solaris 10, tendrá como mínimo una zona global y tantas zonas non-global como queramos <o pueda nuestro host>

Al igual que sucede con LDOMS, nuestra zona global será la encargada de gestionar las demás y, a diferencia de LDOMS aquí no hay productores y consumidores.

La principal diferencia, a parte del kernel compartido, está en la reconfiguración dinámica que no es posible. Es necesario reiniciar para que cualquier cambio en la configuración de la zona se vea reflejada.

Podéis encontrar más información en algún post sobre Gestión Básica de Zonas.

    Software, VirtualBox
    Por último, sólo nos queda comentar el hypervisor de Sun para tecnologías x86 similar a VMWare. Por ello, no vamos a entrar en hacer un análisis detallado ya que asumo que la tecnología de VM es conocida por todos.

    Y ... cuál utilizo?
    Bueno, esto es una pregunta con dificil respuesta. Depende mucho de: Dinero y Necesidades. Si tenemos necesidades de reconfiguración en caliente,por ejemplo tenemos mucha carga de CPU la última semana del mes y el resto es mínima, y disponemos de arquitectura Mx000, entonces, nuestra solución pasa por utilizar dominios.

    Si queremos consolidar aplicativos web, correo, j2ee y tenemos máquinas CMT aka T1, T2 o T2+ la solución pasa por utilizar LDOMS y sobre algunos Solaris Zones.

    Por último, si queremos trastear y necesitamos entornos de pruebas rápidos y sencillos, las zonas son nuestro gran aliado.

    Y mi RDBMS dónde encaja? Bien, mi recomendación es que no se sitúe Oracle en Zonas de Solaris si estamos en un momento de expansión ya que Existen Problemas y Limitaciones de Oracle en Zonas además, si disponemos de hardware SPARC y necesitamos alta disponibilidad, es más fácil otro tipo de Soluciones.

    Conclusión
    Espero no haber soltado un rollo muy largo, pero creo que una explicación sobre las diferentes posibilidades que nos ofrece Sun son muchas y variadas, más allá de las Zonas de Solaris. Además, prometí que escribiría sobre el tema, y así lo he hecho,

    Las ilustraciones han sido obtenidas de los documentos de Sun Microsystems "Guide to LDOMS" y "Mx000 Administation Guide"

    Referencias

    miércoles, 23 de diciembre de 2009

    Cómo ver Uso CPU por Procesador

    Introducción
    Solaris nos ofrece el comando <prstat> para poder ver el uso de cpu, memoria, cola de procesos, etc.  sin embargo, puede que nos interese saber qué cpus (o cores) se encuentran más saturados, para ello, deberemos utilizar el comando <mpstat>

    Al igual que sucede con los comando xxSTAT (iostat, vmstat, prstat) tiene dos argumentos opcionales <intervalo> y <número de muestras>, recordar que si establecemos un intervalo inferior a 6, podemos estar interfiriendo en la muestra.

    Si utilizamos el comando sin ningún argumento, entonces, se nos mostrará la media desde el último boot time, por ejemplo,
    # mpstat
    CPU minf mjf xcal  intr ithr  csw icsw migr smtx  srw syscl  usr sys  wt idl
      0   11   0  233    11    6  126    1   11    4    0   137    5   0   0  95
      2    9   0  227   353   55  140    1   10    4    0   120    3   0   0  96
     16    8   0   69    19   15   73    1    7    4    0   105    5   0   0  94
     18    7   0  110    98   52  101    1    7    4    0   120    4   0   0  96

    Ahora vamos a obtener tres muestras en intervalos de 6 segundos
    # mpstat 6 3
    CPU minf mjf xcal  intr ithr  csw icsw migr smtx  srw syscl  usr sys  wt idl
      0   11   0  235    11    6  126    1   11    4    0   137    5   0   0  95
      2    9   0  228   353   55  140    1   10    4    0   120    3   0   0  96
     16    8   0   69    19   15   74    1    7    4    0   105    5   0   0  94
     18    7   0  110    98   52  101    1    7    4    0   120    4   0   0  96
    CPU minf mjf xcal  intr ithr  csw icsw migr smtx  srw syscl  usr sys  wt idl
      0   26   0 6364    12    6  307    2   26   14    3   529    6   1   0  92
      2  127   0 3823   736  133  229    5   28   12    1   517   21   1   0  78
     16   13   0 1554    12    6  177    2   13   16    1   280   16   1   0  84
     18   38   0 2164   161  152  271    3   15   11    1   331   18   1   0  81
    CPU minf mjf xcal  intr ithr  csw icsw migr smtx  srw syscl  usr sys  wt idl
      0    0   0 3991    14    6  543    2   40   32    1   330    2   2   0  96
      2    0   0 1311  1125  171  320    2   35   15    1   235   13   1   0  86
     16    0   0 1214    12    6  259    1   16   38    0   168    4   1   0  96
     18    1   0  550   292  278  199    6   10    9    1   440   40   1   0  59
    La definición de las columnas será la siguiente, aunque te recomiendo que leas el man page
    • CPU, Nº de CPU
    • csw, Context SWitch
    • icsw, Involuntary Context SWitch
    • usr, Tiempo de Usuario
    • sys, Tiempo de Sistema
    • wt, IO working time
    Debemos prestar atención a los valores de icsw y wt ya que estos nos dirán si tenemos bien dimensionada la máquina.

     Referencias

    martes, 22 de diciembre de 2009

    Cómo Poner un Banner SSH en Solaris 10

    Introducción
    Una de las medidas de seguridad es incluir un Banner de Aviso cuando un usuario intenta acceder al sistema mediante SSH, para ello, simplemente deberemos editar el archivo </etc/ssh/sshd_config> y en la propiedad <Banner> asignaremos un archivo de texto existente

    Si queremos que una vez logeado en el sistema, podemos hacer que se muestre nuesto motd con las informaciones que consideremos necesarias, veamos un ejemplo

    # echo "Bienvenido al Sistema de SafeChildren" > /etc/issue
    # vi /etc/ssh/sshd_config
         Banner /etc/issue
         PrintMotd no
    :wq

    # pkill -HUP sshd

    Al logearnos, nos mostrará lo siguiente:
    $ ssh test@test.sfchildren.com
    Bienvenido al Sistema de SafeChildren
    Contraseña:
     Referencias

    lunes, 21 de diciembre de 2009

    Cómo Saber el Tipo de Archivo 64bits o 32bits en Solaris

    Introducción
    Para saber si un tipo de archivo binario de Solaris es de 64bits o de 32bits, simplemente deberemos utilizar el comando <file>
    $ file squid
    squid:          ELF 64 bits MSB ejecutable SPARCV9 Versión 1, enlazado dinámicamente, no quitado
    $ file /usr/bin/bash
    /usr/bin/bash:  ELF 32 bits MSB ejecutable SPARC Versión 1, enlazado dinámicamente, quitado
     Referencias

    viernes, 18 de diciembre de 2009

    Instalar Apache Mod GZip Solaris 10 64bits

    Introducción
    Vamos a instalar mod_gzip sobre Apache 1.3.41 en Solaris 10 en 64bits para, continuando con la serie de Optimización de páginas web en Solaris, en esta ocasión nuestro objeto será optimizar el tamaño de transferencia de nuestras páginas web.

    Este módulo nos va a permitir comprimir las páginas "al vuelo" utilizando el formato de compresión GZIP. Los navegadores actuales, soportan el envío de páginas web en formato gzip de forma nativa, y por lo tanto, no deberemos hacer ningún cambio en los clientes.

    El servidor Apache será el encargado de decidir si el cliente es capáz de entender el formato comprimido analizando la cabecera Accept-Encoding y verificando que contiene el valor de  gzip o deflate, si tiene esta cabecera, entonces Apache enviará el contenido comprimido en formato gzip, si no es así, lo enviará en formato plano.

    La cabecera que debe contener será la siguiente:
    Accept-Encoding: gzip,deflate
    Al reducir el tamaño a enviar, haremos que nuestro servicio sea más rápido, sin embargo, debemos tener en cuenta que estamos cargando al servidor con el proceso de compresión al vuelo de nuestras páginas web, sin embargo, esto es fácilmente solucionable introduciendo proxys reversos para descargar al Apache.

    Veamos cómo podemos compilar y configurar Mod_Gzip en nuestro Apache 1.3.41 64bits sobre Solaris.


    Nota Importante sobre GCC y Expat en Solaris 10

    Ya os he comentado en post anteriores los problemas que existen al Compilar Apache HTTP Server en 64bits con GCC en Solaris 10, y Problemas de Compilación de Apache HTTP Server y Mod JK con GCC 64bits en Solaris 10, así que os remito a Compilar Apache HTTP Server en 64bits con SunCC en Solaris 10 para poder continuar.

    Si tenéis compilado vuestro Apache con GCC en 64bits, el módulo de mod_gzip no funcionará, aunque compile perfectamente.


    Bajamos y descomprimimos el Source Code de Mod Gzip 
    Podemos descargar el código fuente de mod_gzip desde SourceForge, donde tiene alojada la página principal. Una cosa que nos llama la atención es que la última versión es la 1.3.26a del año 2002, así que es una versión muy estable, :D

    $ wget http://downloads.sourceforge.net/project/mod-gzip/mod-gzip13x/mod_gzip-1.3.26.1a/mod_gzip-1.3.26.1a.tgz?use_mirror=sunet
    $ gtar zxpf mod_gzip-1.3.26.1a.tgz
    Compilamos e Instalamos el Módulo
    Antes de poder compilar el módulo, debemos hacer algunos cambios en el <Makefile> ya que por defecto tiene los modifcadores para GCC, y por lo tanto, debemos adaptarlos a SunCC.

    Así que buscaremos el archivo <Makefile> ubicado en $MOD_GZIP_HOME/Makefile y sustituiremos la entrada del tag <build>
    $(APXS) -Wc,-Wall,-O3,-fomit-frame-pointer,-pipe -c mod_gzip.c mod_gzip_debug.c mod_gzip_compress.c -o mod_gzip.so
    Por la siguiente
    $(APXS) -Wc,-m64 -Wc,-O3 -c mod_gzip.c mod_gzip_debug.c mod_gzip_compress.c -o mod_gzip.so
    Sólo una nota para GCC 32bits
    Para aquellos que tenéis el Apache HTTP Server en 32bits compilado con GCC, el parámetro de optimización se encuentra en su nivel máximo -O3, y este valor provoca que se produzcan muchos coredump, además de ser un nivel que no se debe utilizar según GCC a no ser que se tenga muy testeado. Después de muchos Apaches con mod_gzip instalados, puedo asegurarte que con este flag en 32bits, falla, y falla mucho, así que mi recomendación es dejarlo en -O2 para GCC, por lo tanto, quedaría así:
     $(APXS) -Wc,-Wall,-O2,-fomit-frame-pointer,-pipe -c mod_gzip.c mod_gzip_debug.c mod_gzip_compress.c -o mod_gzip.so

    Además vamos a utilizar el comando <GNU Make> en vez de <Make> y de esta forma, nuestro mod_gzip no nos dará problemas (aunque con <make> tampoco protesta ;) )
    $ cd mod_gzip-1.3.26.1a
    $ gmake APXS=/opt/www/apache-1.3.41/64/bin/apxs
    $ su
    password:
    # gmake APXS=/opt/www/apache-1.3.41/64/bin/apxs install
    /opt/www/apache-1.3.41/64/bin/apxs -A -i mod_gzip.so
    [preparing module `gzip' in /opt/www/apache-1.3.41/64/conf/httpd.conf]
    cp mod_gzip.so /opt/www/apache-1.3.41/64/libexec/mod_gzip.so
    chmod 755 /opt/www/apache-1.3.41/64/libexec/mod_gzip.so
    cp /opt/www/apache-1.3.41/64/conf/httpd.conf /opt/www/apache-1.3.41/64/conf/httpd.conf.bak
    cp /opt/www/apache-1.3.41/64/conf/httpd.conf.new /opt/www/apache-1.3.41/64/conf/httpd.conf
    rm /opt/www/apache-1.3.41/64/conf/httpd.conf.new
    Configuración Mog Gzip
    Dentro del directorio donde hemos descomprimido mod_gzip <MOD_GZIP_HOME> encontraremos un archivo de ejemplo <mod_gzip.conf.sample> que podemos utilizar para ir comprobando el funcionamiento. Podemos copiar este template en $APACHE_HOME/conf/extra/modules/mod_gzip.conf y utilizando la directiva <Include> de configuración de Apache podemos añadirlo tanto a nuestro servidor principal, o a los VirtualHost que deseemos, por ejemplo podemos tener lo siguiente en nuestro $APACHE_HOME/conf/http.conf
    #############################################
    # CARGA DE MODULOS
    #############################################
    LoadModule gzip_module        libexec/mod_gzip.so
    #################################################
    ## MOD_GZIP
    #################################################
    Include conf/extra/modules/modgzip.conf

    Conclusiones
    Salvo el problema con GCC en 64bits, la instalación de mod_gzip en Solaris 10 no es más complicada que otro módulo, además nos permite utilizarlo de forma muy flexible sólo en aquellos lugares donde nos interese.

    Recordar que debemos comprobar el rendimiento obtenido mediante Pruebas de JMeter para Web y de esta forma, ver cómo vamos mejorando <o no> nuestro sistema desde la base

    Referencias

    miércoles, 16 de diciembre de 2009

    Instalar Apache HTTP 64bits SunCC Solaris 10

    Introducción
    En esta ocasión vamos a ver cómo podemos Compilar Apache HTTP Server en 64bits utilizando SunCC en Solaris 10. Esto es debido en gran parte a un problema que os conté hace un tiempo sobre Problemas de Compilación Apache HTTP Server con GCC en Solaris 10 y que se debían a un bug de GCC en Solaris.

    Continuando con la serie de Optimización de Páginas Web en Solaris, me he encontrado con otro problema, esta vez con el módulo mod_gzip que produce un core dump cuando se ejecuta compilado con GCC en 64bits. La verdad es que he probado de todo pero no he sido capáz de hacer funcionar este módulo con el servidor Apache HTTP en 64bits sobre Solaris compilado con GCC, sin embargo, cuando se compila con SunCC, el módulo mod_gzip funciona correctamente, por eso, he creado este pequeño post.

    Al parecer, el problema viene con la biblioteca expat y cualquier módulo que utilice esta biblioteca, creará un coredump y el servidor nos devolverá una página en blanco <se caerá>. He estado compilando sobre diferentes arquitecturas <SPARC, x86> y, en ambos casos, se producía el mismo error. El servidor funcionaba correctamente hasta que se activaba el módulo mod_gzip

    Requisitos
    Para poder compilar Apache HTTP Server con SunCC, obviamente, es necesario tener instalado el Sun Studio Developer Tools y para instalarlo, deberemos seleccionar <al igual que con Java> el formato de instalación.

    Una vez tengamos instalado nuestro SunCC, debemos incluir el directorio <bin> en nuestro PATH para que encuentre <cc> antes que <gcc>, por ejemplo, podemos editar nuestro .profile para que contenga:
    PATH=$PATH:/opt/SUNWspro/bin:/usr/sfw/bin:/usr/ccs/bin:/usr/local/bin
    export PATH
    Comprobamos que tenemos el entorno correcto, como podéis comprobar, yo tengo la versión 5.9 del Sun Studio Compiler, pero también funciona con la última versión
    $ which cc
    /opt/SUNWspro/bin/cc
    $ which gcc
    /usr/sfw/bin/gcc
    $ which make
    /usr/ccs/bin/make
    $ which gmake
    /usr/sfw/bin/gmake
    $ cc -V
    cc: Sun C 5.9 SunOS_i386 Build40_1 2007/02/08
    usage: cc [ options] files.  Use 'cc -flags' for details
    Instalación de Apache
    Vamos a seguir los mismos pasos que realizamos en Compilación de Apache HTTP Server con Mod Security y Mod Bandwidth en 64bit sobre Solaris, pero vamos a modifcar los siguientes valores:
    • En esta ocasión, no será necesario exportar la variable de entorno LD_LIBRARY_PATH
    • Asignaremos el valor de <cc> a la variable CC en el configure en vez de <gcc>
    Una vez descargado y descomprimido el servidor, podemos comenzar a configurarlo con los siguientes valores:
    $ export CC="cc"
    $ export CFLAGS="-O2 -m64"
    $ ./configure \
          "--with-layout=Apache" \
          "--enable-module=rewrite" \
          "--enable-module=expires" \
          "--enable-module=headers" \
          "--enable-module=mmap_static" \
          "--add-module=src/modules/extra/mod_bandwidth.c" \
          "--permute-module=BEGIN:bandwidth" \
          "--activate-module=src/modules/extra/mod_security" \
          "--enable-module=security" \
          "--disable-module=status" \
          "--enable-module=so" \
          "--prefix=/opt/www/64/apache-1.3.41" \
         "$@"
    Una vez configurado, haremos un <make> y <make install> para finalizar la instalación.

    Conclusiones
    Después de horas de pruebas, no pude más que llegar a la conclusión de que el bug de GCC es más molesto de lo que a simple vista puede parecer. El problema no es que no se pueda solucionar, sino que como se produce en tiempo de ejecución, puede darse con cualquier módulo que instales y, por lo tanto, deje de funcionar tu servidor http.

    Compilar Apache HTTP Server, Mod_JK, Mod_Gzip y los demás módulos necesarios para nuestro servidor Web, no suelen suponer mayor problema hacerlo con GCC o con SunCC, y por lo tanto, ahora que SunCC es free es una opción alternativa.

    En el siguiente post veremos Cómo compilar Mod Gzip en Apache 1.3.41 64bits con SunCC en Solaris 10

    Referencias

    lunes, 14 de diciembre de 2009

    Instalar Apache Tomcat Solaris 10 64bits SMF

    Introducción
    En esta ocasión vamos a instalar Apache Tomcat 6.0 en Solaris 10 64bits utilizando el framework SMF para su gestión.

    Prerequisitos
    En función de la versión de Apache Tomcat que queramos instalar, necesitaremos una versión de máquina virtual u otra, por ejemplo, para Apache Tomcat 6.x necesitaremos JVM 1.5+ y para Apache Tomcat 5.x JVM 1.4+.

    En este ejemplo vamos a instalar la versión de Apache Tomcat 6.x utilizando la versión 1.6+ en 64bits, para comprobar la versión que tenemos instalada y su arquitectura haremos lo siguiente:
    $ which java
    /usr/bin/java
    $ java -version
    java version "1.6.0_17"
    Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
    Java HotSpot(TM) Server VM (build 14.3-b01, mixed mode)
     Para comprobar si tenemos soporte de Java 64bits, utilizaremos el modificador <-d64>, además debemos tener en cuenta si nuestro Solaris tiene Soporte de 64bits
    $ java -d64 -version
    java version "1.6.0_17"
    Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
    Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)
    Si por algún motivo no tuvieses la versión de Java mínima, puedes ver Cómo Instalar Java en Solaris 10 64bits

    En esta ocasión vamos a instalar Apache Tomcat utilizando el usuario <webrunner&g;, grupo <webrunner> y project <user.webrunner>, así que deberemos crearlos antes de continuar,
    # groupadd webrunner
    # useradd -s /bin/bash -d /export/home/webrunner -m -g webrunner webrunner
    # projadd user.webrunner
    Descargar e Instalación de Apache Tomcat
    Descargaremos la versión binaria de Apache Tomcat, recordar que es una aplicación Java, y por lo tanto, no depende de plataforma, desde la web de Apache Tomcat  y la descomprimiremos en el directorio que nosotros queramos, en mi caso voy a situar la aplicación en </opt/ww/tomcat6>
    # cd /opt/
    # mkdir www
    # cd /opt/www/
    # pwd
    /opt/www
    # /usr/sfw/bin/wget http://apache.rediris.es/tomcat/tomcat-6/v6.0.20/bin/apache-tomcat-6.0.20.tar.gz
    # /usr/sfw/bin/gtar zxpf apache-tomcat-6.0.20.tar.gz
    # mv apache-tomcat-6.0.20 tomcat6
    # chown -R webrunner:webrunner tomcat6
    # rm apache-tomcat-6.0.20.tar.gz
    Instalación del Descriptor
    Puedes descargar el Descriptor SMF para Tomcat6 o Descriptor SMF para Tomcat 5.x, en ambos casos, debes asignar los valores correctos a las propiedades
    • home, Directorio donde hemos instalado el Tomcat
    • jvmargs, Argumentos de la máquina virtual, valor que se pasará a la variable JAVA_OPTS
    • project, Project con el cual lanzaremos el Tomcat
    • java_home, Home de la versión de Java a utilizar
    Una vez editado, simplemente lo cargaremos en nuestro repositorio con el comando <svccfg>
    # mkdir -p /var/svc/manifest/application/web
    # cd /var/svc/manifest/application/web
    # /usr/sfw/bin/wget blog.sfchildren.com/blogger/tomcat/smf/tomcat_6.xml
    # svccfg
    svc:> validate /var/svc/manifest/application/web/tomcat_6.xml
    svc:> import /var/svc/manifest/application/web/tomcat_6.xml
    svc:> quit
    # svcs tomcat_6
    STATE STIME FMRI
    disabled 13:53:39 svc:/application/web/tomcat_6:default_64bits
    disabled 13:54:16 svc:/application/web/tomcat_6:default_32bits
    Ahora vamos a descargar el archivo method de Tomcat encargado de ejecutar realmente el Tomcat. Esta versión no es necesario modificar ya que se nutre de los parámetros definidos en el Manifest, podéis descargar el Method para Tomcat 6 o Method para Tomcat 5
    # cd /lib/svc/method
    # /usr/sfw/bin/wget http://blog.sfchildren.com/blogger/tomcat/smf/tomcat6
    # chown root:bin tomcat6
    # chmod 555 tomcat6
    Activación del Servicio Tomcat
    Ahora activaremos el servicio que deseemos, en mi caso el de 64bits, pero recordad que sólo uno de los dos puede estar activo simultáneo
    # svcadm enable tomcat_6:default_64bits
    # svcs tomcat_6
    STATE          STIME    FMRI
    disabled       13:54:16 svc:/application/web/tomcat_6:default_32bits
    online         13:55:39 svc:/application/web/tomcat_6:default_64bits
    Podemos ver el pid del proceso Java que está ejecutando utilizando el modificador <-p> del comando <svcs>
    $ svcs -p tomcat_6
    STATE          STIME    FMRI
    disabled       dic_09   svc:/application/web/tomcat_6:default_64bits
    online         11:58:26 svc:/application/web/tomcat_6:default_32bits
                   11:58:26    24927 java
    Conclusiones
    En esta ocasión hemos visto cómo podemos activar el servicio Apache Tomcat utilizando SMF y su gestión pasa ahora por el Sistema Operativo.

    Ahora que ya entendemos cómo funciona SMF, podemos hacer definiciones más complejas utilizando servicios dependientes en nuestros archivos manifest, pero esto es para el siguiente post


    Referencias

    jueves, 10 de diciembre de 2009

    Instalar Java 6 en Solaris 10 64bits

    Introducción
    La instalación de Java se nos proporciona de dos forma: mediante pkgadd o mediante archivo autoextraible. El primer dilema es seleccionar cuál de los dos formatos es el que nos interesa utilizar, y bien, esto depende en gran medida de qué tipo de aplicaciones tengamos instalado y su certificación.

    Me explico, imaginemos que tenemos un applicativo APP el cual está certificado sólo y exclusivamente para Java 1.5.x, e incompatible con la 1.6.x. En esta situación tenemos dos soluciones:
    • Configurar correctamente los PATH para que sólo ejecute la versión 1.5.x
    • No instalar otra máquina virtual distinta a la 1.5.x
    Bien, partiendo de la base de que no tenemos estos problemas, y centrándonos en el tema del post, vamos a ver qué diferencias hay entre la instalación mediante pkgadd y autoextraible.

    Instalación mediante <pkgadd>
    Este tipo de instalación requiere acceso como <root> ya que vamos registrar el paquete en la base de datos de software instalado de Solaris. Tiene como ventaja, que si realizamos una instalación de parches, al estar declarado en la base de Software instalado, se podrán aplicar los necesarios de forma automática.

    Debemos tener en cuenta, que si hacemos esto desde la zona global, y no decimos lo contrario, éste se instalará en todas las zonas, esto puede ser un tipo de inconveniente cuando tenemos varias zonas con diferentes requisitos de Java, i.e. Oracle, Tomcat, ActiveMQ, ...

    Lo primero que debemos hacer es Descargar Java 6 JDK o JRE desde Sun y seleccionaremos la arquitectura de nuestra plataforma, en mi caso Solaris SPARC.


    En la pagina de descargas, después de logearnos, tendremos cuatro opciones:
    • jdk-VERSION-solaris-sparc.tar.Z
    • jdk-VERSION-solaris-sparcv9.tar.Z
    • jdk-VERSION-solaris-sparc.sh
    • jdk-VERSION-solaris-sparcv9.sh

    Las versiones <tar.Z> corresponde al tipo de instalación con pkgadd y las versiones <sh> a las versiones autoextraibles, además las versiones de 64bits en SPARC son referenciadas como sparcv9 y las de 32bits como sparc. A continuación veámos cómo se instalan los paquetes, (realmente es el mismo proceso que cualquier otro paquete de Solaris, en mi ejemplo instalo todos aunque puedes seleccionar que quieres instalar)

    # zcat jdk-6u17-solaris-sparc.tar.Z |tar xpf -
    # pkgadd -d .

    The following packages are available:
      1  SUNWj6cfg              JDK 6.0 Host Config. (1.6.0_17)
                                (sparc) 1.6.0,REV=2006.11.29.05.57
      2  SUNWj6dev              JDK 6.0 Dev. Tools (1.6.0_17)
                                (sparc) 1.6.0,REV=2006.11.29.05.57
      3  SUNWj6dmo              JDK 6.0 Demo Programs (1.6.0_17)
                                (sparc) 1.6.0,REV=2006.11.29.05.57
      4  SUNWj6jmp              JDK 6.0 Man Pages: Japan (1.6.0_17)
                                (sparc) 1.6.0,REV=2006.12.07.19.24
      5  SUNWj6man              JDK 6.0 Man Pages (1.6.0_17)
                                (sparc) 1.6.0,REV=2006.12.07.16.37
      6  SUNWj6rt               JDK 6.0 Runtime Env. (1.6.0_17)
                                (sparc) 1.6.0,REV=2006.11.29.05.57
      7  SUNWjavadb-client      Java DB client
                                (sparc) 10.4.2,REV=2008.10.20
      8  SUNWjavadb-common      Java DB common files
                                (sparc) 10.4.2,REV=2008.10.20
      9  SUNWjavadb-core        Java DB core
                                (sparc) 10.4.2,REV=2008.10.20
     10  SUNWjavadb-demo        Java DB demo
                                (sparc) 10.4.2,REV=2008.10.20

    ... 3 more menu choices to follow;
    for more choices, to stop display:

     11  SUNWjavadb-docs        Java DB documentation
                                (sparc) 10.4.2,REV=2008.10.20
     12  SUNWjavadb-javadoc     Java DB javadoc
                                (sparc) 10.4.2,REV=2008.10.20
     13  SUNWjavadb-service     Java DB service management
                                (sparc) 10.4.2,REV=2008.11.13

    Select package(s) you wish to process (or 'all' to process
    all packages). (default: all) [?,??,q]: all


     El instalador realizará esta tarea para cada una de las zonas.
    Una vez concluido el proceso, ya tenemos nuestra versión Java instalada

    Instalación desde archivo sh
    Este tipo de instalación no requiere privilegios de <root>, ya que es un shx (archivo autoextraible)  y por lo tanto, sólo necesitamos permisos de escritura en el directorio en el cuál queremos descomprimirlo, sin embargo, a diferencia de la instalación mediante <pkgadd> no queda reflejado en la base de datos de software instalado, y por lo tanto, cuando parchemos no se aplicarán los cambios al paquete JDK.

    Continuando con la instalación mediante archivo sh, quiero descomprimirlo en /usr/jdk/instances y por lo tanto si que necesito ser root

    En esta ocasión, nos interesan las versiones <sh> de la página de descargas de Sun. Recordar que cuando se transfieran los archivos al servidor si lo hacemos mediante ftp, debemos asignar el tipo de transferencia como binario ya que sino, no se extraerá correctamente. Si utilizamos sftp, no hay problema

    Una vez subidos al servidor, simplemente deberos ejecutarlos en el directorio que queremos extraerlo, por ejemplo, en mi caso los sh están en $HOME/jdk/6/ y quiero instalarlos en /usr/jdk/instances así que hago lo siguiente
    # cd /usr/jdk/instances
    # sh $HOME/jdk/6/jdk-6u17-solaris-sparc.sh

    ahora sale un mensaje de licencia, pulsamos Q y aceptamos la licencia

    Do you agree to the above license terms? [yes or no]
    yes
     Repetimos el mismo procedimiento para la versión de 64bits
    # cd /usr/jdk/instances
    # sh $HOME/jdk/6/jdk-6u17-solaris-sparcv9.sh
    Ya tenemos concluida la instalación de Java.

    Hacer esta versión por defecto
    Una vez instalada la nueva versión de Java, nuestro sistema seguirá llamado a la versión de Java que tiene en el PATH, esto es /usr/bin/java que es un link a /usr/java/bin/java, así que para hacer que sea nuestro default tenemos dos opciones:
    • Establecer la variable de entorno PATH como PATH=/usr/jdk/instances/jdk1.6.0_17/bin:$PATH
    • Borrar y crear el link de /usr/java a /usr/jdk/instances/jdk1.6.0_17/
    Veamos cómo recrear el link
    # which java
    /usr/bin/java
    # ls -l /usr/bin/java
    lrwxrwxrwx   1 root     other         16 sep  2  2008 /usr/bin/java -> ../java/bin/java
    # ls -l /usr/java
    lrwxrwxrwx   1 root     other         15 sep  2  2008 /usr/java -> jdk/jdk1.5.0_14
    # rm /usr/java
    # ln -s /usr/jdk/instances/jdk1.6.0_17 /usr/java
    # java -version
    java version "1.6.0_17"
    Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
    Java HotSpot(TM) Server VM (build 14.3-b01, mixed mode)
    Conclusiones
    En ambos casos, la instalación de Java no reviste mayor problema, sin embargo, la decisión de instalación de una forma u otra dependerá principalmente del tipo de software que tenemos instalado.

    Yo por ejemplo, en las workstation o equipos de testing suelo utilizar las versiones de sh y, en producción las de pkgadd (siempre que no esté Oracle por medio)

    Referencias

    lunes, 7 de diciembre de 2009

    Problemas Compilación GCC Solaris 64bits Apache Mod_JK

    Introducción
    Compilar Apache 1.3.41 en 64bits en Solaris con GCC puede darnos algún que otro problema cuando empecemos a incluir módulos como mod_jk, mod_gzip, principalmente debido a un problema de configuración predeterminada en la compilación del binario de gcc que viene con Solaris. Este problema es que tiene asignado como Runtime Library Search Path (-rpath) /usr/sfw/lib y por lo tanto, cuando utilizamos el modificador -m64 para crear binarios de 64bits

    En los post sobre Compilación de Apache 1.3.41 en 64bits hemos solucionado el problema asignando el valor de la variable LD_LIBRARY_PATH_64 a </usr/sfw/lib/64>, aunque no está mal, existe otra solución para evitar tener que estar asignando la variable en cada ejecución. Durante la compilación de Apache, podemos asignar Runtime Library Search a </usr/sfw/lib/64> a LDFLAGS, de esta forma el linker incluirá en sus search path la ruta de 64 en vez de la de 32, veamos un ejemplo:

    Compilaremos Apache con los siguientes parámetros, fijaros que en esta ocasión hemos incluido LDFLAGS además de CFLAGS
    CFLAGS="-m64 -O2" \
    LDFLAGS="-R/usr/sfw/lib/64" \
    ./configure \
    "--with-layout=Apache" \
    "--enable-module=rewrite" \
    "--enable-module=expires" \
    "--enable-module=headers" \
    "--enable-module=mmap_static" \
    "--add-module=src/modules/extra/mod_bandwidth.c" \
    "--permute-module=BEGIN:bandwidth" \
    "--activate-module=src/modules/extra/mod_security" \
    "--enable-module=security" \
    "--enable-module=status" \
    "--enable-module=so" \
    "--prefix=/opt/www/apache-1.3.41/64" \
    "$@"
    Compilaremos como siempre nuestro Apache 1.3.41 y lo instalaremos. Ahora vamos a comprobar cómo sin establecer la variable LD_LIBRARY_PATH_64 el binario <httpd> encuentra correctamente las bibliotecas de 64bits de <sfw>
    $ echo $LD_LIBRARY_PATH

    $ echo $LD_LIBRARY_PATH_64

    $ ldd httpd 
            libsocket.so.1 =>        /usr/lib/64/libsocket.so.1
            libnsl.so.1 =>   /usr/lib/64/libnsl.so.1
            libpthread.so.1 =>       /usr/lib/64/libpthread.so.1
            libexpat.so.1 =>         /usr/sfw/lib/64/libexpat.so.1
            libc.so.1 =>     /usr/lib/64/libc.so.1
            libmp.so.2 =>    /lib/64/libmp.so.2
            libmd.so.1 =>    /lib/64/libmd.so.1
            libscf.so.1 =>   /lib/64/libscf.so.1
            libdoor.so.1 =>  /lib/64/libdoor.so.1
            libuutil.so.1 =>         /lib/64/libuutil.so.1
            libgen.so.1 =>   /lib/64/libgen.so.1
            libm.so.2 =>     /lib/64/libm.so.2
    Ahora bien, continuando con la compilación de los módulos, nos encontramos con el problema añadido de MOD_JK. La compilación de mod_jk utilizando APXS, se realiza de la siguiente forma, recordar que mod_jk se compila con GNU Make <gmake>
    $ CFLAGS="-m64 -O2" ./configure --with-apxs=/opt/www/apache-1.3.41/64/bin/apxs
    $ gmake
    Durante el proceso de link, se produce el siguiente error
    ld: error fatal: archivo .libs/mod_jk.o: clase ELF incorrecta: ELFCLASS64
    ld: error fatal: Errores en el proceso de archivos. No se escribir? la salida en .libs/mod_jk.so.0.0.0
    collect2: ld returned 1 exit status
    Esto es debido a que no hemos incluido el flag -64 para que el linker cree una <so> de 64bits, así que vamos a incluir los siguientes flags,
    $ CFLAGS="-m64 -O2" LDFLAGS="-64 -R/usr/sfw/lib/64" ./configure --with-apxs=/opt/www/apache-1.3.41/64/bin/apxs
    $ gmake
    Ahora durante el proceso de link, se produce ahora un nuevo error,
    ld: error fatal: archivo /usr/lib/crti.o: clase ELF incorrecta: ELFCLASS32
    ld: error fatal: Errores en el proceso de archivos. No se escribir? la salida en .libs/mod_jk.so.0.0.0
    collect2: ld returned 1 exit status
    gmake[1]: *** [mod_jk.la] Error 1
    Esto se debe a que el configurador no asigna correctamente el flag -m64 a la variable MOD_LINK del archivo Makefile, para ello, editaremos el archivo que se encuentra en $MOD_JK_HOME/native/apache-1.3 y sustituiremos el valor de MOD_LINK
    MOD_LINK   = $(LIBTOOL) --mode=link $(CC)  -Wl,-G -Wl,-64 -Wl,-R/usr/sfw/lib/64
    por el siguiente valor
    MOD_LINK   = $(LIBTOOL) --mode=link $(CC)  -Wl,-G -Wl,-64 -Wl,-R/usr/sfw/lib/64 -m64
    Una vez hecho esto, volvemos a compilar el mod_jk, y comprobaremos que todo está correcto.

    $ gmake clean all

    $ cd apache-1.3/.libs/
    $ file mod_jk.so
    mod_jk.so:      ELF 64 bits LSB biblioteca dinámica AMD64 Versión 1, enlazado dinámicamente, no quitado, no hay información de depuración disponible
    $ ldd mod_jk.so
            libc.so.1 =>     /lib/64/libc.so.1
            libgcc_s.so.1 =>         /usr/sfw/lib/64/libgcc_s.so.1
            libm.so.2 =>     /lib/64/libm.so.2
    Ya sólo nos quedaría instalar el módulo con <gmake install> y listo


    Conclusiones

    En esta ocasión hemos visto solventar pequeños problemas de compilación con GCC en Solaris 10 x64 y cómo con algunos cambios en la configuración podemos hacer que nuestro Apache 1.3.41 y Mod_JK compilen.

    Recordar que hemos realizado la compilación y las pruebas en Solaris 10 x86_64, y que para SPARC 64bits el directorio </usr/sfw/lib/64> es un link </usr/sfw/lib/sparcv9> y por lo tanto, las opciones del linker funcionarán también en SPARC, sin embargo, si utilizamos Sun CC como compilador, no será necesario realizar estos pasos, ya que no existe ese Bug.

    Referencias

    miércoles, 2 de diciembre de 2009

    Instalación de PostgreSQL 8.4 en Solaris 10 64bits - Parte 2

    Introducción
    En la primera parte de Instalación de PostgreSQL en Solaris 10, vimos como realizar los primeros pasos e iniciar la base de datos de PostgreSQL. En esta ocasión, vamos a ver cómo podemos utilizar el framework SMF para poder gestionar el inicio/parada/reconfiguración de PostgreSQL 8.4 utilizando los comandos svcadm enable/disable/restart

    UPDATED: Si quieres puedes ir a Cómo Instalar PostgreSQL 9.x en OpenIndiana, un post más actualizado sobre el proceso de instalación en el nuevo sistema operativo sucesor de OpenSolaris

    Un Recordatorio Rápido
    Solaris 10 tiene incluida las versione 8.1 y 8.3 de PostgreSQL en su core por eso, para comprobarlo realizaremos los siguientes pasos:
    # which psql
    /usr/bin/psql
    # /usr/bin/psql --version
    psql (PostgreSQL) 8.1.17
    incluye soporte para edición de línea de comandos
    En esta instalación de Solaris, el binario de psql es de la versión 8.1.17, por eso asignábamos en el profile del usuario postgres su PATH como $POSTGRES_HOME/bin en primer lugar, vamos a comprobarlo ahora desde el usuario postgres
    # su - postgres
    Sun Microsystems Inc.   SunOS 5.10      Generic January 2005

    POSTGRES VERSION: 8.4
    POSTGRES HOME   : /u01/app/postgres/8.4/db
    PGDATA          : /var/postgres/8.4/data
    PGARCH          : 64
    $ which psql
    /u01/app/postgres/8.4/db/bin/64/psql
    $ psql --version
    psql (PostgreSQL) 8.4.1
    incluye soporte para edición de línea de órdenes
    Una vez verificado aclarado el tema de las versiones y la importancia de asignar correctamente el PATH, PGDATA y POSTGRES_HOME, continuaremos

    Creación del Archivo de descripción (Manifest)
    Como hemos comentado, Solaris ofrece soporte para PostgreSQL y por ello, en el directorio /var/svc/manifest/application/database podemos encontrar los manifest para PostgreSQL 8.1,8.2 y 8.3. Éstos son dependientes del Sistema Operativo, y por lo tanto, no podemos modificar la estructura ya que al actualizar mediante algún parche, ésta puede ser modificada sin previo aviso, como indica el comentario del xml
    NOTE:  This service manifest is not editable; its contents will
    be overwritten by package or patch operations, including
    operating system upgrade.  Make customizations in a different
    file.
    Así que para evitar sorpresas vamos a utilizar el manifest de PostgreSQL 8.3 y vamos a crearnos uno nuevo postgresql_84 en el cual podamos hacer nuestros ajustes sin temor a que en un parche nos modifiquen los descriptores.

    Preparación del Entorno para SMF
    Vamos a crear el descriptor postgresql_8.4.xml utilizando el archivo postgresql_83.xml y modificaremos las entradas que hagan referencia a <postgresql_83> por <postgresql_84>, posteriormente crearemos un nuevo method de ejecución partiendo de /lib/svc/method/postgres_83, veamos los pasos:
    # cd /var/svc/manifest/application/database/
    # cat postgresql_83.xml > postgresql_84.xml
    # vi postgresql_84.xml 

         :%s/postgresql_83/postgresql_84/
         :%s/postgres_83/postgres_84/
    Deberemos sustiuir los valores de <property_group> en ambas instancias, es decir <default_64bits> y <default_32bits> por los siguientes:
    • Propiedad <bin> /u01/app/postgres/8.4/db/bin para 32bits y /u01/app/postgres/8.4/db/bin/64 para 64bits
    • Propiedad <data> /var/postgres/8.4/data
    • Propiedad <log> /var/log/postgres/server.log
    Desde aquí puedes descarte el archivo completo de PostgreSQL Manifest

    Ahora vamos a hacer lo mismo con el archivo method, partiendo de /lib/svc/method/postgres_83 y sustituyendo las entradas de postgresql_83 por postgresql_84
    # cat /lib/svc/method/postgres_83 > /lib/svc/method/postgres_84
    # chmod +x /lib/svc/method/postgres_84
    # chown root:bin /lib/svc/method/postgres_84
    El métdodo start vamos a modificarlo para asignar el path del archivo de log de forma absoluta en vez de relativa a PGDATA como está en Solaris, por lo tanto, nuestro método quedaría así
    case "$1" in
    'start')
            check_data_dir
            $PGBIN/pg_ctl -D $PGDATA -l $PGLOG start
            ;;
    Desde aquí puedes descargarte el archivo completo PostgreSQL Method

    Importación y Activación del Nuevo Servicio
    Vamos a importar el nuevo manifest utilizando svccfg como en otras ocasiones y para comprobarlo svcs <frmi>
    # svccfg
    svc:> validate /var/svc/manifest/application/database/postgresql_84.xml
    svc:>  import /var/svc/manifest/application/database/postgresql_84.xml
    svc:> quit
    # svcs postgresql_84
    STATE          STIME    FMRI
    disabled       12:20:05 svc:/application/database/postgresql_84:default_64bit
    disabled       12:20:05 svc:/application/database/postgresql_84:default_32bit
    Activamos el servicio y comprobamos el archivo de log de PostgreSQL que hemos ubicado en /var/log/postgres
    # svcadm enable postgresql_84:default_64bit
    # svcs postgresql_84:default_64bit
    STATE          STIME    FMRI
    online         12:27:59 svc:/application/database/postgresql_84:default_64bit
    # tail -f /var/log/postgres/server.log
    LOG:  el sistema de bases de datos fue apagado en 2009-12-01 23:45:10 CET
    LOG:  lanzador de autovacuum iniciado
    LOG:  el sistema de bases de datos está listo para aceptar conexiones
    ^C
    Comprobamos que nuestro servidor funciona correctamente, para ello, nos conectaremos con el cliente de PostgreSQL del sistema, recordar la primera parte sobre las versiones.

    # psql -U postgres
    Contraseña para usuario postgres:
    Bienvenido a psql 8.1.17 (servidor 8.4.1), la terminal interactiva de PostgreSQL.

    Digite:  \copyright para ver los términos de distribución
           \h para ayuda de comandos SQL
           \? para ayuda de comandos psql
           \g o or termine con punto y coma para ejecutar una consulta
           \q para salir

    ATENCION:  usted está conectado a un servidor con versión major 8.4,
    pero su cliente psql es versión major 8.1.  Algunos comandos backslash,
    tales como \d, pueden no funcionar adecuadamente.

    postgres=# \q

    Nota Importante Sobre el Manifest
    El archivo postgresql_84.xml que hemos editado comparte $PGDATA esto es debido a que yo personalmente sólo utilizo una de las dos versiones en la misma máquina, es decir, o la de 32bits o la de 64bits. Si quieres tener ese funcionamiento, debes tener dos PGDATA uno para 32 y otro para 64


    << Cómo Instalar PostgreSQL 8.4 64bits en Solaris 10 - Parte 1

    Conclusiones
    Hemos visto como Solaris nos proporciona gran parte del trabajo para incluir PostgreSQL en nuestro sistema de control SMF con una pequeña adaptación y por supuesto, ya tenemos la gestión de arranque y parada unificada utilizando svcadm


    En las siguientes entregas vamos a ver cómo continuar con la configuración de PostgreSQL en temas de WAL, Backup and Recovery, hasta entonces ... toca esperar



    Referencias

    lunes, 30 de noviembre de 2009

    Cálculo de Rendimiento de Apache 1.3.41 64bits vs 1.3.41 32bits en Solaris 10

    Introducción
    Continuando con la serie de Optimización de Páginas Web en Solaris, en esta ocasión vamos a ver qué diferencias de rendimiento podemos tener con la versión compilada de Apache 1.3.41 en 64bits y en 32bits, para ello continuaremos desde el punto anterior de Compilación de Apache 1.3.41 64bits en Solaris

    Para ello, vamos a configurar solo el valor de la propiedad <Listen> del archivo de configuración $APACHE_HOME/conf/httpd.conf

    Definición de las métricas de la prueba
    Para realizar la prueba de rendimiento se han utilizado tres versiones de Apache HTTP 1.3.41 en Solaris x86_64 sobre una máquina virtual en MacOS X. Los detalles de la configuración son los siguientes:
    • Host: Virtual Box 3.0.10 r54097 Sobre MacOS X
    • Guest:  Solaris 10 10/09 s10x_u8wos_08a X86
    • Memoria: 2048 Megabytes
    • Versión Apache: Apache 1.3.41
    Opciones de Compilación de Apache
    He realizado tres compilaciones, dos en 32 bits y una en 64bits con los siguientes parámetros:
    • 32bits sin Opciones:
    ./configure \
    "--with-layout=Apache" \
    "--enable-module=rewrite" \
    "--enable-module=expires" \
    "--enable-module=headers" \
    "--enable-module=mmap_static" \
    "--enable-module=rewrite" \
    "--add-module=src/modules/extra/mod_bandwidth.c" \
    "--permute-module=BEGIN:bandwidth" \
    "--activate-module=src/modules/extra/mod_security" \
    "--enable-module=security" \
    "--disable-module=status" \
    "--enable-module=so" \
    "--prefix=/opt/www/32/apache-1.3.41" \
    "$@"
    • 32bits Configure con CFLAGS="-O2"
    CFLAGS="-O2" \
    ./configure \
    "--with-layout=Apache" \
    "--enable-module=rewrite" \
    "--enable-module=expires" \
    "--enable-module=headers" \
    "--enable-module=mmap_static" \
    "--enable-module=rewrite" \
    "--add-module=src/modules/extra/mod_bandwidth.c" \
    "--permute-module=BEGIN:bandwidth" \
    "--activate-module=src/modules/extra/mod_security" \
    "--enable-module=security" \
    "--disable-module=status" \
    "--enable-module=so" \
    "--prefix=/opt/www/32/apache-1.3.41" \
    "$@"
    • 64bits Configure con CFLAGS="-m64 -O2"
    CFLAGS="-O2 -m64" \
    ./configure \
    "--with-layout=Apache" \
    "--enable-module=rewrite" \
    "--enable-module=expires" \
    "--enable-module=headers" \
    "--enable-module=mmap_static" \
    "--enable-module=rewrite" \
    "--add-module=src/modules/extra/mod_bandwidth.c" \
    "--permute-module=BEGIN:bandwidth" \
    "--activate-module=src/modules/extra/mod_security" \
    "--enable-module=security" \
    "--disable-module=status" \
    "--enable-module=so" \
    "--prefix=/opt/www/64/apache-1.3.41" \
    "$@"
    Herramientas de Testing
    Se han utilizado las herramientas de Apache Benchmark, que se encuentra en $APACHE_HOME/bin/ab y Apache JMeter. Para hacer una prueba más realista se han realizodo tres métricas con Apache Benchmark (una detrás de otra), y se ha calculado la media con los datos de conexión, rendimiento, etc. La definición de los parámetros son los siguientes:
    • Apache Benchmark (32bits)
    $ /opt/www/32/apache-1.3.41/bin/ab -n 10000 -c 15 http://localhost:8000/
    • Apache Benchmarck (64bits)
    $ /opt/www/apache-1.3.41/bin/ab -n 10000 -c 15 http://localhost:8080/
    • Apache JMeter (32bits y 64bits)
    Número de Hilos: 15
    Contador del Bucle: 10000
    Resultados Obtenidos
    A continuación vamos a ver los gráficos de resultados de las pruebas de Apache Benchmark (recordar que se han realizado tres métricas y luego la media)

    Apache 1.3.41 32bits sin Optimizaciones


    Apache 1.3.41 32bits con Optimización -O2


    Apache 1.3.41 64bits con Optimización -O2 -m64


    Comparativa de las tres gráficas: 32 vs 32plus v2 64


    Resultados de JMeter 32bits



    Resultados de JMeter 64bits


    Conclusiones
    Aunque este test es bastante sencillo, podemos ver como la compilación en 64bits de Apache nos proporciona un mayor rendimiento, además, con el simple hecho de incluir <-O2> ya obtenemos una mejoría con la configuración por defecto.

    Esto, que a simple vista es obvio, puede hacernos ver la importancia de compilar nuestros aplicativos en la arquitectura en la que queramos ejecutarlo, y en la medida de lo posible, evitar los paquetes precompilados para los entornos de producción.

    En la siguiente entrega, veremos cómo podemos ir configurando Apache HTTP Server para obtener mayor rendimiento utilizando mod_expires y mod_gzip.

    Referencias

    viernes, 27 de noviembre de 2009

    Compilar Apache 1.3.x Solaris 64bit con mod_bandwidth y mod_security

    Introducción
    Vamos a ver cómo podemos compilar la versión 1.3.41 de Apache HTTP Server en Solaris 10 en 64bits. La compilación en 64bits no es muy diferente de la de 32bits, realmente es introducir el modifcador -m64 en los flags de CC, sin embargo, si utilizamos módulos adicionales como(mod_bandwidth, mod_security, etc.  debemos incluir las bibliotecas de 64bits de /usr/sfw en nuestro LD_LIBRARY_PATH_64

    Si recordais la Instalación de MemCached en 64bits sobre Solaris, también teníamos que adaptar las variables de LD_LIBRARY_PATH, tanto la de 32bits como la de 64bits, en la instalación de Apache HTTP Server ocurre lo mismo.

    Módulos Adicionales
    En esta ocasión vamos a instalar dos módulos adicionales dentro del core del servidor Apache
    • mod_bandwidth, nos permite establecer usos de ancho de banda por dominio, ip, usuario
    • mod_security, firewall capa 7 (Firewall de aplicación)
    Además, vamos a habilitar los módulos de rewrite, headers, expires y so, este último para poder compilar el módulo jk que nos permite unir Apache HTTP Server con Apache Tomcat

    Instalación de Módulos Adicionales
    Para que podamos instalar los módulos dentro del core debemos copiar los mod_XXX.c al directorio $APACHE_HOME/src/modules/extra y de esta forma, podemos activarlos en la configuración.

    Descargamos el source de Apache HTTP Server 1.3 y lo descomprimimos en $HOME/Apache
    $ mkdir ~/Apache
    $ cd  ~/Apache
    $ wget http://apache.rediris.es/httpd/apache_1.3.41.tar.gz
    $ gtar zxpf apache_1.3.41.tar.gz
    Hay que tener en cuenta que la versión de mod_security para Apache HTTP Server 1.3.x es la 1.9.5, a partir de esta versión, son sólo para Apache HTTP Server 2.x, (aqui tienes un acceso director ala descarga de mod_security)
    $ wget http://downloads.sourceforge.net/project/mod-security/modsecurity-apache/1.9.5/modsecurity-apache_1.9.5.tar.gz?use_mirror=ovh
    $ gtar zxpf modsecurity-apache_1.9.5.tar.gz
    $ cd modsecurity-apache_1.9.5/apache1/
    $ cp mod_security.c ~/Apache/apache_1.3.41/src/modules/extra/
    Descargar e Instalar mod_bandwidth
    $ wget ftp://ftp.cohprog.com/pub/apache/module/1.3.0/mod_bandwidth.c
    $ cp mod_bandwidth.c  ~/Apache/apache_1.3.41/src/modules/extra/
    Compilación de Apache
    Una vez preparado el source de Apache, vamos a compilarlo utilizando los modificadores -m64 como hemos comentado al principio. Recordar que debemos establecer la variable LD_LIBRARY_PATH_64 para que nos encuentre las bibliotecas correctas.
    $ export LD_LIBRARY_PATH_64=/lib/64:/usr/lib/64:/usr/sfw/lib/64:/usr/ccs/lib
    $ CC="gcc" \
       CFLAGS="-O2 -m64" \
       ./configure \
          "--with-layout=Apache" \
          "--enable-module=rewrite" \
          "--enable-module=expires" \
          "--enable-module=headers" \
          "--enable-module=mmap_static" \
          "--add-module=src/modules/extra/mod_bandwidth.c" \
          "--permute-module=BEGIN:bandwidth" \
          "--activate-module=src/modules/extra/mod_security" \
          "--enable-module=security" \
          "--disable-module=status" \
          "--enable-module=so" \
          "--prefix=/opt/www/apache-1.3.41" \
         "$@"
    Instalación y Verificación de la Instalación
    Si todo ha compilado correctamente, podemos hacer una instalación y posteriormente la verificación con ldd, para instalar simplemente haremos
    # make install
    Y para verificar que todo está correcto
    $ ldd /opt/www/apache-1.3.41/bin/httpd
            libsocket.so.1 =>        /lib/64/libsocket.so.1
            libnsl.so.1 =>   /lib/64/libnsl.so.1
            libpthread.so.1 =>       /lib/64/libpthread.so.1
            libexpat.so.1 =>         /usr/sfw/lib/64/libexpat.so.1
            libc.so.1 =>     /lib/64/libc.so.1
            libmp.so.2 =>    /lib/64/libmp.so.2
            libmd.so.1 =>    /lib/64/libmd.so.1
            libscf.so.1 =>   /lib/64/libscf.so.1
            libdoor.so.1 =>  /lib/64/libdoor.so.1
            libuutil.so.1 =>         /lib/64/libuutil.so.1
            libgen.so.1 =>   /lib/64/libgen.so.1
            libm.so.2 =>     /lib/64/libm.so.2
    Si no establecemos el LD_LIBRARY_PATH_64 el resultado será que intentará enlazar con la versión de 32bits de libexpat.so.1
    # ldd /opt/www/apache-1.3.41/bin/httpd
            libsocket.so.1 =>        /lib/64/libsocket.so.1
            libnsl.so.1 =>   /lib/64/libnsl.so.1
            libpthread.so.1 =>       /lib/64/libpthread.so.1
            libexpat.so.1 =>         /usr/sfw/lib/libexpat.so.1 - clase ELF incorrecta: ELFCLASS32
            libc.so.1 =>     /lib/64/libc.so.1
            libmp.so.2 =>    /lib/64/libmp.so.2
            libmd.so.1 =>    /lib/64/libmd.so.1
            libscf.so.1 =>   /lib/64/libscf.so.1
            libdoor.so.1 =>  /lib/64/libdoor.so.1
            libuutil.so.1 =>         /lib/64/libuutil.so.1
            libgen.so.1 =>   /lib/64/libgen.so.1
            libm.so.2 =>     /lib/64/libm.so.2
    Editar la Configuración del Servidor
    Una vez tengamos nuestro servidor instalado y verificado, podemos comenzar a configurarlo.

    Conclusiones
    Hemos visto cómo instalar la versión de 64bits de Solaris con los módulos mod_security y mod_bandwidth que nos permiten establecer un Firewall de Capa 7 y un control de la tasa de transferencia.

    Con estos módulos cargamos, podemos comenzar con la configuración de nuestro servidor Apache que utilizaremos en los ejemplos de Optimización de Aplicativos Web en Solaris.

    En la siguiente entrega, comenzaremos con los parámetros de configuración del archivo $APACHE_HOME/conf/httpd.conf


    Referencias

    jueves, 26 de noviembre de 2009

    Eliminar Unknown hostname Solaris 10

    Introducción
    Hace un tiempo explicaba cómo Eliminar "Unknown Hostname" pero en Solaris 9, bien, ahora toca el turno de Solaris 10

    En Solaris 10, simplemente debemos establecer el valor de /etc/nodename y Solaris se encargará de asignar ese valor a nuestro Host.
    # echo "zooey" > /etc/nodename
    Una vez rebotado el sistema, veremos como en el archivo /etc/hosts existe una nueva entrada con el comentario de Added by DHCP, en mi caso zooey
    # cat /etc/hosts
      #
      # Internet host table
      #
      ::1     localhost      
      127.0.0.1       localhost      
      10.0.2.15      zooey    # Added by DHCP

    Conclusiones
    Esta vez, en Solaris 10 todo es mucho más sencillo y rápido, aunque siempre puedes utilizar el antiguo método si quieres ...


    Referencias

    martes, 24 de noviembre de 2009

    Cálculo de Rendimiento utilizando Apache JMeter - Parte 1

    Instalación
    En este primer post vamos a ver cómo utilizar JMeter para establecer un "Base Time Line" para nuestros cambios de configuración.

    Apache JMeter es un aplicativo diseñado para obtener métricas de rendimiento de una forma automática y repetible. Ésto que parece no es muy importante, sí que lo es. Una de las cosas que debemos eliminar de nuestro vocabulario cuando empecemos a realizar pruebas de carga son: "parece que, más rápido, más lento, ..." todas estas expresiones no nos sirven ya que dependen de muchos factores, aunque el mayor problema es que son subjetivas y dependientes de una/varias personas.

    JMeter nos ofrece datos "la página tarda 2,7 seg" ya no depende de si es "rápido" o "lento" son "2,7 seg", si hacemos un cambio y JMeter ofrece "2,9 seg", el cambio hace que el sistema responda más lento.

    Debemos tener en cuenta que JMeter no es un navegador y por lo tanto, no va a procesar los código JavaScript, me explico, JMeter no va a procesar los document.write del código HTML. Por ejemplo, el siguiente bloque de código no será interpretado por JMeter y por lo tanto, las latencias de render no se computarán.
    <script type='text/javascript'>new BannerManager('http://openads.test.com/').getBanner(106,'banner106',true,-1,false,'null');script>
    <script type='text/javascript'>new BannerManager('http://openads.test.com/').getBanner(107,'banner107',true,-1,false,'null');script>
      
    <script type="text/javascript">
         var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
         document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
    script>
    
    Una vez aclarado el funcionamiento de JMeter, vamos a ver cómo configurar una batería de pruebas para simular el acceso a nuestras webs.

    Instalación de JMeter
    JMeter es una aplicación Java y necesita de JVM 1.5+ para poder ejecutarse. La instalación simplemente es descomprimir el archivo tar.gz en la ubicación que nosotros queramos ($JMETER_HOME)

    Lanzar JMeter
    Antes de lanzar JMeter vamos a analizar si las pruebas que vamos a llevar a cabo van a ser muy complejas, ya que si así fuera, necesitaremos ampliar la memoria asignada por defecto a JMeter.

    JMeter se inicia con un tamaño máximo de memoria de 512Mb, y aunque en la mayoría de los casos es suficiente, yo suelo configurarlo para que abra con 1024Mb.

    Para modificar el parámetro de memoria, simplemente incluiremos una variable de entorno llamada JVM_ARGS donde se le asignan los parámetros de la máquina virtual, por ejemplo
    $ export JVM_ARGS="-server -Xms1024m -Xmx1024m"
    $ jmeter.sh
    También podemos editaremos el archivo $JMETER_HOME/bin/jmeter y cambiar el valor de HEAP para asignarle los valores que deseemos, en mi caso 1024m
    # This is the base heap size -- you may increase or decrease it to fit your
    # system's memory availablity:
    HEAP="-Xms1024m -Xmx1024m"
    Una vez configurado nuestro JMeter, ejecutaremos el script de arranque $JMETER_HOME/bin/jmeter.sh y se nos mostrará nuestro entorno de trabajo que se ve a continuación



    Como podemos observar, JMeter nos ofrece dos categorías dentro del árbol principal
    • Plan de Pruebas
    • Banco de Trabajo
    En esta primera parte, vamos a ver cómo configurar un nuevo plan de pruebas, y en la segunda parte veremos cómo podemos utilizar el Banco de Trabajo


    Nota: En JMeter no existe el botón Guardar y por lo tanto, cuando hagamos un "Focus Lost" del componente éste quedará guardado.

    Configurar un Nuevo Plan de Pruebas
    Lo primero que debemos hacer es añadir un Grupo de Hilos, para ello seleccionaremos Plan de Pruebas y haciendo click con el botón derecho Añadir->Grupo de Hilos. Esto representará a nuestros usuarios, es decir, si queremos comprobar cómo responde nuestro aplicativo con 50 usuarios concurrentes, en la propiedad Número de Hilos deberemos poner 50.

    Para establecer un Base Time Line debemos establecer el valor de Número de Hilos a 1, y Contador del Bucle a un valor superior a 1, de esta forma, podemos obtener la media de ejecución con un sólo usuario y, de esta forma, tomaremos este dato como nuestro punto de partida.
    Cuanto mayor sea el valor de Contador del Bucle mejor será la precisión, ya que obtendremos más muestras y por lo tanto la media será más realista.

    Ahora seleccionaremos nuestro Grupo de Hilos y con el botón derecho Añadir->Elementos de Configuración->Valores por Defecto para Petición HTTP. Esto nos permitirá incluir los valores generales de la petición como: Nombre del Servidor, Puerto, Protocolo y Encoding.

     Seleccionamos Grupo de Hilos y con el botón derecho Añadir->Muestreador->Petición HTTP y, como hemos introducido Valores por Defecto simplemente deberemos editar el valor de la propiedad Path.

    Por último, introduciremos un Listener que nos proporcionará los valores de la muestra, en este primer ejemplo vamos a introducir un Árbol de Resultados, para ello, seleccionaremos Grupo de Hilos y botón derecho Añadir->Listener->Ver Árbol de Resultados

    Ya sólo nos queda guardar la prueba, Archivo->Guardar Como ... y podemos ejecutarla utilizando el menú Lanzar->Arrancar y ver el resultado en Ver Árbol de Resultados.

    Como podéis ver, el funcionamiento de JMeter es sencillo y la creación de planes de pruebas no es muy complicado, en cuatro clicks hemos obtenido un plan de pruebas, sin embargo la información que obtenemos con este Sencillo Plan no nos aporta mucho, vamos a ver cómo hacer un plan más realista. Podéis descargar esta prueba sencilla de JMeter HTTP

    Instalar nuevo Listener

    Antes de comenzar con el plan de pruebas vamos a instalar un Listener que nos mostrará de forma gráfica, y más amena, el rendimiento y tiempo de respuesta de nuestro muestreador. Para ello, debemos descargar e instalar Better JMeter Graphs, después reiniciaremos el JMeter. Una vez hecho esto, tendremos un nuevo Listener llamado Statistical Aggregate Report

    Configurar un Plan de Pruebas Más "Complicado"
    Al igual que hemos hecho en la Prueba Sencilla de JMeter para HTTP añadiremos un Grupo de Hilos, añadiremos también Valores por Defecto para Petición HTTP, ahora viene algún cambio, seleccionamos Grupo de Hilos y con el botón derecho Añadir->Elemento de Configuración->Gestor de Cookies HTTP.

    Los usuarios no hacen siempre las mismas iteraciones, es decir, Home->Pagina1->Pagina2->Home, y por lo tanto, si queremos hacer un plan de prueba que pueda simular  a un usuario, debemos tener en cuenta esto, por ello, JMeter nos ofrece el Controlador Lógico Random Order, así que seleccionamos Grupo de Hilos y con el botón derecho del ratón Añadir->Controlador Lógico->Random Order.

    Ahora vamos a introducir los muestreadores HTTP dentro de nuestro controlador lógico, para ello, seleccionamos Controlador Random Order y con botón derecho Añadir->Muestreador->Petición HTTP y aquí pondremos la primera página. Deberemos repetir este proceso para todas las páginas que queremos muestrear.

    Por último, vamos a añadir nuestro Listener seleccionando Grupo de Hilos y con el botón derecho Añadir->Listener->Statistical Aggregate Report, guardamos la prueba y ejecutamos. Podéis descargar la Prueba JMeter HTTP Multiples Páginas


    Conclusión
    En esta primera parte hemos visto cómo movernos con JMeter y las opciones que nos aporta, además, tenemos el resultado en formato gráfico al incluir el listener alternativo.

    En la siguiente parte, veremos cómo podemos crear pruebas mucho más complejas y cómo establecer valores de control en los muestreadores

    Referencias

    domingo, 22 de noviembre de 2009

    Optimización de Aplicaciones Web en Solaris

    Introducción
    En esta serie de post's vamos a ver cómo podemos exprimir al máximo nuestros servidores Solaris, y con el apoyo de los programadores hacer que el rendimiento de nuestras aplicaciones Web se vea mejorado.

    Antes de comenzar, debemos hablar de las capas de optimización (tuning) que existen y la importancia de cada una.


    Uno de los errores mas comunes es creer que cambiando el Hardware se conseguirá el mayor rendimiento, por ejemplo, si tenemos una CPU cargada, se pone más CPU (por ejemplo el doble, pasamos de 4 a 8 CPU) y se espera que el rendimiento aumente en relación al incremento de potencia, ERROR.

    La capa HARDWARE es la que menos relación COSTE-RENDIMIENTO nos va a ofrecer, entonces por qué empezamos por el HARDWARE? Buena pregunta, la respuesta es muy sencilla: Es el cambio que menos trauma supone a los desarrolladores, y por lo tanto a los aplicativos. Si, es cierto, todos nos hemos encontrado en la situación de:

    Como arquitecto le explicas:
    • "Necesito que cambies la aplicación X para que haga Z y reduzcas el número de llamadas a DB haciendo F"
    Y la respuesta desde desarrollo es:
    • "Imposible, tenemos que tocar F,G,H, … mucho, mucho. Eso es problema de la máquina, el Software está súper optimizado"
    Bien, vamos a ver cómo podemos enfrentarnos a estas situaciones y salir airoso de ellas siguiendo unas pautas y mejoras en nuestras arquitecturas.

    En el primer post de la serie comenzaremos hablando de Cálculo de Rendimiento utilizando Apache JMeter y seguiremos con Parametrización de Apache para Cacheo de contenido, espero que os guste y mañana comenzaremos esta nueva serie.