

这段旅程总共花了我四年的时间。四年的精心规划、渐进式步骤,以及无数小时的编码和调试,用于迁移与此服务相关的所有内容。
在本文中,将分享使用 Phalcon 和 Swoole 重写高负载微服务的经验,为什么我们决定进行这项转变,我们遇到的障碍,以及我们如何克服它们。
无论您是 PHP 爱好者,还是曾经认为它只适合小型项目的人,我们的故事将提供一些洞见,或许还能带来几声笑声。
让我们深入探讨如何将 PHP 转变为高性能的动力源!
老实说:PHP 常常备受诟病。它是快速搭建 WordPress 或 Drupal 等博客网站,或使用任何知名框架构建企业 CRM 的首选语言。它是 Web 开发的瑞士军刀——多功能且无处不在,但往往在严肃的高性能或企业级应用中被低估。
但是,如果我告诉您 PHP 可以在高负载应用领域轻松与巨头们竞争呢?
这就是 Phalcon 和 Swoole 的强大组合。想象一下为您的可靠老 PHP 设置超级充电,给它注入处理每秒数千请求所需的动力。
当我们团队开始重写高负载微服务时,我们已经非常熟悉 PHP 的能力,特别是 Phalcon。作为 Phalcon 的核心开发者,我熟悉其高性能和效率的潜力。然而,经典的 PHP 设置:PHP-FPM 与 Nginx——已经无法满足我们的需求。
我们的项目起源于一个遗留代码库,最初使用 PHP 5.6 编写,后来升级到 PHP 7.0。这个单体应用运行在私有数据中心,部署在多个 Proxmox 虚拟机上。基础设施相当庞大,拥有 50-100 个 CPU 和数百 GB 的 RAM。
尽管有如此可观的硬件,经典的 Nginx 和 PHP-FPM 栈仍无法提供我们所需的性能和可扩展性。

该应用在我们的运营中扮演关键角色,但随着流量和数据量的增长,我们设置的局限性变得越来越明显。传统的 PHP-FPM 模型为每个请求生成一个单独进程,在负载下挣扎,导致高延迟和资源利用效率低下。
最初,我们考虑用 Golang 重写整个代码库,因为我们已经成功地在类似应用中这样做了。Golang 的性能和并发模型使其成为高负载应用的吸引人选择。
然而,项目的复杂性带来了重大挑战:代码中嵌入了数千条硬编码的业务逻辑规则。在一次迭代中将所有逻辑迁移到 Golang 是不可行的。
我们需要一种允许以非常小、可管理步骤推进的解决方案,最大限度地减少中断,同时逐步改善性能和可扩展性。这让我们探索了 PHP 生态系统中的替代方法,利用我们现有的知识和基础设施,同时提供所需的性能提升。
Phalcon 结合 Swoole 提供了一条引人注目的前进路径。然而,Phalcon 最初并非设计为与 Swoole 协同工作。没有现有的库或指南来集成两者。
所以,我决定实现一个桥接器,允许 Swoole 的 Request 和 Response 传递给 Phalcon,在 Phalcon 的 MVC 中处理,然后将输出返回给 Swoole 发送给客户端。
在实现过程中,我们遇到了几个技术挑战,最显著的是内存管理问题。由于服务启动一次且一切保持在内存中,我们的逻辑需要高效管理内存,以确保稳定性和防止内存泄漏。这些泄漏开始频繁出现,这是此类设置中的常见问题,但需要细致解决。

我们的应用作为一个数据输入验证器,处理传入数据并异步发送到 Kafka。在新版本中,我们使用 Swoole\Table 实现了内部热缓存,每小时通过 Swoole\Tick 从 S3 更新数据。它将数据存储在内存中,因此获取数据和参数的延迟最小。
此外,Phalcon 内部还有几个问题导致了内存泄漏。我花费了大量时间识别、调试和修复这些问题。这个过程对于确保我们的新架构长期稳定和高性能至关重要。
这种方法允许我们逐步重构应用,保持业务逻辑在 PHP 中,同时利用 Swoole 的异步能力显著提升性能。这种策略提供了我们所需的连续性和改进平衡,用于处理复杂、逐步迁移。
选择一个可靠与 AWS MSK(AWS 中的托管 Kafka 代理)合作的 Kafka 客户端,并在服务器启动时连接一次至关重要。该客户端需要处理 AWS MSK 的具体细节,包括认证和维护持久连接。
在适应 Swoole 的 Kafka 客户端并实现缺失功能后,例如认证到 AWS MSK(AWS 中的托管 Kafka 代理),我们实现了没有内存泄漏的稳定系统。
这段旅程充满挑战,但成果非常值得……

一个地理区域的每日入站流量

迁移的主要目标之一是实现稳定性和改善性能。鉴于之前内存管理的问题,这是一项重大成就。

通过严格的调试和优化,我们成功消除了之前困扰应用的内存泄漏。服务的持续运行性质,一切在内存中,需要仔细处理内存分配和释放。我们的努力得到了回报,实现了高度稳定的系统,能够在高负载下持续运行而不会性能下降。

Phalcon 的效率与 Swoole 的异步能力的结合导致响应时间显著改善。即使在重负载下,我们的平均响应时间现在也始终稳定。这大大提升了用户体验,提供更快、更可靠的服务。

新架构极大地改善了微服务的可扩展性。我们现在可以用相同的硬件资源处理更大的请求量,这要归功于 Swoole 提供的并发连接和资源管理的有效处理。
通过保持业务逻辑在 PHP 中并利用 Phalcon 的 MVC 框架,我们使应用更容易维护和扩展。清晰的责任分离和模块化设计允许我们引入新功能并进行更改,而不会干扰现有功能。
为 Swoole 的 Kafka 客户端实现缺失功能,例如认证到 AWS MSK,允许我们无缝集成 AWS 的托管 Kafka 服务。这为我们提供了可靠且可扩展的消息解决方案,进一步增强了微服务的鲁棒性。
Dockerfile 示例:
FROM php:8.1-cli
COPY . /srv
WORKDIR /srv
RUN pecl install phalcon swoole
EXPOSE 9501
ENTRYPOINT ["php", "/srv/server.php"]
使用 Phalcon 和 Swoole 重写我们的高负载微服务是一次变革性过程。我们不仅实现了稳定性和性能改进的目标,还为未来的增长和可扩展性奠定了坚实基础。这个项目证明了,使用正确的工具和方法,PHP 可以驱动高效处理重大工作负载的高性能应用。