热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP与Go的合体有什么优势

本篇内容介绍了“PHP与Go的合体有什么优势”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如

本篇内容介绍了“PHP与Go的合体有什么优势”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

常规 PHP 开发环境

在讲述 Go 如何改善 PHP 死亡模型前,先了解一下常规 PHP 开发环境。

通常,应用运行于 nginx 和 PHP-FPM 上。nginx 处理静态请求,而动态请求则被重定向给 PHP-FPM,并由其执行 PHP 代码。也许你用的是 Apache 和 mod_php,但是他们原理相同,运行起来只有细微的差别。

看看 PHP-FPM 是如何执行代码的。当收到请求,PHP-FPM 初始化 PHP 子进程,并将请求的详细信息转发给它,作为其状态的一部分(_GET, _POST, _SERVER 等)。

在 PHP 脚本执行期间,状态将无法更改,因此只能通过一种方式获取一组新的输入数据:清除进程内存并再次初始化它。

这种性能模型有许多优点。你不需要太担心内存消耗,所有进程都是完全隔离的,如果其中一个进程「死亡」,它将自动重新创建,并且不会影响其他进程。但是,当你尝试扩展应用程序时,这种方式会有缺点产生。

典型 PHP 环境的缺点和低效性

如果你从事 PHP 的专业开发,那么你就知道从哪儿开始创建一个新项目——选择框架。它是一个用于依赖注入、ORM、转化和模板方法的库。当然,所有用户输入的数据都可以方便地放在一个对象中(Symfony / HttpFoundation 或者 PSR-7)。这些框架很棒!

但一切都有它的代价。在任何企业框架中,为了处理一个简单的用户请求或访问数据库,您必须加载至少几十个文件,创建许多类,并解析多个配置。但最糟糕的是,在每个任务完成后,您需要重置所有内容并重新启动:您刚刚启动的所有代码都将变得无用,在它的帮助下,您将无法处理另一个请求。把这件事告诉任何用其他语言编写的程序员——你会看到他脸上的困惑。

多年来,PHP工程师一直在寻找解决此问题的方法,他们使用了延迟加载技术、微帧、优化库、缓存等。但最终,您仍然必须放弃整个应用程序,重新开始*(译者注:随着PHP7.4中预加载的出现,这个问题将得到部分解决)

一个PHP进程能处理多个请求吗?

您可以编写持续时间超过几分钟的PHP脚本(最多几小时或几天):例如Cron任务、CSV解析器、队列处理程序。所有这些工作遵循一个模式:他们获取一条任务,处理完它,然后获取下一个任务。代码常驻在内存中,因此避免了额外的操作来加载框架和应用程序,节约了宝贵时间。

但是开发长时间运行的脚本并不是那么容易。任何错误都会杀死进程,内存溢出会导致崩溃,而且不能用F5来调试程序了。

自PHP 7后情况有所改善:可靠的垃圾收集器出现了,它变得更容易处理错误,内核的扩展可以避免内存泄漏。是的,工程师仍然需要仔细处理内存并记住代码中的状态的问题(有哪一种语言能让你可以不关注这些事情呢?)当然,在PHP 7中,惊喜并不多。

是否可以采用一种 常驻 PHP 脚本的模型,将其用于处理 HTTP 请求等更琐碎的任务,从而消除对每个请求都从头开始下载所有内容的需要?

要解决这个问题,首先需要实现一个服务器应用程序,该应用程序可以接收 HTTP 请求并将它们逐个重定向到 PHP worker,而不是每次都杀死它。

我们知道我们可以用纯 PHP(PHP-PM)或 C 扩展(Swoole)编写 web 服务器。尽管每种方法都有其优点,但这两种选择都不适合我们 —— 我想要更多的东西。我们需要的不仅仅是一个 web 服务器 —— 我们希望得到一个解决方案,可以使我们避免与 PHP 中的「重启动」相关的问题,同时可以轻松地为特定的应用程序进行调整和扩展。也就是说,我们需要一个应用服务器。

Go 可以帮助解决这个问题吗?我们知道它可以,因为这种语言将应用程序编译成单个的二进制文件; 它是跨平台的; 使用自己的并行处理模型(并发)和用于处理 HTTP 的库; 最后,我们可以把更多的开源库集成到我们的程序中。

合并两种编程语言遇到的困难

首先,有必要确定两个或多个应用程序之间如何相互通信。

例如,使用 Alex Palaestras 的 go-php 库, 可以实现 PHP 和 Go 进程 (如 Apache 中的 mod_php) 之间的内存共享。但是这个库的功能限制了我们使用它解决问题。

我们决定使用另一种更常见的方法:通过使用 sockets / pipelines 来构建进程之间的交互。 这种方法在过去十年中已经证明了其可靠性,并且在操作系统级别得到了很好的优化。

首先,我们创建了一个简单的二进制协议,用于在进程之间交换数据和处理传输错误。在其最简单的形式中, 这种类型的协议类似于 一个具有固定大小的 packet 头 (在我们的示例中为 17 个字节) 的 netstring ,其中包含的信息有 packet 的类型,其大小和二进制掩码的信息,用来检查数据的完整性。

在 PHP 端,我们使用了 pack 函数 ,在 Go 端,使用了 编码 / 二进制 库。

有一个协议对我们来说有点过时,我们添加了直接 从 PHP 调用 net / rpc Go 服务 的功能。 这个功能在后面的开发中对我们有很大的帮助,因为我们可以轻松地将 Go 库集成到 PHP 应用程序中。这项工作的结果可以在我们的另一个开源产品 Goridge 中看到。

在多个 PHP Worker 之间分配任务

在交互机制实现之后,我们开始思考如何更好地将任务转移到 PHP 进程中。当任务到达时,应用服务器必须选择一个空闲的 worker 来执行它。 如果 worker 进程因错误而终止或「死亡」,我们将清除它并创建一个新的。 如果 worker 进程成功执行,我们会将它返回到可用于执行任务的 worker 池中。

PHP与Go的合体有什么优势

为了存储活跃的 worker 进程池,我们使用了一个 缓冲通道 , 为了从池中清除意外「死亡」的工作进程,我们添加了一种跟踪错误和 worker 进程状态的机制。

最终,我们得到了一个可以运行的 PHP 服务器,它能够处理任何以二进制形式呈现的请求。

为了让我们的应用程序作为 web 服务器开始工作,我们必须选择一个可靠的 PHP 标准来处理任何传入的 HTTP 请求。在我们的例子中,我们只需将简单的 net / http 请求从 Go  转换 为 PSR-7 格式,这样它就可以与目前大多数可用的 PHP 框架兼容。

由于 PSR-7 被认为是不可变的(有人会说在技术上不是),开发人员必须编写那些在原则上不将请求视为全局实体的应用程序。这完全符合 PHP 常驻进程的概念。我们的最终实现(尚未收到名称)如下所示:

PHP与Go的合体有什么优势

RoadRunner - 高 - 性能 PHP 应用服务器

我们的第一个测试任务是一个 API 后端,在该后端上,会周期性地出现不可预测的突发请求(比平时更频繁)。虽然在大多数情况下 nginx capabilities 是足够的,但是我们经常因为无法在预期的负载增加下快速平衡系统而遇到 502 错误。

为解决此问题,我们在 2018 年初部署了第一台 PHP / Go 应用服务器。并立即取得了惊人的效果!我们不仅完全消除了 502 错误,并且还将服务器的数量减少了三分之二,节省了大量资金并解决了令工程师和产品经理头痛的问题。

在年中的时候,我们改进了我们的方案,在 MIT 许可下将其发布在 GitHub 上,并命名为 RoadRunner, 从而强调了它惊人的速度和效率。

RoadRunner 是如何改进你的开发堆栈的

RoadRunner 的使用允许我们在 Go 端使用中间件 net/http ,甚至在请求进入 PHP 之前进行 JWT 验证,以及在 Prometheus 中处理 WebSocket 和全局聚合状态。

由于内置的 RPC,你可以在不编写扩展包的情况下,在 PHP 中打开任何 Go 库的 API。更重要的是,使用 RoadRunner,你可以部署不同于 HTTP 的新服务器。示例包括在 PHP 中运行 AWS Lambda 处理器 , 创建强大的队列 选择器, 甚至将  gRPC 添加到我们的应用程序中。

同时使用 PHP 和 Go ,对解决方案有了稳定的提升,在一些测试中将应用程序性能提高了 40 倍,改进了调试工具,实现了与 Symfony 框架的集成,并添加了对 HTTPS、HTTP/2、插件和 PSR-17 的支持。

“PHP与Go的合体有什么优势”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程笔记网站,小编将为大家输出更多高质量的实用文章!


推荐阅读
  • Cookie学习小结
    Cookie学习小结 ... [详细]
  • Ubuntu 22.04 安装搜狗输入法详细指南及常见问题解决方案
    本文将详细介绍如何在 Ubuntu 22.04 上安装搜狗输入法,并提供常见问题的解决方法。包括下载安装包、更新源、安装依赖项等步骤。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
  • 小程序的授权和登陆
    小程序的授权和登陆 ... [详细]
  • 本文介绍了 Go 语言中的高性能、可扩展、轻量级 Web 框架 Echo。Echo 框架简单易用,仅需几行代码即可启动一个高性能 HTTP 服务。 ... [详细]
  • python模块之正则
    re模块可以读懂你写的正则表达式根据你写的表达式去执行任务用re去操作正则正则表达式使用一些规则来检测一些字符串是否符合个人要求,从一段字符串中找到符合要求的内容。在 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • Framework7:构建跨平台移动应用的高效框架
    Framework7 是一个开源免费的框架,适用于开发混合移动应用(原生与HTML混合)或iOS&Android风格的Web应用。此外,它还可以作为原型开发工具,帮助开发者快速创建应用原型。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 该大学网站采用PHP和MySQL技术,在校内可免费访问某些外部收费资料数据库。为了方便学生校外访问,建议通过学校账号登录实现免费访问。具体方案可包括利用学校服务器作为代理,结合身份验证机制,确保合法用户在校外也能享受免费资源。 ... [详细]
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • 如何利用Apache与Nginx高效实现动静态内容分离
    如何利用Apache与Nginx高效实现动静态内容分离 ... [详细]
author-avatar
宁艺汉先生
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有