Configurando el pool dbcp de OpenCms

08/03/2012       Francisco Fuentes       Administración, OpenCms, Programación, Manuales y tutoriales

En este caso, una de las cosas que podemos solucionar es mejorar el rendimiento del pool dbcp de base de datos, ajustando los parámetros de este. Tal y como viene configurado de casa puede dar problemas dependiendo del entorno donde este se encuentre. Lo mejor para decidir si realizar estos ajustes es conveniente es echar a rodar la aplicación. Si esta se degrada fácilmente (tras mucho tiempo arrancada la aplicación en el servidor, deja de funcionar, o los tiempos de respuesta empeoran) y/o crea muchas conexiones de base de datos, o sencillamente tienes que reiniciar la aplicación muy de vez en cuando, es posible que este ajuste sea beneficioso.

El pool de conexiones que utiliza OpenCms es el Apache commons dbcp, el cual no es precisamente el mejor pool java que existe (no es multihilo, es pesado, etc...), pero es funcional y es el que viene. Se configura en el archivo de configuración {CONTENEDOR_SERVLETS}/opencms/WEB-INF/config/opencms.properties.

Para ajustar estos parámetros, primero estaría bien conocer el funcionamiento básico de este pool. Un pool de conexiones no es más que un determinado conjunto de conexiones a un esquema de base de datos, que son mantenidas por un conjunto de clases java, quedando de esta manera desacoplada la gestión de conexiones de otras capas de la aplicación. Estas clases java se encargan crear conexiones, de mantener un número de conexiones en espera, comprobar que estas funcionan antes de entregarselas a nuestra aplicación cuando esta las pida, aumentar el número de conexiones si es necesario, y cerrar las conexiones que se mantengan inactivas durante mucho tiempo.

Los parámetros más relevantes son:

  • testQuery : Sentencia sql que sirve para comprobar una conexión y determinar si sirve o no. Ha de ser una sentencia sencilla y que no consuma muchos recursos, en el pool por defecto suele venir algún ejemplo.
  • whenExhaustedAction : Cuando el pool no tenga más conexiones disponibles, que accion tomar. Tenemos 3 opciones: Grow (aumentar el tamaño de conexiones disponibles), Block (no se crean más conexiones, pero no provoca excepciones), Fail (provoca una excepción cuando esto ocurre).
  • timeBetweenEvictionRuns : Determina en milisegundos el tiempo que pasará hasta que se ejecute el hilo que se encarga de podar las conexiones innecesarias (Evictor thread).
  • numTestsPerEvictionRun : El número de conexiones a testear por el el evictor thread cada vez que se ejecute.
  • minEvictableIdleTime : El tiempo que ha de pasar desde que una conexión está ociosa hasta que esta sea considerada como "podable" por el evictor thread.
  • maxActive : El máximo número de conexiones que pueden ser usadas del pool por la aplicación.
  • minIdle : El mínimo de conexiones que permanecerán activas en el pool.
  • maxIdle : El máximo de conexiones inactivas que puede tener el pool.

Como referencia y para más información, los parámetros de configuración del commons dbcp están explicados de forma pormenorizada aquí: http://commons.apache.org/dbcp/configuration.html

La configuración del pool que viene de casa con OpenCms es bastante conservadora, tiende a crear muchas conexiones y a destruir muy pocas, por ejemplo; el parámetro timeBetweenEvictionRuns es 3600000 ms, o lo que es lo mismo, una hora, el parámetro numTestsPerEvictionRun está puesto a 3 por lo cual solamente se prueban 3 conexiones cada hora, mientras que si el pool se agota, la acción a tomar es aumentar el número de conexiones. Con una configuración así, las conexiones crecerán más rápidamente y se eliminarán en menor medida.

Para solucionar esto, una de las estrategias que podemos seguir es disminuir el tiempo de espera del evictor thread (timeBetweenEvictionRuns), aumentar el número de conexiones que se probarán (numTestsPerEvictionRun) y disminuir el tiempo de espera entre que una conexión permanece inactiva y pasa a ser candidata de la poda (minEvictableIdleTime). Una posible configuración sería entonces:

  • db.pool.default.timeBetweenEvictionRuns=360000
  • db.pool.default.numTestsPerEvictionRun=10
  • db.pool.default.minEvictableIdleTime=180000

Hemos reducido los tiempos 10 veces (ahora el evictor thread se ejecuta cada seis minutos), y en vez de probar 3 conexiones probamos 10. Esto hará que el pool tenga un número de conexiones más ajustado a lo que necesita en cada momento, ya que si por ejemplo, recibiéramos un alto tráfico y el número de conexiones creciera drásticamente, sería al poco tiempo cuando se comprobaría si son necesarias esas conexiones. Solamente con este ajuste ya se nota en el número de conexiones. En la práctica, en un portal implementado con OpenCms pasamos de unas 500 conexiones a base de datos a unas 60 (cifras aproximadas).

Ajustar los otros parámetros mentados anteriormente también tiene sus beneficios, pero son parámetros cuyo ajuste es más dependiente de la aplicación, y del número de conexiones que se usen, etc.