Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

patrones:pool_conexiones [2013/04/20 13:04]
admin [Pool de conexiones]
patrones:pool_conexiones [2016/09/27 09:43] (actual)
admin [Configurando el pool de conexiones en Tomcat 7]
Línea 1: Línea 1:
 ====== Pool de conexiones ====== ====== Pool de conexiones ======
-El pool de conexiones es una técnica usada en aplicaciones Web para mejorar el rendimiento de éstas.+El pool de conexiones es una técnica usada en aplicaciones Web para mejorar el rendimiento de las aplicaciones Web.
  
-Antes de ver en que consiste veamos como funciona la creación de conexiones en una aplicación clásica de escritorio cliente-servidor y luego veamos los problemas se seguir con dicha estructura en una aplicación web.+Antes de ver en que consiste veamos como funciona la creación de conexiones en una aplicación clásica de escritorio cliente-servidor y luego veamos los problemas se seguir con dicha estructura en una aplicación web.
  
 ===== Problemas en la creación de conexiones ===== ===== Problemas en la creación de conexiones =====
-En una aplicación de escritorio se crea una conexión de base de datos al iniciar la aplicación y se cierra al finalizar la aplicación. Es decir que cada usuario que inicia la aplicación tiene una conexión en exclusiva para él. Y obviamente sería imposible de compartirlas ya que cada aplicación estará en un ordenador independiente.+En una aplicación de escritorio se crea una conexión de base de datos al iniciar la aplicación y se cierra al finalizar la aplicación. Es decir que cada usuario que inicia la aplicación tiene una conexión en exclusiva para él. Y obviamente sería imposible compartirlas ya que cada aplicación estará en un ordenador independiente.
  
-En una aplicación Web podríamos seguir un esquema similar , en el que cada usuario nuevo que se conecta a nuestra aplicación se le crea una conexión y al salir de la aplicación que se cierre la conexión.+En una aplicación Web podríamos seguir un esquema similar , en el que cada usuario nuevo que se conecta a nuestra aplicación se le crea una conexión y al salir de la aplicación que se cierre su conexión.
  
 Esto que aparentemente es sencillo tiene unos problemas debido a la diferente naturaleza de las aplicaciones de escritorio y las web. Esto que aparentemente es sencillo tiene unos problemas debido a la diferente naturaleza de las aplicaciones de escritorio y las web.
Línea 13: Línea 13:
 ^ Característica ^  Escritorio ^  Web ^  Problemas  ^ ^ Característica ^  Escritorio ^  Web ^  Problemas  ^
 | Número de usuarios | Bajo. Suele estar limitado por el tamaño de una oficina o edificio. | Muy alto. Potencialmente toda internet. | En la Web si cada usuario tiene una conexión propia para él se podría saturar el servidor de base de datos | | Número de usuarios | Bajo. Suele estar limitado por el tamaño de una oficina o edificio. | Muy alto. Potencialmente toda internet. | En la Web si cada usuario tiene una conexión propia para él se podría saturar el servidor de base de datos |
-| Momento de cierre de la conexión | Claramente definido al cerrar la aplicación | Vagamente definido | En Web es complejo saber cuando el usuario abandona el portal (que no la página) para en ese momento cerrar la página |+| Momento de cierre de la conexión | Claramente definido al cerrar la aplicación | Vagamente definido | En Web es complejo saber cuando el usuario abandona el portal (que no la página) para en ese momento cerrar la conexión |
  
 Si siguiéramos el mismo patrón de creación de conexiones de aplicaciones de escritorio en aplicaciones web acabaríamos con una cantidad enorme de conexiones activas (debido al gran número de usuarios) y con gran cantidad de conexiones abiertas sin usar (debido a usuarios que abandonan el portal y no lo hemos detectado) Si siguiéramos el mismo patrón de creación de conexiones de aplicaciones de escritorio en aplicaciones web acabaríamos con una cantidad enorme de conexiones activas (debido al gran número de usuarios) y con gran cantidad de conexiones abiertas sin usar (debido a usuarios que abandonan el portal y no lo hemos detectado)
Línea 19: Línea 19:
 Consecuencia de los anterior al tener tantas conexiones a la base de datos se acabaría cayendo el servidor de base de datos debido a los recursos consumidos por todas las conexiones. Consecuencia de los anterior al tener tantas conexiones a la base de datos se acabaría cayendo el servidor de base de datos debido a los recursos consumidos por todas las conexiones.
  
-Podemos pensar que nuestro servidor puede aguantar todas esas conexiones debido que tenemos pocos usuarios pero no suele ser así debido a: +Podemos pensar que nuestro servidor puede aguantar todas esas conexiones ya que podemos tener pocos usuarios pero no suele ser así debido a: 
-  * Si no se cierran las conexiones aun teniendo pocos usuarios se llenaría de conexiones sin usar. +  * Si no se cierran las conexiones aun teniendo pocos usuarios es probable que acabemos saturando al servidor de conexiones sin usar. 
-  * Las aplicaciones Web pueden tener picos de mucho tráfico (como las épocas de matriculación) donde se excedería la capacidad de nuestro servidor. +  * Las aplicaciones Web pueden tener picos de mucho tráfico (como en las épocas de matriculación) donde sería normal que se excediera la capacidad de nuestro servidor. 
-  * Sería muy sencillo hacernos un ataque de denegación de servicio y tumbarnos el servidor haciéndonos que creáramos gran cantidad de conexiones que no se usaran.+  * Sería muy sencillo hacernos un ataque de denegación de servicio y saturando el servidor haciendo que se crearan gran cantidad de conexiones que no se usen.
  
-Una solución **chapuza** que nos evitaría las conexiones sin usar sería creara la conexión al iniciar cada petición web y cerrarla al finalizar dicha petición web. ¿El problema de eso? Crear y cerrar una conexión es muy costoso. Lo que tendríamos es una aplicación lentísima.+Una solución **chapuza** que nos evitaría las conexiones sin usar sería que se creara la conexión al iniciar cada petición web y se cerrara al finalizar dicha petición web. ¿El problema de eso? Crear y cerrar una conexión es muy costoso. Lo que tendríamos es una aplicación lentísima.
  
 ===== Pool de conexiones ===== ===== Pool de conexiones =====
-La solución del pool de conexiones tiene que solucionar dos problemas:+La solución del pool de conexiones tiene que solucionar los siguientes problemas:
   * No tener tantas conexiones como usuarios ya que el nº de usuarios es demasiado elevado.   * No tener tantas conexiones como usuarios ya que el nº de usuarios es demasiado elevado.
   * Cerrar la conexión.   * Cerrar la conexión.
Línea 35: Línea 35:
 Así que por fin pasemos a explicar en que consiste el pool de conexiones: Así que por fin pasemos a explicar en que consiste el pool de conexiones:
  
-El pool de conexiones consiste en tener un conjunto (pool) de conexiones a la base de datos que puedan ser reutilizadas entre distintas peticiones.+El pool de conexiones consiste en tener un conjunto (pool) de conexiones ya conectadas a la base de datos que puedan ser reutilizadas entre distintas peticiones.
  
 Veamos como funciona: Veamos como funciona:
-  * El servidor web tiene "n" conexiones ya creadas y conectadas a la base de datos (El pool de conexiones). +  * El servidor web tiene "n" conexiones ya creadas y conectadas a la base de datos (Se llaman conexiones esperando
-    * Cuando llega una petición web la aplicación pide una conexión al pool de conexiones,quedando libre en el pool "n-1" conexiones. Esta operación es muy rápida ya que la conexión ya está creada y solo hay que marcarla como que alguien la está usando. +    * Cuando llegan "m" peticines web la aplicación pide "m" conexiones al pool de conexiones,quedando esperando en el pool "n-m" conexiones. Esta operación es muy rápida ya que la conexión ya está creada y solo hay que marcarla como que alguien la está usando. Ahora hay "m"  conexiones activas que está usando la aplicación
-    * Cuando la petición web finalizala conexión no se cierra sino que se devuelve al pool indicándole que ya se ha acabado de usar la conexión. Ahora vuelve a quedar "n" conexiones libres en el pool. Esta operación también es muy rápida ya que realmente no se cierra sino que simplemente se marca como que ya no la está usando nadie. +    * Cuando las peticiones web finalizanlas conexiones no se cierran sino que se devuelven al pool indicándole que ya se han acabado de usar las conexiones. Ahora vuelve a quedar "n" conexiones esperando en el pool. Esta operación también es muy rápida ya que realmente no se cierra ninguna conexión sino que simplemente se marcan como que ya no las están usando nadie. 
-  * Si se pide más conexiones de las que hay en el pool se creará en ese instante una nueva conexión hasta el máximo de conexiones que permita el pool +  * Si se piden más conexiones de las que hay esperando en el pool se crearán en ese instante nuevas conexiones hasta el máximo de conexiones que permita el pool 
-  * Al devolver una conexión al pool se queda libre para que otra petición la pueda usar. Si hay ya demasiadas conexiones esperando a ser usadas se cerrarán para ahorrar recursos en el servidor de base de datos.+  * Al devolver una conexión al pool , ésta se queda esperando para que otra petición la pueda usar. Si hay ya demasiadas conexiones esperando a ser usadas se cerrarán para ahorrar recursos en el servidor de base de datos.
  
  ¿Que hemos conseguido con el pool?  ¿Que hemos conseguido con el pool?
-  * Ahora las conexiones ya no se quedarán abiertas cuando el usuario se marcha del portal ya que cada conexión se //pseudoabre// y //pseudocierra// con cada petición. +  * Ahora las conexiones ya no se quedarán abiertas cuando el usuario se marcha del portal ya que cada conexión se //pseudo-abre// y //pseudo-cierra// con cada petición. 
-  * No tenemos tantas conexiones como usuarios usan la aplicación ya que solo se necesitan tantas como usuarios hay haciendo una petición en ese instante. Pensemos por un momento en facebook. ¿cuandos usuarios están conectados a facebook? Supongamos "n". Pero ¿cuantos están realmente haciendo una petición y no viendo los datos que se han servido? Supongamos "m". Obviamente "m" es mucho menor que "n". Con lo que nos hemos ahorrado "n-m" conexiones.+  * No tenemos tantas conexiones como usuarios usan la aplicación ya que solo se necesitan tantas como usuarios hay haciendo una petición en ese instante. Pensemos por un momento en facebook. ¿cuandos usuarios están conectados a facebook? Supongamos "x". Pero ¿cuantos están realmente haciendo una petición y no viendo los datos que se han servido? Supongamos "y". Obviamente "y" es mucho menor que "x". Con lo que nos hemos ahorrado "x-y" conexiones.
  
-En la siguiente gráfica vemos como evolucionan las conexiones de una aplicación web:+==== Ejemplo de Pool ==== 
 +Veamos ahora un ejemplo de uso de un pool de conexiones que ha sido configurado de la siguiente forma: 
 +  * Máximo de conexiones: 200 
 +  * Maximo de conexiones esperando: 50 
 + 
 +En la siguiente gráfica vemos un ejemplo de como podrían evolucionan las conexiones del pool:
  
 {{:patrones:pool.png|}} {{:patrones:pool.png|}}
-^ Tiempo (s) ^ Maximo ^ Activas ^ Esperando ^ 
  
 +^ Tiempo (s) ^ Maximo ^ Activas ^ Esperando ^ 
 |10 | 200 | 100 | 50 |  |10 | 200 | 100 | 50 | 
 |20 | 200 | 120 | 30 |  |20 | 200 | 120 | 30 | 
Línea 62: Línea 67:
 |80 | 200 | 70 | 80 |  |80 | 200 | 70 | 80 | 
 |90 | 200 | 70 | 50 |  |90 | 200 | 70 | 50 | 
-|100 | 200 | 110 10 |  +|100 | 200 | 150 |  
-|110 | 200 | 110 | 50 | +|110 | 200 | 150 | 50 |  
 +|120 | 200 | 90 | 110 |  
 +|130 | 200 | 90 | 50 |  
 + 
 + 
 +En la gráfica podemos ver como el máximo de conexiones que puede haber es 200 y por lo tanto de usuarios activos es de 200. Este valor es constante ya que es tal y como hemos configurado el pool. Eso no quiere decir que no pueda haber mas usuario reales en ese momento siempre y cuando estén mirando su navegador y no actuando con el servidor. 
 +También se ve como a lo largo del tiempo va variando el nº de usuarios activos, sin llegar nunca a 200. 
 + 
 +En el instante 60 bajan bruscamente el nº de conexiones activas de 140 a 100 por lo que se quedan 90 conexiones esperando, como son demasiadas el propio pool desconecta conexiones y en el instante 70 vuelven a ser solo 50 las conexiones esperando a ser usadas. Lo mismo pasa en el instante 80. 
 + 
 +En el instante 100 hay una fuerte subida de conexiones activas y no hay suficientes esperando para absorber la subida de usuarios, asi que en ese caso se deben crear 30 nuevas conexiones. Esto hará que se deban esperar un poco los 30 usuarios que les toque la creación de la conexión.Sin embargo en el instante 120 hay una caída brusca de usuarios con lo que vuelven a sobrar conexiones esperando. En ese caso se da la curiosidad de que hay mas conexiones esperando (110) que activas (90). En el siguiente instante (110 s) vemos como el pool ha cerrado conexiones para volver a tener las 50 con las que ha sido configurado.
  
  
Línea 83: Línea 98:
 InitialContext initCtx=new InitialContext();;                         InitialContext initCtx=new InitialContext();;                        
 Context envCtx = (Context) initCtx.lookup("java:comp/env"); Context envCtx = (Context) initCtx.lookup("java:comp/env");
-DataSource ds = (DataSource)envCtx.lookup("jdbc/hibernate1"); +DataSource dataSource = (DataSource)envCtx.lookup("jdbc/hibernate1");
 </code> </code>
  
 Siendo ''jdbc/hibernate1'' el nombre del pool de conexiones. Siendo ''jdbc/hibernate1'' el nombre del pool de conexiones.
- 
 ===== Configurando el pool de conexiones en Tomcat 7 ===== ===== Configurando el pool de conexiones en Tomcat 7 =====
 Por último nos queda configurar el pool de conexiones. Cada servidor web puede usar su propia implementación del pool de conexiones y se configura de forma específica. Nosotros vamos a explicar como configurar el pool que viene incluido en Tomcat 7. Por último nos queda configurar el pool de conexiones. Cada servidor web puede usar su propia implementación del pool de conexiones y se configura de forma específica. Nosotros vamos a explicar como configurar el pool que viene incluido en Tomcat 7.
Línea 122: Línea 136:
 Hasta ahora solo hemos indicado los atributo básicos de conexión a la base de datos, veamos ahora los atributos concretos del pool: Hasta ahora solo hemos indicado los atributo básicos de conexión a la base de datos, veamos ahora los atributos concretos del pool:
   * El atributo 'maxActive' de la línea 12 indica el número máximo de conexiones que pueden usarse. Esto indicará el nº máximo de usuarios que podrá haber a la vez haciendo peticiones.Si hay más usuarios se producirá un error indicando que ya no hay conexiones.   * El atributo 'maxActive' de la línea 12 indica el número máximo de conexiones que pueden usarse. Esto indicará el nº máximo de usuarios que podrá haber a la vez haciendo peticiones.Si hay más usuarios se producirá un error indicando que ya no hay conexiones.
-  * El atributo 'maxIdle' de la línea 13 indica el número máximo de conexiones libres que puede haber esperando a que llegue un usuario para usarlas. Si hay demasiadas conexiones libres Tomcat empezará a cerrarlas hasta llegar al valor ''maxIdle'' para ahorrar recursos del servidor de base de datos.+  * El atributo 'maxIdle' de la línea 13 indica el número máximo de conexiones que puede haber esperando a que llegue un usuario para usarlas. Si hay demasiadas conexiones esperando Tomcat empezará a cerrarlas hasta que baje hasta el valor ''maxIdle''. Ésto se hace para ahorrar recursos del servidor de base de datos.
   * El atributo 'maxWait' de la línea 14 indica el tiempo en ms que esperará Tomcat a que haya una conexión libre en caso de que no hubiera ninguna libre en ese instante.   * El atributo 'maxWait' de la línea 14 indica el tiempo en ms que esperará Tomcat a que haya una conexión libre en caso de que no hubiera ninguna libre en ese instante.
   * El atributo 'validationQuery' de la línea 15 indica una SQL de tipo ''SELECT'' que lanza Tomcat para comprobar que la conexión aun está conectada a la base de datos y que ésta ultima no la ha cerrado unilateralmente.   * El atributo 'validationQuery' de la línea 15 indica una SQL de tipo ''SELECT'' que lanza Tomcat para comprobar que la conexión aun está conectada a la base de datos y que ésta ultima no la ha cerrado unilateralmente.
  
 +<note important>
 +El muy importante indicar el atributo ''validationQuery'' ya que sino se podría usar una conexión que la base de datos ha cerrado pero que Tomcat cree que aun está conectada.
 +</note>
  
 <note tip>Más información sobre el formato de este fichero se puede encontrar en [[http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html|The Tomcat JDBC Connection Pool]]</note> <note tip>Más información sobre el formato de este fichero se puede encontrar en [[http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html|The Tomcat JDBC Connection Pool]]</note>
 +
 +<note important>
 +En Tomcat 8 se usa un nuevo pool de conexiones.Esta nueva versión ha cambiado el nombre de varios atributos al configurar el pool y añadido otros nuevos.
 +Los mas destacables son los siguientes:
 +  * El parámetro de configuración ''maxActive'' ha sido renombrado a **maxTotal**
 +  * El parámetro de configuración ''maxWait'' ha sido renombrado a **maxWaitMillis**
 +
 +Mas información en [[https://tomcat.apache.org/migration-8.html#Database_Connection_Pooling|Apache Tomcat - Migration Guide - Tomcat 8.0.x - Database Connection Pooling]] y en [[http://commons.apache.org/proper/commons-dbcp/|Apache Commons BDCP]]
 +</note>
 +
patrones/pool_conexiones.1366455853.txt.gz · Última modificación: 2016/07/03 20:18 (editor externo)
Ir hasta arriba
CC Attribution-Noncommercial-Share Alike 3.0 Unported
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0