Es una aplicación PHP. ¿Cómo puedo minimizar el tiempo de inactividad mientras actualizo toda la base de código?
Es una aplicación PHP. ¿Cómo puedo minimizar el tiempo de inactividad mientras actualizo toda la base de código?
Respuestas:
Lo que generalmente hacemos en el trabajo es:
/www/app-2009-09-01
/www/application
/www/app-2009-09-08
/www/application
, pero que apunta a las nuevas fuentes:/www/app-2009-09-08
Todo este proceso se realiza a través de un script automático (lo único que no es automático es que lo iniciemos cuando sea necesario). Esto significa :
Otra ventaja de este procedimiento de enlace simbólico es que es muy fácil "revertir" una actualización si notamos un error catastrófico solo después de poner en producción la nueva versión de las fuentes: solo tenemos que volver a cambiar los enlaces simbólicos.
Por supuesto, esto no le impide probar la nueva versión en su servidor de ensayo antes de ponerla en producción, pero, quién sabe ... A veces, hay un gran error que nadie ha podido ver mientras testing :-(
Por ejemplo, porque no se realizan pruebas de carga de forma regular en la máquina de preparación.
(He visto que la cosa de "retroceso" usaba algo como 4 o 5 veces en 3 años, cada vez, salvó el día y los sitios web ^^)
Aquí hay algún tipo de ejemplo rápido: supongamos que tengo este VirtualHost en mi configuración de Apache:
<VirtualHost *>
ServerName example.com
DocumentRoot /www/application
<Directory /www/application>
# Whatever you might need here (this example is copy-pasted from a test server and test application ^^ )
Options Indexes FollowSymLinks MultiViews +SymLinksIfOwnerMatch
AllowOverride All
php_value error_reporting 6135
php_value short_open_tag on
</Directory>
</VirtualHost>
Bastante "estándar" ... Lo único es /www/application
que no es un directorio real: es solo un enlace simbólico a la versión actual de las fuentes.
Lo que significa que cuando haya puesto las fuentes en el servidor, pero aún no haya cambiado, tendrá algo como esto:
root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root 19 2009-09-08 22:08 application -> /www/app-2009-09-01
Tenga en cuenta que el symlinc apunta a la "versión anterior"
Ahora que la nueva versión se ha subido totalmente al servidor, cambiemos:
root@shark:/www
# rm /www/application
root@shark:/www
# ln -s /www/app-2009-09-08 /www/application
Y, ahora, los /www/application
puntos a la nueva versión de las fuentes:
root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root 19 2009-09-08 22:09 application -> /www/app-2009-09-08
Y solo tenemos que reiniciar Apache:
root@shark:/www
# /etc/init.d/apache2 restart
* Restarting web server apache2
Los tres pasos " eliminar el enlace; crear el nuevo enlace; reiniciar apache " deben realizarse rápidamente; es decir, por un script automatizado, y no por un ser humano.
Usando esta solución:
Y supongo que si usa algún caché de código de operación como APC con la opción estadística en 0, puede significar incluso menos riesgo de tiempo de inactividad.
Por supuesto, esta es la versión "simple": si tiene algunos archivos cargados, por ejemplo, tendrá que usar otro enlace simbólico en algún lugar, u otro VirtualHost o lo que sea ...
Espero que esto sea más claro :-)
¿No puede tomar el código existente y migrar el proyecto a un archivo php de prueba separado, y usarlo mientras realiza sus actualizaciones? Lo que quiero decir es que debe tener un servidor de prueba y un servidor de producción para que cuando tenga que realizar una actualización no incurra en ningún tiempo de inactividad.
Configure un segundo servidor con la base de código actualizada y cámbielos lo más rápido posible. :-)
Si no es posible, asegúrese de que su base de código esté dividida en docenas de partes más pequeñas. Entonces, el tiempo de inactividad se limitaría a solo una subparte uno en ese momento. Los bloques de código más pequeños son más fáciles de reemplazar y la mayoría simplemente continuará ejecutándose sin problemas. Sin embargo, ¡primero intente esto en un entorno de prueba!
En primer lugar, a menudo uso y me gusta un método similar a la respuesta de Pascal MARTIN.
Otro método que también me gusta es usar mi SCM para insertar un nuevo código. El proceso exacto depende de su tipo de SCM (git vs svn vs ...). Si está utilizando svn, me gusta crear una rama "en línea" o "producción" que compruebo como la raíz del documento en el servidor. Luego, cada vez que quiero insertar un nuevo código desde otra rama / etiqueta / troncal, simplemente confirmo el nuevo código en la rama "en línea" y ejecuto svn update en la raíz del documento. Esto permite retrocesos muy fáciles, ya que hay un registro de revisión completo de lo que ha subido / bajado al servidor y quién lo hizo y cuándo. También puede ejecutar fácilmente esa rama "en línea" en un cuadro de prueba, lo que le permite examinar la aplicación que está a punto de impulsar.
El proceso es similar para git y otros estilos de SCM, solo modificado para que sea más natural para su estilo de flujo de trabajo.
¿Desea extraer / sondear en lugar de enviar actualizaciones? Solo tenga un trabajo cron u otro mecanismo más inteligente que ejecute automáticamente svn update.
Extra: también puede usar este proceso para hacer una copia de seguridad de los archivos que su aplicación escribió en el disco. Simplemente haga que un trabajo cron o algún otro mecanismo ejecute svn commit. Ahora los archivos que creó su aplicación están respaldados en su SCM, revisión registrada, etc. (por ejemplo, si un usuario actualiza un archivo en el disco, pero quiere que lo revierta, simplemente presione la revisión anterior).
También uso un enfoque similar al de Pascal MARTIN. Pero en lugar de cargar varias versiones de mi aplicación en el servidor de producción, mantengo las "compilaciones" detrás de mi firewall, cada una en un directorio separado con el número de compilación y la fecha. Cuando quiero cargar una nueva versión, uso un script simple que incluye "rsync -avh --delay-updates". El indicador "delay = updates" cargará todo (eso es diferente) a una carpeta temporal hasta que todas las actualizaciones estén allí, y luego moverá todo de una vez al final de la transferencia a sus rutas adecuadas para que la aplicación nunca esté en un estado medio viejo medio nuevo. Tiene el mismo efecto que el método anterior, excepto que solo mantengo una versión de la aplicación en el sitio de producción (lo mejor es tener solo los archivos esenciales desnudos en el servidor de producción, IMO).