Laravel 如何在单线程的 PHP 中实现异步任务处理?

2024/12/3 6:03:01

本文主要是介绍Laravel 如何在单线程的 PHP 中实现异步任务处理?,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

PHP被认为是一种单线程的语言,意味着在一个进程中它只能执行一个任务一次。然而,Laravel提供了一个强大的队列系统来异步处理多个任务。既然PHP是单线程,Laravel是如何实现这种功能的呢?让我们简单地解释一下。

什么是PHP过程?

在深入了解队列之前,我们首先需要了解什么是 PHP 进程。

一个进程就像被雇来完成任务的工人。当你执行一个 PHP 脚本文件(例如 php my_script.php)时,操作系统将创建一个新的进程。这个进程:

  • 加载 PHP 脚本。
  • 按步骤执行代码。
  • 任务完成后停止并“结束”。
    例如:
    echo "Hello World!"; // 输出 "Hello World!"

点击全屏,退出全屏

当你运行这个脚本时,PHP 将启动一个进程,显示“Hello World!”,然后该进程结束。

PHP在网页应用中

在网页应用中:

  • 一个 web 服务器(比如 Apache 或 Nginx)从浏览器接收一个 HTTP 请求。
  • 服务器会创建一个新的 PHP 进程来处理这个请求。
  • PHP 会处理请求,比如从数据库获取数据或者渲染页面。
  • 当响应被发送回浏览器之后,进程就会结束。
  • PHP 进程是短命的。它们一次处理一个请求,然后停止。这种设计使 PHP 对于 web 应用来说既简单又高效。
单线程是什么?

PHP 是单线程的,也就是说,

  • 一个 PHP 进程一次只能执行一个任务。
  • 它不会在同一进程中同时处理多个任务。例如:在同一个 PHP 进程中,它不会同时处理两个 HTTP 请求。
    echo "任务1";
    // 等待任务1完成后才开始任务2
    echo "任务2";

全屏查看 退出全屏

PHP 首先执行任务一。只有在任务一完成后才执行任务二。这种行为与 JavaScript 这样的语言不同,后者可以在同一个进程中并行执行任务。

Laravel 是如何处理队列的呢?

Laravel的任务队列系统允许你在后台运行多个任务而不妨碍主程序的运行,比如。

  • 发送邮件。
  • 处理图片上传任务。
  • 发送通知。这些任务在后台运行,所以您的应用程序可以更快地响应用户。

不过,PHP 一次只能处理一个任务,对吧?Laravel 是如何让它看起来像是异步处理的呢?答案在于 Laravel 使用了 workers 和多个进程。

什么是工人(指从事某种工作的劳动者)?

Laravel 中的 worker 进程是一个持续运行的 PHP 进程,这个进程会监听任务队列中的任务并执行它们。

当你运行以下命令时:

你可以使用下面的命令来启动队列工作:"php artisan 队列工作"

进入全屏 退出全屏

一个新的 PHP 进程(或工作线程)启动了。接下来,这个进程:

  • 首先,它连接到队列系统(如 Redis 或数据库)。
  • 然后,它等待新任务进入队列。
  • 接下来,它依次处理每个任务。例如:假设你有一个发送 1,000 封邮件的任务:主应用程序将发送 1,000 封邮件的任务发送到队列。一个工作进程拾取一个任务,发送邮件,然后处理下一个任务。
Laravel 是怎么实现异步功能的

Laravel 通过同时运行多个 worker 实现了“并发”行为。每个 worker 都是独立的 PHP 进程。

这怎么运作:
当你运行 php artisan queue:work,它会启动一个 worker(一个 PHP 进程)。
你可以启动多个 worker,以在本地和生产环境中使用进程管理器(例如 supervisor)并行处理 job。
这将启动多个 PHP 进程。每个 worker 独立处理 job,使每个任务看起来像是在同时运行。

任务排队时会发生什么?

当你在 Laravel 中添加任务时,以下是逐步发生的事情:

  1. 任务创建:将任务(例如发送一封邮件)序列化成可存储格式,并将其添加到队列后台(如 Redis 或数据库)。
  2. 工作程序定期检查队列:如果有新的任务,工作程序就会将其取出。
  3. 执行任务:工作程序反序列化该任务并运行其处理函数 handle()。完成后,任务标记为已完成。
  4. 任务完成:工作程序会从队列中移除该任务。

如果任务失败了,Laravel 会再试一次,或者放到“失败的任务”列表里(具体视您的配置而定)。

示例场景:处理联系表单的邮件
想象你有一个 Laravel 应用程序,用户可以在其中提交联系表单。当用户提交表单时:

  • 主程序会立即处理表单并回应用户。
  • 它不是立即发送电子邮件,而是将发邮件的任务排队发送。

背景里:

  • 一名工人开始处理发送邮件的工作。
  • 发送了邮件。
  • 然后处理下一个任务。
  • 这样用户就不必等待邮件发送,应用程序也能运行得更快。
生产中工人们是怎么工作的?

在生产中,Laravel 任务由如 Supervisor 这样的工具管理。Supervisor 负责让这些任务 24/7 运行,并在崩溃时自动重启。

配置示例:

[program:laravel-worker]
command=php /path/to/artisan queue:work --tries=3
numprocs=5

进入全屏 退出全屏

命令:运行 queue:work 命令。
numprocs=5:启动 5 个工作进程(5 个 PHP 进程)来处理任务。

真的是异步的吗?

从技术角度来说,Laravel 队列并不像 JavaScript 或 Node.js 那样在执行任务时是异步的。实际上,Laravel 队列是通过其他方式来处理任务的。

每个工人一次只处理一个工作。
多个工人(进程)提供了并行处理的能力,从而使看起来像是异步处理的效果显现出来。

需要注意的几点
  • PHP 是单线程,所以一个 PHP 进程一次只能处理一个任务。
  • Laravel 使用长时间运行的 PHP 工作进程来处理队列任务。
  • 多个工作进程可以同时运行,从而实现并行处理任务。
  • 队列后端(如 Redis)充当中间人,存储任务直到被工作进程取走。
  • 工具如 Supervisor 确保工作进程在生产环境中的持续运行。

Laravel的队列系统是一种处理后台任务的智能方法,可以提升应用性能和用户体验。尽管PHP本身是单线程的,Laravel通过运行多个进程(即工作者)实现了并行处理。这种简单有效的设计使Laravel即使在受到PHP的限制时也能处理繁重的工作负载。



这篇关于Laravel 如何在单线程的 PHP 中实现异步任务处理?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程