PHP asincrónico. Por qué

imagen

La programación asincrónica es muy solicitada hoy, especialmente en el desarrollo web, donde la capacidad de respuesta de la aplicación es especialmente importante. Nadie quiere esperar a que la aplicación se "caiga", incluso si en ese momento ejecuta una consulta a la base de datos, envía un correo electrónico o trabaja en otras tareas que pueden llevar mucho tiempo. El cliente quiere una respuesta a su acción, lo mejor de todo, de inmediato. Si su aplicación es lenta, está perdiendo clientes. Frente a una aplicación flotante, la mayoría de las veces el usuario simplemente la cierra y nunca regresa. Desde el punto de vista del usuario, la aplicación se colgó, no puede entender por qué sucedió esto: ¿realiza una operación compleja o deja de funcionar en principio?

Presentamos la traducción de un artículo del desarrollador backend de Skyeng Sergey Zhuk.

Capacidad de respuesta de la aplicación


Las aplicaciones modernas a menudo responden, pero algunas tareas u operaciones, como el intercambio de datos a través de una red, la E / S de archivos o la consulta de una base de datos, pueden llevar mucho tiempo y ralentizar significativamente la aplicación. Para evitar que tales operaciones bloqueen la aplicación, puede ejecutarlas en segundo plano, ocultando así el retraso que causan. Al mismo tiempo, la aplicación sigue respondiendo porque puede continuar realizando otras tareas, por ejemplo, devolviendo el flujo de control a la interfaz de usuario o respondiendo a otros eventos.

Concurrencia y asincronía


Cuando las personas ven código asincrónico, la mayoría de las veces piensan de inmediato: "¡Genial, puedo paralelizar los procesos!". Puedo decepcionarte, pero en realidad no lo es. La asincronía y la concurrencia no son lo mismo. Puede ser difícil detectar esta diferencia, así que tratemos de resolverlo.

Si las tareas se realizan de forma asincrónica, no se bloquean entre sí y la ejecución de una tarea no depende de la finalización de otra. La concurrencia, a su vez, implica el lanzamiento de varias tareas separadas simultáneamente como unidades de trabajo independientes.

Asincronía:
Ve y completa la tarea tú mismo . Avísame cuando hayas terminado y muéstrame el resultado. En este momento, puedo continuar haciendo mi trabajo.

El código asincrónico requiere el procesamiento de dependencias que surgen durante la ejecución de tareas, y esto se implementa mediante devoluciones de llamada. Cuando se completa una tarea, el código notifica a otra tarea. El código asincrónico se trata básicamente del tiempo que tarda la tarea en completarse (orden de los eventos).
imagen
Concurrencia:
Contrata tantos trabajadores como quieras y comparte la tarea entre ellos para completarla más rápido, y notifícame cuando hayas terminado. Puedo seguir haciendo otras cosas o, si la tarea es urgente, me quedaré y esperaré hasta que regrese con los resultados. Entonces puedo componer el resultado final de todos los empleados. La ejecución paralela a menudo requiere más recursos, por lo que aquí básicamente depende del hardware.

imagen
Para comprender la diferencia entre la ejecución asíncrona y paralela utilizando un ejemplo de la vida real, comparamos dos servidores web populares: Apache y Nginx. Ilustran perfectamente esta diferencia. Nginx usa un modelo asincrónico basado en eventos mientras que Apache usa hilos paralelos. Apache crea nuevos hilos para cada conexión adicional, por lo que aquí el número máximo de conexiones permitidas depende de la cantidad de memoria disponible en el sistema. Cuando se alcanza el límite de conexión, Apache deja de crear conexiones adicionales. El factor limitante al configurar Apache es la memoria (recuerde que la ejecución paralela a menudo depende del hardware). Si el hilo se detiene, el cliente espera una respuesta hasta que el hilo esté libre y pueda enviar una respuesta.

Nginx no funciona como Apache, no crea nuevos hilos para cada solicitud entrante. Nginx tiene un flujo de trabajo principal (o varios trabajadores, a menudo para un procesador hay un flujo de trabajo), que es de un solo subproceso. Este trabajador puede procesar miles de conexiones "simultáneamente" y lo hace de forma asíncrona, en un hilo, y no en paralelo en varios hilos.

Por lo tanto, "asincronía" es cómo construimos el sistema, es una composición de procesos independientes entre sí. Por "ejecución paralela" se entiende la ejecución de varios procesos en el mismo momento, mientras que pueden o no estar relacionados. En la ejecución asíncrona, procesamos varias tareas a la vez, y en ejecución paralela, iniciamos varios procesos a la vez. Esto puede parecer lo mismo, pero no lo es. La asincronía describe una estructura, el paralelismo describe una forma de hacerlo.

La ejecución asincrónica se puede comparar con los dispositivos de E / S en su computadora (mouse, teclado, pantalla). Todos son administrados por el sistema operativo, pero cada uno de ellos es una parte independiente del núcleo. Estos procesos son asíncronos, pueden ser paralelos, pero esto no es necesario. Por lo tanto, para garantizar la coherencia, debe crear un enlace entre estas partes independientes para coordinarlas.

¿Qué hay de este backend?


Puede decir que la capacidad de respuesta no es tan importante en el backend. Todas estas cosas asíncronas interesantes con JavaScript suceden en un servidor gratuito, y su servidor solo responde a las solicitudes, por lo que un servidor libre debe ser responsable de la capacidad de respuesta de la aplicación, pero no usted. Sí, eso es cierto, pero la tarea del servidor no se limita a las respuestas API. A veces tiene que administrar tareas complejas, por ejemplo, descargar un video. En este caso, la capacidad de respuesta puede no ser un factor clave, pero su falta de recursos se desperdicia porque la aplicación tiene que estar inactiva. Puede esperar la finalización de las operaciones del sistema de archivos, las interacciones de red, las consultas de la base de datos y similares. A menudo, estas operaciones de E / S son muy lentas en comparación con los cálculos del procesador, por ejemplo, cuando convertimos archivos de video. Y mientras guardamos o leemos lentamente el archivo, el procesador se ve obligado a esperar en lugar de hacer un trabajo útil. Como ya descubrimos, en lugar de esperar, podemos ejecutar estas tareas en segundo plano. Como? Adelante

PHP asincrónico


En JavaScript, de forma inmediata, están disponibles el soporte integrado y las soluciones para escribir código asincrónico. También hay Node.js, que le permite escribir aplicaciones de servidor asíncronas. En JavaScript, podemos usar la función setTimeout () para demostrar un ejemplo de código asincrónico:
imagen

Cuando ejecutamos este código, veremos lo siguiente:
imagen

La función setTimeout () envía el código a la cola y lo ejecuta al final de la pila de llamadas actual. Esto significa que interrumpimos el flujo síncrono de código y retrasamos la ejecución. La segunda llamada a console.log () se realiza antes de la llamada a la cola dentro de la llamada setTimeout ().

¿Qué hay de PHP? En PHP, no tenemos herramientas adaptadas adecuadas para escribir código verdaderamente asincrónico. No hay equivalente a setTimeout (), y no podemos simplemente retrasar o poner en cola ningún código. Es por eso que los frameworks y bibliotecas como Amp y ReactPHP comenzaron a aparecer. Su idea es ocultar detalles de lenguaje de bajo nivel y proporcionar al usuario herramientas de alto nivel que le permitan escribir código asincrónico y controlar la ejecución competitiva de procesos como JavaScript y Node.js.

¿Por qué debería usar PHP si hay Node.js y Go?


Esta pregunta a menudo surge cuando se trata de PHP asíncrono. Por alguna razón, muchos están en contra del uso de PHP para escribir código asincrónico. Alguien siempre sugiere usar Go o Node.js. en lugar de PHP.

El tweet afirmativo describe perfectamente estas situaciones:

imagen

Por supuesto, cuando se acababa de crear PHP, no había ningún propósito de convertirlo en un lenguaje de programación que se pueda utilizar para crear grandes aplicaciones complejas. En ese momento, nadie pensaba en JavaScript o asincronía. Pero ahora tenemos un PHP completamente diferente que ya tiene sus propias funciones para escribir código asincrónico (por ejemplo, la función stream_select ()).

Sí, puede usar Go o Node.js para crear aplicaciones de servidor asíncronas, pero esto no siempre resuelve el problema. Si ya tiene una amplia experiencia con PHP, será mucho más fácil aprender las bibliotecas y las herramientas apropiadas para su situación que aprender un nuevo lenguaje y un nuevo ecosistema. Herramientas como ReactPHP o Amp le permiten escribir código asincrónico tal como lo hace en Node.js. Estas herramientas están bastante desarrolladas y tienen versiones estables, por lo que puede usarlas con seguridad en la producción.

No solo CLI


No voy a escribir un chat, servidor o algo así. Solo quiero acelerar el sitio.

En general, se acepta que el código asincrónico solo se puede usar en scripts de CLI. Es absolutamente normal integrar algunos componentes asincrónicos en un entorno síncrono tradicional, incluso en una aplicación web tradicional. Por ejemplo, puede recibir una solicitud y luego llamar a varios recursos diferentes de forma asincrónica, y cuando se completan estas llamadas, puede continuar el ciclo de vida de solicitud-respuesta y, como resultado, la página se mostrará más rápido.

O debe realizar algunas llamadas externas a la API; por ejemplo, cuando un usuario completa un pago, desea enviar un correo electrónico o una notificación automática. Puede realizar estas llamadas API de forma asincrónica y luego continuar con su secuencia de código síncrono tradicional. No es necesario reescribir completamente la aplicación y eliminar todo lo que se ralentiza. Simplemente identifique los cuellos de botella que interfieren con el rendimiento, y es posible que puedan solucionarse mediante código asincrónico.

Sí, el código asíncrono todavía se usa en la mayoría de los casos en los scripts de la CLI, pero no se limita a los chats y servidores en tiempo real. Si solo quiere acelerar su sitio, no necesita renunciar a su framework Symfony o Laravel y crear su propio servidor de aplicaciones completamente asíncrono.

Conclusión


No tengas miedo de aprender un nuevo paradigma. PHP es mucho más que "ejecutar un script, ejecutar código y morir". Te sorprenderás cuando te des cuenta de que puedes usar el PHP familiar de una manera completamente nueva, ¡como si nunca lo hubieras usado! El código asincrónico y la programación orientada a eventos ampliarán su comprensión de PHP y las posibilidades de usar este lenguaje. No necesita aprender un nuevo lenguaje para escribir aplicaciones asincrónicas solo porque "PHP es una herramienta inapropiada" o "Siempre he hecho esto, no se puede mejorar". ¡Solo pruébalo!

¡Bien, también le recordamos que siempre tenemos muchas vacantes interesantes para desarrolladores!

Source: https://habr.com/ru/post/448968/


All Articles