RoadRunner有哪些特性


这篇文章主要介绍“RoadRunner有哪些特性”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“RoadRunner有哪些特性”文章能帮助大家解决问题。在讲述 Go 如何改善 PHP 死亡模型前,先了解一下常规 PHP 开发环境。通常,应用运行于 nginx 和 PHP-FPM 上。nginx 处理静态请求,而动态请求则被重定向给 PHP-FPM,并由其执行 PHP 代码。也许你用的是 Apache 和 mod_php,但是他们原理相同,运行起来只有细微的差别。看看 PHP-FPM 是如何执行代码的。当收到请求,PHP-FPM 初始化 PHP 子进程,并将请求的详细信息转发给它,作为其状态的一部分(_GET, _POST, _SERVER 等)。在 PHP 脚本执行期间,状态将无法更改,因此只能通过一种方式获取一组新的输入数据:清除进程内存并再次初始化它。这种性能模型有许多优点。你不需要太担心内存消耗,所有进程都是完全隔离的,如果其中一个进程「死亡」,它将自动重新创建,并且不会影响其他进程。但是,当你尝试扩展应用程序时,这种方式会有缺点产生。如果你从事 PHP 的专业开发,那么你就知道从哪儿开始创建一个新项目 —— 选择框架。它是一个用于依赖注入、ORM、转化和模板方法的库。当然,所有用户输入的数据都可以方便地放在一个对象中(Symfony / HttpFoundation 或者 PSR-7)。这些框架很棒!但一切都有它的代价。在任何企业框架中,为了处理一个简单的用户请求或访问数据库,您必须加载至少几十个文件,创建许多类,并解析多个配置。但最糟糕的是,在每个任务完成后,您需要重置所有内容并重新启动:您刚刚启动的所有代码都将变得无用,在它的帮助下,您将无法处理另一个请求。把这件事告诉任何用其他语言编写的程序员 —— 你会看到他脸上的困惑。多年来,PHP 工程师一直在寻找解决此问题的方法,他们使用了延迟加载技术、微帧、优化库、缓存等。但最终,您仍然必须放弃整个应用程序,重新开始 *(译者注:随着 PHP7.4 中预加载的出现,这个问题将得到部分解决)您可以编写持续时间超过几分钟的 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 来执行它。 如果 worker 进程因错误而终止或「死亡」,我们将清除它并创建一个新的。 如果 worker 进程成功执行,我们会将它返回到可用于执行任务的 worker 池中。为了存储活跃的 worker 进程池,我们使用了一个 缓冲通道 , 为了从池中清除意外「死亡」的工作进程,我们添加了一种跟踪错误和 worker 进程状态的机制。最终,我们得到了一个可以运行的 PHP 服务器,它能够处理任何以二进制形式呈现的请求。为了让我们的应用程序作为 web 服务器开始工作,我们必须选择一个可靠的 PHP 标准来处理任何传入的 HTTP 请求。在我们的例子中,我们只需将简单的 net /http 请求从 Go 转换 为 PSR-7 格式,这样它就可以与目前大多数可用的 PHP 框架兼容。由于 PSR-7 被认为是不可变的(有人会说在技术上不是),开发人员必须编写那些在原则上不将请求视为全局实体的应用程序。这完全符合 PHP 常驻进程的概念。我们的最终实现(尚未收到名称)如下所示:我们的第免费云主机域名一个测试任务是一个 API 后端,在该后端上,会周期性地出现不可预测的突发请求(比平时更频繁)。虽然在大多数情况下 nginx capabilities 是足够的,但是我们经常因为无法在预期的负载增加下快速平衡系统而遇到 502 错误。为解决此问题,我们在 2018 年初部署了第一台 PHP / Go 应用服务器。并立即取得了惊人的效果!我们不仅完全消除了 502 错误,并且还将服务器的数量减少了三分之二,节省了大量资金并解决了令工程师和产品经理头痛的问题。在年中的时候,我们改进了我们的方案,在 MIT 许可下将其发布在 GitHub 上,并命名为 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 的支持。关于“RoadRunner有哪些特性”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注百云主机行业资讯频道,小编每天都会为大家更新不同的知识点。

相关推荐: Go中并发和并行的区别有哪些

这篇文章主要介绍了Go中并发和并行的区别有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Go中并发和并行的区别有哪些文章都会有所收获,下面我们一起来看看吧。 并发和并行的区别:1、并发是把任务在不同的时间点交给处理器进行处理,…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 04/02 21:53
下一篇 04/02 21:53

相关推荐