首页 >后端开发 >php教程 >PHP 是单线程语言,那么 Laravel 如何异步处理队列作业呢?

PHP 是单线程语言,那么 Laravel 如何异步处理队列作业呢?

Linda Hamilton
Linda Hamilton原创
2024-12-01 07:24:18448浏览

PHP is a Single-Threaded Language, So How Does Laravel Handle Queue Jobs Asynchronously?

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

什么是 PHP 进程?

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

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

  • 加载 PHP 脚本。
  • 逐步执行代码。
  • 任务完成后停止并“死亡”。 例如:
echo "Hello World!";

当您运行此脚本时,PHP 会启动一个进程,显示“Hello World!”,然后进程结束。

Web 应用程序中的 PHP

在网络应用程序中:

  • Web 服务器(如 Apache 或 Nginx)从浏览器接收 HTTP 请求。
  • 服务器创建一个新的 PHP 进程来处理请求。
  • PHP 处理请求(例如,从数据库获取数据或渲染页面)。
  • 向浏览器发送响应后,该过程结束。
  • PHP 进程是短暂的。他们一次处理一个请求,然后停止。这种设计使 PHP 对于 Web 应用程序来说变得简单而高效。

什么是单线程?

PHP 是单线程的,意思是:

  • 一个 PHP 进程一次只能处理一项任务。
  • 它不会在同一进程中同时执行多个任务。 例如:
echo "Task 1";
// Waits for Task 1 to finish before starting Task 2
echo "Task 2";

PHP 首先执行任务 1。只有完成后,它才会转移到任务 2。这种行为与 JavaScript 等语言不同,在 JavaScript 中,任务可以在同一进程中并行运行。

那么 Laravel 如何处理队列呢?

Laravel 的队列系统允许您在后台运行多个任务,而不会阻塞主应用程序。例如:

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

但是 PHP 一次只能处理一项任务,对吗? Laravel 如何让它看起来像是异步的?答案在于工人和多个进程。

什么是工人?

Laravel 中的 Worker 是一个长时间运行的 PHP 进程,它监听队列中的作业并执行它们。

运行命令时:

php artisan queue:work

一个新的 PHP 进程(或工作进程)启动。这个过程:

  • 连接到队列系统(如 Redis 或数据库)。
  • 等待新作业(任务)到达队列。
  • 一项一项地挑选并处理工作。 示例:假设您有一个发送 1,000 封电子邮件的任务: 主应用程序向队列发送 1,000 个作业。 工作进程选择一个作业,发送电子邮件,然后移至下一个作业。

Laravel 如何实现异步行为?

Laravel 通过同时运行多个工作线程来实现“异步”行为。每个worker都是一个独立的PHP进程。

工作原理如下:
当您运行 php artisanqueue:work 时,它从一个工作者(一个 PHP 进程)开始。
您可以使用流程管理器(如主管)启动多个工作人员在本地和生产中的不同选项卡上并行处理作业。
这将启动多个 PHP 进程。每个工人独立处理工作,使得任务看起来像是同时运行的。

当作业排队时会发生什么?

当您在 Laravel 中对作业进行排队时,将逐步发生以下情况:

  1. 创造就业机会: 作业(例如,发送电子邮件)被序列化(转换为可存储格式)并添加到队列后端(如 Redis 或数据库)。
  2. Worker 轮询队列: 工人们不断地检查队列中是否有新的工作。 如果找到工作,工人就会接手。
  3. 作业执行: 工作线程反序列化作业并运行其handle()方法。 完成后,该作业将标记为已完成。
  4. 工作完成情况: 工作人员从队列中删除作业。

如果作业失败,Laravel 会重试或将其移至“失败作业”列表(根据您的配置)。

示例场景:发送电子邮件
假设您有一个 Laravel 应用程序,用户在其中提交联系表单。提交表格后:

  • 主应用程序处理表单并立即响应用户。
  • 它不是立即发送电子邮件,而是将电子邮件发送任务添加到队列中。

背景:

  • 一名工人接手发送电子邮件的工作。
  • 发送电子邮件。
  • 转到下一个工作。
  • 这样,用户就不必等待电子邮件发送,从而使应用程序更快。

工人在生产中如何奔跑?

在生产中,Laravel 工作人员由 Supervisor 等工具进行管理。主管让工作人员 24/7 持续运行,并在崩溃时重新启动他们。

Supervisor 配置示例:

echo "Hello World!";

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

它真的是异步的吗?

从技术上讲,Laravel 队列不像 JavaScript 或 Node.js 处理任务那样是异步的。相反:

每个工人一次处理一项工作。
多个工作线程(进程)提供并行性,呈现异步执行的外观。

需要记住的要点

  • PHP 是单线程的,因此单个 PHP 进程一次处理一项任务。
  • Laravel 使用工人(长时间运行的 PHP 进程)来处理队列作业。
  • 多个worker可以同时运行,允许并行处理作业。
  • 队列后端(如 Redis)充当中间人来存储作业,直到工作人员拿起它们。
  • Supervisor 等工具可确保工人在生产中持续运行。

Laravel 的队列系统是一种在后台处理任务的智能方式,可以提高应用程序性能和用户体验。虽然 PHP 本身是单线程的,但 Laravel 通过运行多个进程(worker)来实现并行性。这种简单而有效的设计使 Laravel 能够处理繁重的工作负载,即使有 PHP 的限制。

以上是PHP 是单线程语言,那么 Laravel 如何异步处理队列作业呢?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn