14 de abril de 2015

Conexiones Persistentes PHP

La idea detrás de las conexiones persistentes es que una conexión entre un proceso cliente y una base de datos puede ser reutilizados por un proceso cliente, en lugar de ser creado y destruido varias veces. Esto reduce la sobrecarga de la creación de conexiones nuevas cada vez que es requerido, como las conexiones no utilizadas se almacenan en caché y están lista para ser reutilizadas.

este ejemplo PDO-MySQL utiliza conexiones persistentes
<?php
try{
        $this->db = new PDO(DB_MOTOR.':host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS);
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        $this->db->setAttribute(PDO::ATTR_PERSISTENT,true);
        $this->db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
   
   }catch(PDOException $e){
         echo 'Ha surgido un error y no se puede conectar a la base de datos' .E_USER_ERROR. PHP_EOL;
         echo "";
         echo "Detalle: ".$e->getMessage();
         exit;
      }
?>
Cuando un script php necesita conectarse a un SGBDR, la función PDO con su atributo PDO::ATTR_PERSISTENT primero intenta encontrar un enlace (persistente) que ya esté abierto con el mismo anfitrión, nombre de usuario y contraseña. Si se encuentra uno, se devolverá un identificador para él, en lugar de abrir una nueva conexión.

Consideraciones sobre conexiones persistentes
Al finalizar, la conexión al SGBDR no será cerrada cuando la ejecución del script finalice. En su lugar, el enlace permanecerá abierto para su uso futuro.

Tener en cuenta que PHP no tiene una funcion para "desconectar" las conexiones persistentes.

En las conexiones persistentes se pueden encontrar estados impredecibles por los clientes. Por ejemplo, un bloqueo de tabla puede ser activado antes de que un cliente termina de forma inesperada. Un nuevo proceso cliente reusando esta conexión persistente tendrá la conexión "tal cual". Toda la limpieza tendría que ser realizada por el nuevo proceso cliente antes de que pudiera hacer buen uso de la conexión persistente, aumentando la carga sobre el programador.

Las conexiones persistentes son eficientes si los gastos indirectos para crear un acoplamiento a tu servidor del SQL son altos, por ejemplo porque el web server no funciona en la misma computadora que el servidor de la base de datos:
Si el servidor web con sus páginas php y los servidores de bases de dados están en el mismo ordenador, no puedes notar diferencia de velocidad entre conexiones persistentes y no persistentes. Si no están en el mismo ordenador, pero sí están en una misma subred privada rápida, seguramente tampoco notarás la diferencia de velocidad. Las conexiones persistentes tienen sentido cuando el servidor de bases de datos está en un ordenador remoto, con una conexión lenta, a través de internet por ejemplo.

Las conexiones persistentes no te dan ninguna funcionalidad que no sea posible con las conexiones no-persistentes.

Debes siempre poder substituir conexiones persistentes con las conexiones no-persistentes.

El uso de conexiones persistentes puede requerir ajustar un poco las configuraciones de Apache y de MySQL para asegurarse de que no se excede el número de conexiones permitidas por MySQL.

Por lo general se maneja un archivo de configuracion con los parametros para conectarse a la base de datos, pero en caso de estar en un ambiente de desarrollo ten en cuenta que si tienes un servidor llamado por ejemplo miservidor.com, con ip pública 123.123.123.123, e ip local 192.168.0.1 y unas veces abres conexión contra el nombre de servidor, otras veces contra la ip pública, otras contra la local y otras veces contra localhost, son conexiones distintas cada vez, y vas a multiplicar por 4 el número de conexiones persistentes.
Y más grave aún, esto es muy típico, si tienes en tu servidor varias webs distintas que se corresponden con distintas bases de datos de cada cliente, es normal que configures el servidor de bases de datos con un nombre de usuario y password distinto para cada cliente (con la orden GRANT), y que desde cada programa php conectes con un nombre de usuario y password
distinto según la base de datos a usar, pues en este escenario vas a abrir tantas conexiones persistentes como número de usuarios y passwords distintos tengas, pues para que una conexión persistente se reutilice, TODOS los parámetros de conexión han de ser idénticos.

Las conexiones persistentes no solo dependen de php y la base de datos, tambien es importante configurar estos parametros en httpd.conf

# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests [valor numerico]

# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout [valor numerico]

En el archivo de configuracin php.ini tambin se puede definir cuantas conexiones de puede abrir tanto persistentes como no persistentes