前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >让我们认识一下PHP非阻塞并发框架Amp

让我们认识一下PHP非阻塞并发框架Amp

作者头像
Tinywan
发布2024-05-21 20:16:45
1570
发布2024-05-21 20:16:45
举报
文章被收录于专栏:开源技术小栈开源技术小栈

什么是异步编程?

当使用PHP编写的应用程序I/O任务时,程序会在执行某个任务之前,一定要等待之前的任务完成,这时CPU会有很多时间处于空闲状态,这不仅会降低应用程序性能,还会降低硬件利用率。比如,当程序需要从数据库中读取大量的数据时,由于需要等待I/O操作完成,程序的执行速度会非常缓慢。

因此,我们通过事件库,在程序执行的过程中,不需要等待某个任务完成才能执行下一个任务。这种编程模式可以极大地提高程序的效率和响应速度,尤其在处理复杂的I/O操作时表现得更为出色,而这就是异步编程。

Amphp

Amphp/Amp 是一个轻量级、高效的PHP异步库,为开发人员提供了一种处理I/O密集型任务和网络操作的新方式。它基于coroutine(协程)模型,让你能够编写出并发执行的任务,从而最大化服务器资源利用率,提高应用性能。

核心技术

Amp的核心是它的事件循环coroutine(协程)支持。事件循环监听系统级别的事件,如文件描述符的状态变化或定时器触发,而coroutine则允许代码在不阻塞主线程的情况下进行暂停和恢复。这种设计使得开发者可以以同步代码的风格编写异步程序,降低了异步编程的学习曲线。

此外,Amp还提供了Promise/Try机制,这是一套处理异步操作成功与失败的工具。通过Promise对象,你可以轻松地链式处理异步操作,并优雅地处理错误。

应用场景

  • 网络I/O: Amp非常适合处理大量HTTP请求、TCP连接或其他网络通信,如:Websocket。它可以并行处理这些连接,显著提升Web服务的吞吐量。
  • 数据库交互: 异步数据库操作可以大大提高数据读取和写入的速度,尤其是在需要处理多个查询时。
  • 文件系统操作: 读写大文件或者遍历大量目录时,Amp可以通过异步操作避免阻塞主线程。
  • 后台任务: 对于耗时较长的后台任务,如数据处理、爬虫或批量更新,Amp可以实现更快的执行速度。

AMPHP是一个事件驱动的PHP库集合,设计时考虑了纤程和并发性。amphp/amp专门提供了future和cancellation作为异步编程的基本原语。我们现在使用Revolt,而不是使用amphp/amp发布事件循环实现。

PHP大量使用PHP 8.1附带的纤程来编写异步代码,就像同步、阻塞代码一样。与早期版本相比,不需要基于生成器的协程或回调。与线程类似,每个纤程都有自己的调用堆栈,但纤程由事件循环协同调度。使用Amp\async()并发运行。

动机

传统上,PHP遵循顺序执行模型。PHP引擎按顺序一行接一行地执行。然而,程序通常由多个独立的子程序组成,这些子程序可以同时执行。

如果查询数据库,则以阻塞方式发送查询并等待数据库服务器的响应。一旦你有了答案,你就可以开始做下一件事。我们可以发送下一个数据库查询,或者对一个API执行HTTP调用,而不是坐在那里什么也不做。让我们利用我们通常花在等待I/O上的时间!

Revolt允许这样的并发I/O操作。我们通过避免回调来保持低认知负荷。我们的API可以像任何其他库一样使用,除了它们也可以并发工作,因为我们在后台使用了非阻塞I/O。使用Amp\async()并发运行,并在需要时使用Future::await()等。

多年来,在PHP中实现并发的技术有很多,例如PHP 5中的回调和生成器。这些方法都有“你的函数是什么颜色”的问题,我们通过PHP 8.1中的Fibers解决了这个问题。它们允许多个独立调用堆栈的并发性。

纤程由事件循环协同调度,这就是为什么它们也被称为协程。重要的是要理解,在任何给定的时间只有一个协程在运行,所有其他协程在此期间暂停。

你可以将协程比作一台使用单个CPU内核运行多个程序的计算机。每个程序都有一个执行时间段。然而,协程并不是抢占式的。他们没有固定的时间。他们必须主动给予事件循环的控制权。

任何阻塞I/O函数在等待I/O时阻塞整个进程。你会想要避开他们。如果你还没有阅读安装指南,可以看看Hello World示例,它演示了阻塞函数的效果。AMPHP提供的库避免了I/O阻塞。

安装

此包可以作为Composer依赖项安装。

代码语言:javascript
复制
composer require amphp/amp

如果您使用这个库,很可能希望使用Revolt来调度事件,您应该单独要求Revolt,即使它是作为依赖项自动安装的。

代码语言:javascript
复制
composer require revolt/event-loop

这些包为PHP中的异步/并发应用程序提供了基本的构建块。我们提供了很多建立在这些基础上的软件包。

例如以下

  • amphp/byte-stream提供流抽象
  • amphp/socket为UDP和TCP(包括TLS)提供套
  • amphp/parallel提供并行处理以利用多个CPU内核并卸载阻塞操作
  • amphp/http-client提供HTTP/1.1和HTTP/2客户端
  • amphp/http-server提供HTTP/1.1和HTTP/2应用服务器
  • amphp/mysqlamphp/postgres用于非阻塞数据库访问

要求

此软件包需要PHP 8.1或更高版本。无需扩展!仅当应用需要大量并发套接字连接时才需要扩展,通常此限制配置为最多1024个文件描述符。

使用

协程

协同程序是可中断的功能。在PHP中,它们可以使用纤程来实现。

以前版本的JavaScript使用生成器来实现类似的目的,但是纤程可以在调用堆栈中的任何地方中断,这使得以前的样板文件(如Amp\call())变得不必要。

在任何给定的时间,只有一个纤程在运行。当协程挂起时,协程的执行会暂时中断,允许其他任务运行。一旦计时器到期,流操作可能,或任何等待的Future完成,执行将恢复。

协同程序的低级挂起和恢复由Revolt的SuspensionAPI处理。

代码语言:javascript
复制
<?php

require __DIR__ . '/vendor/autoload.php';

use Revolt\EventLoop;

$suspension = EventLoop::getSuspension();

EventLoop::delay(5, function () use ($suspension): void {
    print '++ Executing callback created by EventLoop::delay()' . PHP_EOL;

    $suspension->resume(null);
});

print '++ Suspending to event loop...' . PHP_EOL;

$suspension->suspend();

print '++ Script end' . PHP_EOL;

在Revolt事件循环上注册的回调会自动作为协程运行,挂起它们是安全的。除了事件循环API,Amp\async()还可以用来启动独立的调用栈。

代码语言:javascript
复制
<?php

use function Amp\delay;

require __DIR__ . '/vendor/autoload.php';

Amp\async(function () {
    print '++ Executing callback passed to async()' . PHP_EOL;

    delay(3);

    print '++ Finished callback passed to async()' . PHP_EOL;
});

print '++ Suspending to event loop...' . PHP_EOL;
delay(5);

print '++ Script end' . PHP_EOL;
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是异步编程?
  • Amphp
    • 核心技术
      • 应用场景
        • 动机
          • 安装
            • 要求
              • 使用
                • 协程
                相关产品与服务
                数据库专家服务
                数据库专家服务(Database Expert Service,DBexpert)为您提供专业化的数据库服务。仅需提交您的具体问题和需求,即可获得腾讯云数据库专家的专业支持,助您解决各类专业化问题。腾讯云数据库专家服务团队均有10年以上的 DBA 经验,拥有亿级用户产品的数据库管理经验,以及丰富的服务经验。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档