Tag Archives: Cluster

Cluster con Hazelcast en Alfresco One 4.2.2

Si hay algo en lo que Alfresco ha trabajado en cada una de las versiones que han visto la luz ha sido el tema de cluster y la comunicación entre los nodos. En las versiones 2.x con EHCache y un sistema de multicast que era bastante pobre, usando JGroups en la 3.x hasta llegar a la 4.2.x con Hazelcast.

Pero, ¿qué es Hazelcast?

Es según la propia página web oficial un “Open Source In-Memory Data Grid”, es decir, una plataforma para la distribución de datos de código abierto. Entre sus características podemos encontrar:

  • Implementaciones distribuidas de Set, List, Map, Lock, MultiMap
  • Mensajería distribuida P/S
  • Soporte transaccional e integración JEE vía JCA
  • Soporte encriptación a nivel de sockets
  • Persistencia síncrona o asíncrona
  • Clusterizado Sesión HTTP
  • Discovery dinámico
  • Monitorización JMX
  • Escalado dinámico
  • Particionado dinámico
  • Fail-over dinámico

Como se puede ver, es una herramienta fantástica para cumplir las especificaciones de cluster que necesita Alfresco.

Las funciones de las que se sirve Alfresco y que son comunes a Hazelcast están:

  • Compartir datos/estados entre varios servidores: como compartición sesión Web
  • Cacheo distribuido de datos
  • Comunicación segura entre servidores
  • Particionado de datos en memoria
  • Distribución de trabajo entre servidores
  • Procesamiento paralelo
  • Gestión fail-safe de datos

Además se lleva muy bien con Hibernate como caché de segundo nivel y con Spring.

¿Cómo configuramos el cluster de Alfresco 4.2.2?

Para configurar un sistema de cluster en Alfresco 4.2.2 es tan fácil como cuando se configuraba con EHCache o JGroups e incluso más todavía y eso sí, se comprueba la fiabilidad que tiene este producto integrado en Alfresco.

Hay que entender que aquí explico solamente como montar el cluster, es decir, que ambos nodos se comuniquen entre sí, un sistema completo de alta disponibilidad requiere de un balanceador ya sea hardware o software, un sistema de cluster en la base de datos, etc.

Lo primero que hay que hacer es quitar cualquier referencia a EHCache y JGroups antiguos, esto va orientado a sistemas que han ido siendo actualizados desde versiones antiguas principalmente:

Por ejemplo, el fichero que está dentro de {alfrescoRoot}/tomcat/shared/clases/alfresco/extensión:

ehcache-custom.xml

También en dicha localización (si existe) el fichero:

hazelcastConfig.xml

Este fichero se ha incluido ya dentro del fichero alfresco.war con lo que no hace falta.

Así como las siguientes propiedades que están dentro de {alfrescoRoot}/tomcat/shared/clases/alfresco-global.properties:

alfresco.cluster.name
alfresco.ehcache.rmi.hostname
alfresco.ehcache.rmi.port
alfresco.ehcache.rmi.remoteObjectPort
alfresco.jgroups.defaultProtocol
alfresco.jgroups.bind_address
alfresco.jgroups.bind_interface
alfresco.tcp.start_port
alfresco.tcp.initial_hosts
alfresco.tcp.port_range
alfresco.udp.mcast_addr
alfresco.udp.mcast_port
alfresco.udp.ip_ttl
filesystem.cluster.enabled
filesystem.cluster.configFile

Configuración del cluster para el repositorio

Por defecto si apuntamos dos instancias de Alfresco al mismo repositorio y base de datos, estos formarán de forma automática un grupo de repositorio, no obstante hay que realizar una pequeña configuración para que todo funcione correctamente.

Montar el repositorio de forma compartida y visible para todos los nodos, por ejemplo vía NAS o SAN a través de protocolo NFS.

Configurar el acceso a la base de datos para la misma base de datos en cada uno de los nodos.

Abrir el puerto 5701 TCP en el cortafuegos de los nodos para que puedan ser accesibles entre ellos.

Especificar correctamente la IP (sea en wildcard como por ejemplo 192.168.1.*) de la tarjeta de red del cluster:

alfresco.cluster.interface=192.168.1.101

Fijar la propiedad para activar Hazelcast en JMX

hazelcast.jxm=true

Y por razones de seguridad se debería fijar la contraseña con la siguiente propiedad:

alfresco.hazelcast.password=

Un ejemplo de la parte del fichero alfresco-global.properties para la configuración del cluster puede ser la siguiente:

alfresco.cluster.enabled=true
alfresco.cluster.interface=192.168.1.101
alfresco.hazelcast.password=clavehazelcast
alfresco.hazelcast.port=5701
alfresco.hazelcast.autoinc.port=false
alfresco.hazelcast.mancenter.enabled=false
alfresco.hazelcast.max.no.heartbeat.seconds=15

Una vez arrancada la primera instancia se puede observar un mensaje como el siguiente:

2014-06-30 22:38:36,148 INFO [cluster.core.ClusteringBootstrap] [localhost-startStop-1] Cluster started, name: MainRepository-fea9ebdf-04f3-495e-9456-cf43c24b8e91
2014-06-30 22:38:36,152 INFO [cluster.core.ClusteringBootstrap] [localhost-startStop-1] Current cluster members:
192.168.1.101:5701 (hostname: alfnode1.localdomain)

Finalmente al arrancar el segundo en este se observará lo siguiente:

2014-07-02 10:58:12,108 INFO [cluster.core.ClusteringBootstrap] [localhost-startStop-1] Cluster started, name: MainRepository-fea9ebdf-04f3-495e-9456-cf43c24b8e91
2014-07-02 10:58:12,111 INFO [cluster.core.ClusteringBootstrap] [localhost-startStop-1] Current cluster members:
192.168.1.102:5701 (hostname: alfnode2.localdomain)
192.168.1.101:5701 (hostname: alfnode1.localdomain)

También se puede ver que el cluster está bien configurado mediante la nueva consola de administración cuya URL es:

http://
:8080/alfresco/service/enterprise/admin

En “Servicio de repositorio” y dentro de este en “Agrupación de servidores del repositorio” se puede ver toda la información del cluster, además se puede validar con el botón “Validar grupo” que realiza las comprobaciones necesarias para saber si ambos nodos se están comunicando correctamente:

Propiedades de Hazelcast

Todas las propiedades admitidas por Hazelcast en alfresco-global.properties son:

alfresco.cluster.enabled
Ejemplo: true
Descripción: Activa el cluster de Alfresco para este nodo

alfresco.cluster.interface
Ejemplo: 192.168.80.1
Descripción: Especifica la tarjeta de red usada para el cluster. Se puede usar tipo de dirección wildcard, por ejemplo 192.168.80.*

alfresco.cluster.nodetype
Ejemplo: NodoDesconectado001
Descripción: Especifica un nombre “amigable” para ese nodo del cluster, generalmente utilizado para servidores que se han unido al repositorio pero no forman parte del cluster (p.e. servidores de indexación)

alfresco.hazelcast.password
Ejemplo: mipasswd
Descripción: Define el password que usarán los nodos del cluster

alfresco.hazelcast.port
Ejemplo: 5701
Descripción: Establece el puerto de comunicación entre nodos del cluster

alfresco.hazelcast.autoinc.port
Ejemplo: false
Descripción: Realiza varios intentos de puertos para hayar uno libre desde la configuración alfresco.hazelcast.port. Alfresco no recomienda establecer esta propiedad

alfresco.hazelcast.mancenter.enabled
Ejemplo: false
Descripción: Activa las estadísticas y otros valores del cluster donde se puede acceder a través del Centro de gestión de Hazelcast

alfresco.hazelcast.mancenter.url
Ejemplo: http://localhost:8080/mancenter
Descripción: URL de acceso al centro de gestión de Hazelcast, evidentemente alfresco.hazelcast.mancenter.enabled debe estar en valor true

alfresco.hazelcast.max.no.heartbeat.seconds
Ejemplo: 15
Descripción: Tiempo máximo de monitorización para que se de por hecho que un nodo no está respondiendo

Configuración de Hazelcast en Share

En un entorno de cluster, Alfresco Share ahora utiliza Hazelcast para proporcionar mensajes entre los nodos de la capa web. Como resultado, las cachés ya no necesitan estar deshabilitadas para cualquier nodo. Cada uno funciona prácticamente tan rápido como una sola instancia de Share, mejorando así su rendimiento general.

Se pueden realizar dos configuraciones según las necesidades, con multicast o a nivel de TCP directo.

En todo caso, en balanceadores hay que seguir usando el sistema de Sticky-Session para funcionar correctamente. Hay que configurar correctamente el fichero share-config-custom.xml dentro de {extensionRoot}/alfresco/classes/web-extension poniendo correctamente el host y puerto de acceso al repositorio en caso necesario.

También hay que tener en cuenta que si se usa autenticación Kerberos o NTML con SSO las sesiones utilizarán la cookie JSESSIONID por lo que habrá que tenerla en cuenta por parte del balanceador.

Para esto hay que configurar el fichero custom-slingshot-application-context.xml
que hay en {extensionRoot}/alfresco/classes/web-extension (quitándole la extensión .sample)

Ejemplo para multicast:

 <!– Hazelcast distributed messaging configuration – Share web-tier cluster
    config (3.4.8 and 4.0.1) – see http://www.hazelcast.com/docs.jsp – and specifically
    http://www.hazelcast.com/docs/1.9.4/manual/single_html/#SpringIntegration –>
<!– Configure cluster to use either Multicast or direct TCP-IP messaging
    – multicast is default –>
<!– Optionally specify network interfaces – server machines likely to have
    more than one interface –>
<!– The messaging topic – the "name" is also used by the persister config
    below –>
<hz:topic id="topic" instance-ref="webframework.cluster.slingshot"
    name=”slingshot-topic” />

    
        
        
            
                <hz:multicast enabled="true" multicast-group="224.2.2.5"
                    multicast-port=”54327″ />
                
                    
                
            
            
                192.168.1.*
            
        
    

<bean id="webframework.slingshot.persister.remote"
    class=”org.alfresco.web.site.ClusterAwarePathStoreObjectPersister”
    parent=”webframework.sitedata.persister.abstract”>
    
    
        alfresco/site-data/${objectTypeIds}
    
    
    
        slingshot-topic
    

<bean id="webframework.factory.requestcontext.servlet" class="org.alfresco.web.site.ClusterAwareRequestContextFactory"
    parent=”webframework.factory.base”>
    
    
    
    

Ejemplo para conexión directa TCP:

<!– Hazelcast distributed messaging configuration – Share web-tier cluster
    config (3.4.8 and 4.0.1) – see http://www.hazelcast.com/docs.jsp – and specifically
    http://www.hazelcast.com/docs/1.9.4/manual/single_html/#SpringIntegration –>
<!– Configure cluster to use either Multicast or direct TCP-IP messaging
    – multicast is default –>
<!– Optionally specify network interfaces – server machines likely to have
    more than one interface –>
<!– The messaging topic – the "name" is also used by the persister config
    below –>
<hz:topic id="topic" instance-ref="webframework.cluster.slingshot"
    name=”slingshot-topic” />

    
        
        
            
                <hz:multicast enabled="false" multicast-group="224.2.2.5"
                    multicast-port=”54327″ />
                
                    alfnode1,alfnode2
                
            
            
                192.168.1.*
            
        
    

<bean id="webframework.slingshot.persister.remote"
    class=”org.alfresco.web.site.ClusterAwarePathStoreObjectPersister”
    parent=”webframework.sitedata.persister.abstract”>
    
    
        alfresco/site-data/${objectTypeIds}
    
    
    
        slingshot-topic
    

<bean id="webframework.factory.requestcontext.servlet" class="org.alfresco.web.site.ClusterAwareRequestContextFactory"
    parent=”webframework.factory.base”>
    
    
    
    

Centro de gestión Hazelcast (mancenter):

El centro de gestión Hazelcast (mancenter) permite monitorizar y administrar los servidores que ejecutan Hazelcast. Además, mancenter permite supervisar el estado general de los clústeres, y analizar y examinar las estructuras de datos en detalle.

Para instalarlo, se puede instalar tanto en un tomcat distinto como en el mismo de Alfresco. Solo hay que bajar una versión de Hazelcast (mancenter) y copiar el fichero mancenter-x.x.x.war al directorio de aplicaciones de tomcat.

Por ejemplo:

cp mancenter-2.4.1.war /opt/Alfresco422/tomcat/webapps/mancenter.war

Establecer la propiedad hazelcast.mancenter.home con el directorio donde se almacenan los datos, aquí se puede poner en la misma línea de opciones de Java (JAVA_OPTS), por ejemplo:

-Dhazelcast.mancenter.home=/opt/Alfresco422/tomcat/mancenter_data

Acordarse de activarlo en alfresco-global.properties:

alfresco.hazelcast.mancenter.enabled=true

Establecer la url de acceso, por ejemplo:

alfresco.hazelcast.mancenter.url=http://192.168.1.101:8080/mancenter

Por último, si se produce un error de serialización en el arranque, descomentar la siguiente línea en el contex.xml del servidor Tomcat:


 

Monitorización del funcionamiento de Hazelcast en Alfresco

La mejor forma como siempre es usando Log4j y para esto se puede usar la siguiente propiedad:

log4j.logger.org.alfresco.enterprise.repo.cluster=info

Para monitorizar la caché también se usan las siguientes propiedades:

log4j.logger.org.alfresco.enterprise.repo.cluster.cache=DEBUG
log4j.logger.org.alfresco.repo.cache=DEBUG

A nivel del propio Hazelcast:

log4j.logger.com.hazelcast=info

Y para aumentar el registro de seguimiento también se puede usar:

log4j.logger.com.hazelcast.impl.TcpIpJoiner=debug

Para finalizar

Las pruebas realizadas con un cluster de Alfresco One 4.2.2 usando Hazelcast han resultado ser muy satisfactorias, he realizado pruebas de subida de documentos, cambios de propiedades, etc. y eran instantáneas en ambos nodos.

Hay que tener en cuenta además que hay que configurar Solr (si se usa esta opción de indexado) correctamente para que se use de forma compartida, siempre y cuando no se utilize protocolo NFS para estos recursos compartidos de red ya que no está aconsejado. En este cado (uso de NFS) también se puede seguir usando una configuración similar a la que se utilizaba con Lucene, es decir, mantener índices locales por cada nodo.

Más información

http://docs.alfresco.com/4.2/concepts/ha-intro.html
http://hazelcast.org
http://unpocodejava.wordpress.com/2013/01/21/que-es-hazelcast/

Buenas prácticas en Alfresco ECM

Verión: 1 – Revisión: 0 – Publicación: 4/10/2011 – Última modificación: 4-oct-2011

Introducción
La instalación de Alfresco ECM requiere de una requisitos previos así como unas acciones posteriores para que el sistema comience a funcionar correctamente y se mantenga “sano” surante todo el tiempo que esté gestionando la documentación y registros. Este artículo pretende ser solamente un compendio de consejos y buenas prácticas y por tanto se irá modificando y ampliando en la medida de lo posible.

El ciclo de instalación, configuración y mantenimiento de Alfresco ECM comprende las siguientes fases:

Fase de preparación
1.    Diseñar tanto la arquitectura física como la arquitectura lógica antes de comenzar la instalación, si bien pueden usarse diagramas mixtos, es preferible realizar estos diseños por separado lo que nos dará también la posibilidad de generar lo sentregables para los distintos departamentos (comunicaciones y hardware, sistemas, etc.)
2.    Utilizar arquitecturas de 64 bits preferentemente, tanto a nivel de Hardware como Software (Sistema Operativo, Máquina Virtual de Java, etc.). Esto es muy importante en la medida en que en sistemas de 32 bits. se limita a nivel de direccionamiento de memoria principalemente.
3.    Usar procesadores de doble núcleo como mínimo y procesadores de 2,5GHz. en adelante.
4.    Usar la matriz de compatibilidad establecida por Alfresco para la instalación de todos los componentes: http://www.alfresco.com/services/subscription/supported-platforms/
5.    Adecuar la instalación a la arquitectura planteada y verificar la disponibilidad de recursos (NAS/SAN, SGDB,…) y que estos están disponibles, que son montados en el inicio de la máquina o al menos antes de arranque de Alfresco ECM.

Ejemplos (en Linux/Unix/MacOS X):
   Comprobar las unidades montadas para verificar su existencia: mount
   Verificar la correcta escritura: touch prueba

Comprobar que el servidor de la SGDB está funcionando: ping servidorsgdb
6.    Verificar la disponibilidad de los puertos que son necesarios para la instalación. Algunos puertos importantes para Alfresco son los siguientes:

  • a.    FTP: TCP 21 (se recomienda desconectar)
  • b.    SMTP: TCP 25
  • c.    SMB / NetBT: UDP 137,138, TCP 139,445 (para determinados entornos no es aconsejable)
  • d.    IMAP: TCP 143
  • e.    SharePoint Protocol: TCP 7070
  • f.    Tomcat Administration: TCP 8005
  • g.    HTTP: TCP 8080 (Tomcat, JBoss,…) / 9080 (para WebSphere) /…
  • h.    RMI: TCP 50500

Ejemplos (en Linux/Unix/MacOS X):
   Comprobar la existencia del puerto SMTP: telnet servidoralfresco 25
   Otra forma de comprobar que el puerto está abierto: nmap -P0 -p T:21,25,110,8080 servidoralfresco
   Puertos abiertos en el mismo servidor: netstat -putan

7.    Verificar la correcta comunicación tanto a nivel de fiabilidad como de estabilidad, verificar la latencia y rapidez de las transferencias:

  • a.    Conexión con el SGBD.
  • b.    I/O del disco que almacena los índices de Lucene.
  • c.    I/O del disco que almacena el repositorio.
  • d.    Conectividad entre los nodos (clúster).
  • e.    Conectividad con servidor NTP.

 Ejemplos (en Linux/Unix/MacOS X):
   Comprobar la transferencias a discos locales cada 2 segundos: iostat -w 2
   Visualizar las estadísticas de red cada 2 segundos: netstat -s -p tcp -w 2

8.    Comprobar la configuración con el SGDB con un DBA certificado así como la configuración del sistema de almacenamiento del repositorio con un experto certificado en el sistema de archivo usado (GFS, OCFS, VxFS, etc.). Es muy aconsejable que tanto la SGBD como el lugar donde se aloja el repositorio se conecten mediante “fibre channel” para evitar excesivas latencias y lentitud en las transacciones.
9.    Usar Alfresco Environment Validation Tool (Alfresco EVT) para validar el entorno (http://code.google.com/p/alfresco-environment-validation/)

Fase de instalación
1.    Crear una plantilla estándar adecuada al tipo de instalación y entorno con “checks” de control de las tareas. Es importante que los técnicos que instalen los sistemas, rellenen correctamente estas hojas e indiquen todas las incidencias que encuentran.

2.    Verificar los parámetros para la instalación, espacio disponible en discos, memoria RAM de los equipos y memoria Heap/Stack/Perm a usar para la JVM según el fabricante soportado (SUN, ORACLE, etc.), descriptores posibles, máximas conexiones del servidor de aplicaciones así como de firewalls y proxies puestos delante de Alfresco ECM.

Recomendaciones básicas de memoria para producción:
– Heap (-Xmx): 4G
– Pila (-Xss): 256k
– Perm (-XX:MaxPermSize): 256m

Ejemplos (en Linux/Unix/MacOS X):
   Kernel: uname -a
   Datos del sistema: cat /proc/cpuinfo
   Verificar memoria: free
   Procesos java arrancados: jps -v
   Procesos java arrancados: ps -fea | grep java

3.    Utilizar las recomendaciones de Alfresco para la ubicación de los archivos:

  • a.    ${TOMCAT_HOME}/shared/classes/extension/alfresco
  • b.    ${WEBSPHERE_HOME}/lib/alfresco
  • c.    ${JBOSS_HOME}/conf/alfresco

4.    NO incluir nunca ficheros de configuración en el despliegue de Alfresco ECM excepto por parte de módulos.
5.    Usar SIEMPRE módulos (mmt) para la instalación de nuevas funcionalidades, personalizaciones y configuraciones de Alfresco ECM.
6.    Usar las recomendaciones de Alfresco para la creación de ficheros de propiedades y XML y el uso de las normas estándar para la lectura de ficheros de configuración de Spring Framework.
7.    Puede utilizarse NFS con SAN para entornos clúster de repositorio compartido (solo a partir de la versión 3.4 según Alfresco) aunque es recomendable la utilización de sistemas de ficheros de clúster/concurrencia como GFS, OCFS, VxFS, etc.
8.    Los índices de Apache-Lucene deben ir siempre en el sistema local o en su defecto en NAS. A partir de la versión 4 de Alfresco ECM podrá utilizarse Solr.
9.    Es preferible tener en el “extension” una copia de log4j.properties como custom-log4j.properties para gestionar la salida de información de los logs.
10.    Aunque no es parte de Alfresco ECM, hay que medir cuidadosamente los aplicativos que interactúan con este respecto a seguridad:

  • a.    Uso de SSL (HTTPS) para asegurar canales de comunicación. Si es posible, también entre los propios elementos de Alfresco ECM, como Alfresco Share y el repositorio.
  • b.    Configuración de sistemas de autenticación externa mediante CAS, AD-Kerberos, NTLM, etc. y usar Single Sign On (SSO) en la medida de lo posible.
  • c.    Usar puertos por encima del 1024 y usuario “no root” en las instalaciones en sistemas Linux/Unix.

11.    No es recomendable balancear los protocolos TCP como CIFS/SMB, FTP y NFS que Alfresco ECM ofrece como servicios debido a problemas de bloqueos en JLan hasta aviso de Alfresco ECM y por lo menos hasta la versión actual (3.4.x). Sí es posible balancear HTTP/HTTPS y WebDAV. Una posible arquitectura siguiendo esta recomendación sería la siguiente:

12.    NO USAR JAMÁS EL USUARIO ROOT, crear un usuario tomcat, alfresco, jboss, etc. con los privilegios apropiados (acordarse de que en máquinas con Linux/Unix/MacOS X no pueden usarse puertos por debajo del 1024 por defecto).
13.    Es muy aconsejable que siempre se realicen 3 tipos de instalación, una para la parte de desarrollo y personalización, otra para preproducción o “Quality Service” que sirva para realizar pruebas antes de desplegar en producción, y una tercera instalación para producción. El entorno de desarrollo puede ser “no cluster” siempre y cuando no dependa dicho desarrollo de elementos própios de este. El entorno de preproducción y producción deben ser totalmente idénticos excepto en el tema de arquitectura hardware, es decir, puede ser un entorno con máquinas virtuales en preproducción y con máquinas físicas o virtuales con mayor asignación de recursos en producción. Así mismo, la carga de datos entre preproducción y producción tiene que ser lo más parecida posible, siempre al menos de un 50% de carga entre uno y otro para no tener problemas posteriores en cuanto a límites.

Fase de configuración y tuning
1.    Comprobar que la configuración de la codificación tanto en el SO, la SGDB, sistema de ficheros y JVM están en UTF-8. Ejemplos:

  • a.    En JVM de SUN y JRockit de IBM: -Dfile.encoding=UTF8
  • b.    En MySQL (my.cnf): default-character-set=utf8
  • c.    En Oracle, debe realizarlo un DBA.

2.    Usar autenticación con Single Sign On (SSO) en lo posible a través de AD-Kerberos o CAS siendo CAS el recomendable actualmente.
3.    Establecer los parámetros de monitorización en el arranque (JMX)
Ejemplo:
   Para monitorizar con jconsole: jconsole service:jmx:rmi:///jndi/rmi://servidoralfresco:50500/alfresco/jmxrmi
 
4.    Verificar parámetros de configuración y optimización del SGBD siempre a través de personal DBA certificado. Por ejemplo:

  • a.    MySQL: ANALYZE   
  • b.    PostgreSQL: VACUUM y ANALYZE
  • c.    Oracle: Dependiente de la versión, debe realizarse por un DBA.
  • d.    MS-SQL Server: ALTER INDEX REBUILD, UPDATE STATISTICS
  • e.    DB2: REORGCHK, RUNSTATS

5.    Utilizar los parámetros de optimización aconsejados por Alfresco:

  • a.    Ajustar pool de conexiones de Alfresco, se recomiendan 225 en adelante para el uso de protocolo CIFS/SMB. En WebSphere, Tomcat, Jboss, etc. Se pueden gestionar las conexiones a través de JNDI. En este caso, hay que tener en cuenta si el que controla los parámetros de conexiones máximas, mínimas, tiempos de espera para cierre de conexiones, etc. es Alfresco ECM o el mismo servidor de aplicaciones. Por ejemplo para WebSphere se pueden modificar los valores correspondientes desde la Consola de administración, en Recursos->JDBC->Orígenes de datos->(origen)->Propiedades de la agrupación de conexiones.

   db.pool.max=275

  • b.    Deshabilitar el uso de máximo de conexiones abiertas, es decir, no espera un tiempo en los que la conexión no responde para cerrarla. Igual que en el punto anterior, hay que modificarlo en la consola de administración de WebSphere o ficheros necesarios en otros servidores de aplicaciones.

   db.pool.idle=-1

  • c.    Esteblecer un tamaño de consultas (registros) mayor al establecido por defecto (10 registros).

   hibernate.jdbc.fetch_size=150

  • d.    Desactivar la parte de almacenamiento de transacción atómica para los índices y las transacciones de indexación “atómicas”, SOLO EN EL CASO DE IMPORTACIONES Y SUBIDAS MASIVAS DE DOCUMENTOS.

   lucene.maxAtomicTransformationTime=0
   index.tracking.disableInTransactionIndexing=true

  • e.    Si no se van a usar “quotas” de espacio, se aconseja desconectarlas ya que suponen tiempo de cálculo.

   system.usages.enables=false

  • f.    Usar JodConverter en lugar de la integración directa con OpenOffice.org deshabilitando esta última ya que si no Alfresco levantará dos instancias de OpenOffice.org. También es aconsejable usar un servidor independiente para realizar todas las conversiones.

   ooo.enabled=false
   jodconverter.enabled=true

  • g.    En clúster usar JGroups con conexiones TCP (para controlar mejor las conexiones).
  • h.    En clúster usar el “tracking” cada 5 segundos.

   index.tracking.cronExpression=0/5 * * * * ?

  • i.    En sistemas con muchos documentos y consultas Apache-Lucene muy genéricas, el resultado puede contener muchas filas y tardar mucho tiempo. Para evitar que salgan menos filas de las solicitadas hay que adaptar los parámetros system.acl.maxPermissionCheckTimeMillis y system.acl.maxPermissionChecks, pe. Para la salida de hasta 30000 filas cuya consulta dura menos de 5 minutos sería:

   system.acl.maxPermissionCheckTimeMillis=300000
   system.acl.maxPermissionChecks=30000

  • j.    Si es necesario indexar todo el contenido del documento y este tiene más de 10000 términos, hay que ajustar el valor lucene.indexer.maxFieldLength para que indexe todo el contenido. Por ejemplo, para que indexe contenidos con hasta 150000 palabras:

   lucene.indexer.maxFieldLength=150000

  • k.    Configurar correctamente y verificar su acceso a las utilidades utilizadas por Alfresco ECM:

   ImageMagick 
   Pdf2swf
   OpenOffice.org

  • l.    Realizar pruebas de carga y estrés antes de la puesta a producción mediante herramientas especializadas, p.e. JMeter.
  • m.    Adaptar valores de EHCache a los nodos, usuarios, permisos (ACLs), tickets de autenticación, etc. para que no se llene.

Desarrollo y personalización
Extensión del modelo de datos
1.    Usar la indexación por tokens en los casos necesarios, p.e. para metadatos que usan caminos, códigos o palabras sin significado semántico es mejor usar solamente la indexación por cadenas (strings).

Por ejemplo, si se tiene un metadato llamado “sección” que almacena una sección en particular como valor único, se podría definir como:


        d:text
       
        true
        false
        false
       
 

2.    Utilizar ficheros independientes por modelo de datos así como de prefijos para clarificar los desarrollos.
3.    NO usar nunca los modelos de ejemplo que vienen en Alfresco ECM.
4.    Es preferible usar Aspectos a Tipos e intentar crear tipos básicos heredados de los que Alfresco ECM incluye por defecto.
5.    Usar solamente los metadatos que van a ser usados en búsquedas en el gestor documental directamente y que tengan relevancia dentro de la gestión documental.
6.    Usar restricciones donde hagan falta (CONSTRAINTS) y reutilizarlas.
7.    Evitar en la medida de lo posible muchas asociaciones (ASSOCIATIONS), ya que Alfresco ECM no es un sistema relacional.
8.    No cambiar el modelo original de Alfresco ECM bajo ningún concepto.
9.    No eliminar modelos y aspectos si no se tiene total seguridad de que no han sido usados nunca.
10.    Evitar complejidades innecesarias en los modelos así como excesiva profundidad en la estructura.
11.    El modelo de datos dedicado a permisos y roles no puede ser movido del lugar del despliegue actualmente y hay que ser muy cauto a la hora de crear nuevos roles.
12.    Se aconseja no modificar los roles actuales.

Interoperabilidad
1.    Usar CMIS a través de RESTful principalmente (versión 3.4 en adelante) o en su defecto WebServices a través de SOAP para mantener la interoperabilidad, escalabilidad y estandarización.
2.    Comunicarse a través de aplicaciones mediante tecnologías SOA. Capas intermedias de middelware, buses de integración, fachadas de servicios y sistemas centralizados de control.
3.    Usar las AFC (Alfresco Foundation Classes) solo en casos muy específicos.
4.    Si es necesario personalizar/desarrollar directamente en Alfresco ECM, es preferible realizarlo a través de WebScripts, Reglas/Acciones y Workflows en lugar de desarrollar directamente clases Java.
5.    Es desaconsejado el uso de JCR ya que está obsoleto.

WebScripts/JavaScripts – Surf
1.    Incluir los ficheros de scripts en los lugares adecuados del extensión en lugar del despliegue o en su defecto crear un módulo de Alfresco ECM para instalarse de forma limpia usando el mmt (Module Management Tool) de Alfresco ECM.
2.    Usar librerías comunes mediante “includes” y reutilizar código.
3.    Realizar depuraciones mediante el depurador incluido en Alfresco ECM.
4.    Evitar mucha recursividad al recorrer nodos ya que puede llenar la memoria de pila, o bien, ampliar el espacio de esta en la configuración.
5.    Dirigir los desarrollos hacia la plataforma Spring-Surf.

WebServices
1.    Evitar la transferencia de grandes ficheros mediante mensajes SOAP. Usar para ello el Servlet que incorpora Alfresco ECM.
2.    Minimizar las transferencias de información en tareas reiterativas. Por ejemplo, es preferible la llamada a un WebScript que devuelva en formato JSON/Atom/Text la lista de usuarios que realizar N llamadas desde el WebService cliente.

Búsquedas y consultas
1.    Adecuar los motores de búsqueda de Alfresco ECM al tipo de consulta y resultado requerido XPath/Lucene/CMIS-SQL.
2.    Es recomendable ir hacia consultas vía CMIS (cmis-strict) para estandarizar lo máximo posible.
3.    Intentar optimizar las consultas Lucene/CMIS para que devuelva pocos resultados.

Autenticación y seguridad
1.    Usar alf_ticket como método de mantener sesiones autenticadas en lugar de el uso de autenticaciones usuario/contraseña contínuas, así como JSESSIONID para el caso de mantener rutas en balanceadores. Se recomienda legar el uso de autenticaciones a Alfresco ECM y sistemas dedicados a esta tarea como CAS, AD-Kerberos, etc.
2.    Almacenar los datos “sensibles” de forma “ofuscada” o encriptada.

Mantenimiento
1.    Monitorizar la JVM, Servidor de Aplicaciones y la instancia de Alfresco ECM mediante Jconsole/VisualVM, IBM WebSphere Console, etc.
2.    Realizar seguimientos de tráfico entre los componentes de Alfresco ECM (WebClients y Repositorio, Alfresco y SGBD, etc.) para detectar grandes cargas, tráfico alto y cuellos de botella usando comandos como ntop, iostat, netstat, etc.
3.    Reindexar todo cuando se hayan cambiado valores de configuración de Apache-Lucene así como si se detecta corrupción en los índices. Esto es muy importante para mantener estable el sistema. Se puede usar la consola de chequeo de índices de Alfresco ECM para reindexar por fechas, transacciones, etc. Por ejemplo: http://servidoralfresco:8080/alfresco/service/enterprise/admin/indexcheck
4.    Estudiar las salidas (logs) constantemente prestando especial atención a mensajes de aviso (Warnings) y errores (Errors) y filtrando convenientemente:

Ejemplo:
Salida controlada de errores de log en un WebSphere: tail -2000f /opt/WebSphere/AppServer70/profiles/AppSrv01/logs/alfresco/SystemOut.log | grep ” E “

5.    Utilizar herramientas como NAGIOS/ICINGA para monitorizar puertos, memoria, CPU, etc.
6.    Usar sistemas de mensajes SMS y alertas de seguimiento en los sistemas en producción.

Bibliografía
Documentos y libros
Título: Alfresco Day Zero Configuration Guide.pdf
Autor: Peter Monks

Título: Administering_an_Alfresco_Enterprise_3_4_0_Production_Environment.pdf
Autor: Alfresco

Título: Escalabilidad y tuning.pdf
Autor: Toni de la Fuente

Título: Scale your Alfresco Solutions. Architecture, Design and Tuning Best Practices
Autor: Gabriele Columbro

Titulo: Alfresco Developer Guide
Autor: Jeff Potts

Blogs:
http://www.blyx.com
http://www.fegor.com
http://ecmarchitect.com/

Webs:
http://docs.alfresco.com
http://www.juntadeandalucia.es/xwiki/bin/view/MADEJA/ArqSIAlfresco

Arquitectura(s) Cluster en Alfresco

Desde un punto de vista más teórico y funcional, dentro de los escenarios de posibles instalaciones en cluster de Alfresco ECM encontramos dos escenarios básicos, uno que utiliza repositorio por cada nodo y estos son sincronizados y la más usada actualmente, en la que se usa un repositorio común así como índices separados por cada nodo.

Dentro del segundo escenario, existe multitud de documentación sobre posibles arquitecturas de Alfresco ECM que podemos encontrar tanto en la documentación oficial de Alfresco (http://docs.alfresco.com) como en otros recursos tanto personales (http://blyx.com), como públicos (Junta de Andalucía, Ministerio de Justicia, etc.)

Pero generalmente, cuando se habla de arquitecturas en cluster para Alfresco, estas se limitan solo al producto en sí, es lógico pues Alfresco ECM es capaz de clusterizarse mediante el uso de EHCache y JGroups sin necesidad de más componentes.

Una posible arquitectura a desarrollar es la siguiente:

Se pueden observar varias capas o niveles en las cuales se pueden introducir de forma intermedia distintos elementos adicionales como nuevos balanceadores (hardware y software), firewalls, etc. según las necesidades de cada entorno.

Existen además varios tipos de usuarios, los usuarios externos o que acceden desde fuera de la organización, estos a su vez pueden ser usuarios “anónimos” o “autenticados” y también usuarios que son trabajadores de la organización y que deben tener los recursos como si estuvieran dentro de esta, incluidos los de administración.

Intranet Network: Es la red de intranet principal a través de la cual se conectan todos los usuarios. Generalmente es la red local de la empresa, bien, sementada, o por el contrario para un solo segmento p.e. 192.168.1.0/24 (Clase C). Los accesos a la mayoría de los protocolos por parte de los usuarios y concretamente a través de HTTP para el Share se realizan dentro de esta red. En algunos casos se puede segmentar esta para el uso de otros protocolos como CIFS pero requiere más complejidad de la que ya hay en sí misma.

Capa de WEB/Balanceo (1): Esta capa está planteada desde un doble punto de vista, por un lado es un servidor web (Apache) y por otro lado también es un balanceador software (Apache+mod_jk o Apache+mod_proxy) si bien también contempla el uso de alta disponibilidad por sí mismo (HA_Proxy) usando una IP “flotante” o virtual (192.168.1.100) a través de lo que se llama un Heartbeat (HB). De esta forma mantenemos la alta disponibilidad y sistema en “failover” para esa capa y usando un único punto de entrada para todos los usuarios.

Como esta capa es de entrada exclusiva por HTTP (Web y WebDAV), los accesos de otros protocolos que no pueden ser accedidos a través de Apache y el balanceo, como CIFS y FTP se realizarán directamente sobre la capa de aplicación.

Capa de presentación o FrontEnd (2): En esta capa se utiliza el servidor de aplicaciones como sistema de acceso al repositorio donde se instala Alfresco Share.

Esta capa puede contener también servidores HTTP como Apache para servir partes estáticas e incluso para balancear también hacia la siguiente capa (repositorio de Alfresco). En este diagrama no viene indicado para no complicar en exceso pero en muchas ocasiones es muy buena idea que también esta capa balancee e incluya un “Heartbeat” para mantener alta disponibilidad también en este punto.

Tampoco viene reflejado pero se da por supuesto que los servidores Tomcat están en cluster a nivel de servidor de aplicaciones, que , aunque esto no afecte directamente a Alfresco es una buena idea tener todas las capas también con sus propios métodos de redundancia y sincronización.

Capa de aplicaciones o repositorio (3): Aquí están localizados los repositorios o Alfresco Explorer, no los repositorios físicos que son más propios de la siguiente capa. Es decir, la instalación de Alfresco (sin Share) estaría en este sitio. Alfresco está configurado por JGroups como cluster y conectado su “Heartbeat” mediante una red propia para este que realiza la sincronización mediante TCP y RMI (EHCache).

Capa de persistencia y repositorio (4): Esta capa es la encargada de almacenar físicamente los ficheros/documentos en el sistema de ficheros así como toda la información asociada en la base de datos. Se da por supuesto que el almacenamiento está redundado mediante cabinas de discos así como de un sistema como Oracle RAC o MySQL Cluster NDB. Cada sistema tiene su propia subred que debería estar conectada por “fibra channel”.

Otros elementos: Como se ve en el diagrama de arquitectura, existen elementos que al no estar directamente conectados mediante HTTP ni tener posibilidad de balanceo además de por sus características de aplicaciones, se conectan directamente a uno de los nodos de Alfresco. Así mismo, algunos accesos (p.e. CIFS, etc.) se realizan al otro nodo en una forma de repartir la carga de estos sistemas que no son balanceables.

Estos elementos son usados en muchas ocasiones para inyección masiva de datos o bien para conectar aplicaciones como SAP, AutoCAD, etc.

Administration & Monitoring Network: Por último, se usa también una red aparte también para los administradores y para monitorización, de esta forma se aíslan estas transmisiones y evita mayor carga en la red.

Más información:

Trucos para mantener un cluster en WebSphere 7 con Alfresco 3.4.x

Para instalar Alfresco ECM 3.4.x en WebSphere 7, lo mejor es seguir el siguiente enlace: http://docs.alfresco.com/3.4/index.jsp?topic=%2Fcom.alfresco.Enterprise_3_4_0.doc%2Ftasks%2Falf-websphere-install.html

Si además creamos un clúster de nodos en el mismo WebSphere además de la configuración para Alfresco ECM mediante JGroups, tenemos todavía algunas cosas que el servidor de aplicaciones no controla. Una de ellas es el control de los ficheros de configuración, comunmente llamados “ficheros del extension” o extension/alfresco.

Esto es fácil si compartimos mediante NFS estos ficheros. Imaginemos que tenemos dos servidores, alfpru1 y alfpru2, en ambos hay una instalación de WAS 7 en: /opt/IBM/WebSphere/AppServer

En esta existe un directorio llamado lib donde generalmente se crea un directorio llamado alfresco y dentro de este se introducen los ficheros de configuración. Bien, solo hay que exportar el recurso en la máquina o cabina, en este caso es la misma máquina alfpru1 y en la misma localización por defecto (lo suyo es tener evidentemente una cabina de discos para esto):

El fichero /etc/exports tendrá la siguiente línea:

/opt/IBM/WebSphere/AppServer/lib/alfresco       alfpru2(rw,sync)

Además deberá exportar el recurso compartido para el repositorio, etc.

Bien, ahora en alfpru2 creamos un directorio alfresco dentro de /opt/IBM/WebSphere/AppServer/lib y montamos el recurso como:

mount alfpru1:/opt/IBM/WebSphere/AppServer/lib/alfresco /opt/IBM/WebSphere/AppServer/lib/alfresco

Y listo!!… bueno, no del todo. Resulta que hay un fichero llamado alfresco-global.properties que está en el mismo nivel que el directorio alfresco. Como no queremos (ni podemos) exportar todo el directorio lib, lo que se puede hacer es mover este fichero dentro de lib y crear dos enlaces simbólicos, uno en cada servidor, de esta forma:

En alfpru1:

mv alfresco-global.properties ./alfresco
ln -s alfresco/alfresco-global.properties .

En alfpru2 (después de haber montado el recurso):

ln -s alfresco/alfresco-global.properties .

Para prácticamente toda la configuración vale que se compartan los ficheros, en algún caso excepcional necesitaremos otros valores, en el caso además de subsistemas podrémos realizar este truco también de forma que parte esté como recurso compartido y parte no.

¿Replica la información de sesión Alfresco ECM en clúster?

Una de las críticas que más recibe Alfresco es que este no clona/replica las sesiones y variables asociadas, como por ejemplo la variable alf_ticket, por lo que en aplicaciones que llaman a nodos de un clúster de Alfresco se produce un error de autenticación.


Pero ¿es esto cierto?… bueno, creo que en parte si pero en parte no y por eso he realizado unas pruebas.

Una solución realizada hasta ahora era la de configurar en el balanceador lo que se llaman sesiones “sticky” que usan una variable de sesión como JSESSIONID para dirigir todas las peticiones de esa sesión al mismo nodo. De esta forma, al ser siempre el mismo nodo quien recibe las peticiones y tener la información del ticket de validación correcta no hay problemas.

Esta solución es válida para aplicaciones que usan sesiones, pero ¿que ocurre si una aplicación no las usa?, como el balanceador no sabe a donde dirigirlo porque no tiene esta información puede dirigirlo siempre al mismo nodo, lo que sería un mal menor, o redirigir a uno u otro nodo indistintamente, lo que provoca el error.

Bien, vamos a comprobar que Alfresco ECM versión 3.3.4 si clona al menos la información del ticket de autenticación para que cuando se entra en cualquier nodo usando un ticket de validación válido, Alfresco permite la entrada.

Lo primero es configurar correctamente el cluster de Alfresco ECM. En mi caso esta es la información de alfresco-global.properties:

alfresco.cluster.name=alfprucluster
alfresco.jgroups.defaultProtocol=TCP
alfresco.tcp.initial_hosts=alfpru1[7800],alfpru2[7800]

Además de renombrar el fichero ehcache-custom.xml.sample.cluster como ehcache-custom.xml

Creamos el fichero para probar el acceso entre los nodos usando la variable alf_ticket y sin usarla (o usando si quieremos una ficticia no válida)

Fichero: prueba_auth_cluster.sh

#!/bin/bash

ALF_USER=admin
ALF_PASSWD=admin
ALF_NODE1=alfpru1:8080
ALF_NODE2=alfpru2:8080
ALF_SEARCH_TERM=readme.ftl
ALF_ROOT=Company%20Home

echo “AUTENTICACION Y RECOGIDA DEL TICKET EN EL PRIMER NODO.”
ALF_TICKET=`curl “http://${ALF_NODE1}/alfresco/service/api/login?u=${ALF_USER}&pw=${ALF_PASSWD}” | grep TICKET_ | sed ‘s:::g’ | sed ‘s:::g’ | tr -d ‘r’`

echo “BUSCAR EN EL PRIMER NODO USANDO EL TICKET DE AUTENTICACION DEL PRIMER NODO.”
curl “http://${ALF_NODE1}/alfresco/service/api/search/keyword.text?q=${ALF_SEARCH_TERM}&p=${ALF_ROOT}&c=1&l=es&alf_ticket=${ALF_TICKET}”

echo “BUSCAR EN EL SEGUNDO NODO USANDO EL TICKET DE AUTENTICACION DEL PRIMER NODO.”
curl “http://${ALF_NODE2}/alfresco/service/api/search/keyword.text?q=${ALF_SEARCH_TERM}&p=${ALF_ROOT}&c=1&l=es&alf_ticket=${ALF_TICKET}”

echo “BUSCAR EN EL SEGUNDO NODO SIN USAR EL TICKET DE AUTENTICACION DEL PRIMER NODO.”
curl “http://${ALF_NODE2}/alfresco/service/api/search/keyword.text?q=${ALF_SEARCH_TERM}&p=${ALF_ROOT}&c=1&l=es”

Una vez configurado todo y arrancados ambos nodos de Alfresco, ejecutamos el script.

La salida en mi caso ha sido la siguiente:

./prueba_auth_cluster.sh
AUTENTICACION Y RECOGIDA DEL TICKET EN EL PRIMER NODO.
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   106    0   106    0     0     10      0 –:–:–  0:00:10 –:–:–    31
BUSCAR EN EL PRIMER NODO USANDO EL TICKET DE AUTENTICACION DEL PRIMER NODO.
readme.ftl
BUSCAR EN EL SEGUNDO NODO USANDO EL TICKET DE AUTENTICACION DEL PRIMER NODO.
readme.ftl
BUSCAR EN EL SEGUNDO NODO SIN USAR EL TICKET DE AUTENTICACION DEL PRIMER NODO.
Apache Tomcat/6.0.18 – Informe de Error

Estado HTTP 401 –


type Informe de estado

mensaje

descripci�n Este requerimiento requiere autenticaci�n HTTP ().


Apache Tomcat/6.0.18

Que demuestra efectivamente que con el ticket obtenido en la autenticación del primer nodo, nos sirve para usarlo con el segundo. Además se realiza otra llamada sin usar el ticket para afirmar esta prueba ya que de esta forma sí debe salir un error.

Ahora vamos a eliminar el clúster, de forma que no se comuniquen los nodos entre sí y no pasen la información. Para ello quitamos las líneas de configuración del clúster de alfresco-global.properties y volvemos a ejecutar el script, el resultado, obviamente será el siguiente:

./prueba_auth_cluster.sh

AUTENTICACION Y RECOGIDA DEL TICKET EN EL PRIMER NODO.
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   106    0   106    0     0    182      0 –:–:– –:–:– –:–:–     0
BUSCAR EN EL PRIMER NODO USANDO EL TICKET DE AUTENTICACION DEL PRIMER NODO.
readme.ftl
BUSCAR EN EL SEGUNDO NODO USANDO EL TICKET DE AUTENTICACION DEL PRIMER NODO.
Apache Tomcat/6.0.18 – Informe de Error

Estado HTTP 401 –


type Informe de estado

mensaje

descripci�n Este requerimiento requiere autenticaci�n HTTP ().


Apache Tomcat/6.0.18

BUSCAR EN EL SEGUNDO NODO SIN USAR EL TICKET DE AUTENTICACION DEL PRIMER NODO.
Apache Tomcat/6.0.18 – Informe de Error

Estado HTTP 401 –


type Informe de estado

mensaje

descripci�n Este requerimiento requiere autenticaci�n HTTP ().


Apache Tomcat/6.0.18

Por tanto, como puede observarse Alfresco ECM sí funciona correctamente como un clúster. Hay que indicar también que sigue siendo necesario (a mi entender) el uso de las Sticky Sessions para controlar mejor el tráfico a través del balanceador.

También se ha probado a recoger el ticket del primer nodo, parar este nodo y acceder con el resultado del ticket al segundo funcionando correctamente también.

Pero ¿que pasa entonces con las interfaces web?, bien, tanto el Explorer como Share, así como todas las interfaces que se desarrollen deberán controlar al menos el uso de la variable alf_ticket para que ninguno de los nodos reciba un ticket de validación erróneo o no lo reciba ya que de esta forma volverá a solicitar el inicio de sesión. Esto no es un problema del clúster en sí, si no de las interfaces de usuario y como he podido comprobar, en este caso ambas fallan cuando no tienen activadas las Sticky Sessions porque al parecer no pasan entre las peticiones (GET y POST) la variable alf_ticket. Según Alfresco, en la versión 3.4.3 esto estará solucionado.

NOTA: He usado el WebScript de búsqueda y que realiza una salida en texto de mi post http://www.fegor.com/2011/05/calculando-metricas-en-alfresco.html al que he declarado como autenticado mediante usuario user”.