php 队列扩展安装_扩展到无限:创新工人队列

php 队列扩展安装

构建应用程序时,通常需要协调前端,数据库,工作队列和API。 传统上,队列和API是分开的。 队列处理长时间运行或占用大量CPU的任务,API提供快速响应以使应用程序保持快照。

在Paragon,我们面临一个问题:我们如何为处理所有客户任务的队列构建高性能API?”

对于不熟悉Paragon的用户 ,Paragon提供了用于创建API和工作流的可视化构建器。 用户可以在几分钟内构建cron作业和API端点,这些端点可以连接到数据库,第三方API和服务以及用于路由请求和转换数据的逻辑或自定义代码。 在这种情况下,我们必须构建一个支持以下用例的工作队列:

  • 用户可以在服务器上运行任意代码(步骤)
  • 系统应该能够扩展以并行执行零,数千或数百万个步骤
  • API请求或预定事件可以触发一系列步骤(工作流程)
  • 如果是由API请求触发的,则工作流的输出应几乎立即在API响应中返回

听起来像是艰巨的壮举,对不对? 剧透警报: 。 这模糊了工作人员队列和API之间的界线,并且不存在可以借鉴的常见工程范式。 可以想象,这些产品要求对安全性和性能的影响使我们的工程时间忙了一段时间。

简介:爱马仕+大力神

由于平台的复杂性,性能和安全性要求,我们不得不在API + worker队列构造上进行一些创新。 我们创建了Hermes(我们的API消息传递服务)和Hercules(我们的工作流执行器)来解决这些问题。

Hermes接受API请求,将其发送给Hercules进行执行,等待指定的工作流程及其步骤完成(或失败),然后将响应发送回任何等待的客户端。 它们是完全独立的服务,但是它们相互通信以接收,安排和执行工作。

有人可能会认为,将作业提交到工作人员队列与等待响应之间增加的复杂性和延迟可能会降低API的速度。 我们很高兴发现相反的情况:我们的API变得更快,特别是在处理大量数据时。

借助Hercules的自我监控和自动缩放功能,我们可以跨流程分配工作并并行运行它们。 此外,如果某个步骤的分支失败,其他步骤可以继续成功运行,而无需终止请求,从而为工作流增加了更多的一致性和可靠性。

考虑到这一点,以下是我们在构建弹性,可扩展的系统时思考或了解的一些事情。

容错能力

事情会破裂。 这是我们构建系统时所有人都必须接受的事实。 代码将无法按预期运行,内存将泄漏,API将不会返回预期的响应,升级后的依赖项将引入新的问题,等等。我们正在处理所有这些未知的未知数,以及从我们的用户运行任意代码可能会失败。

为了确保作业不会减少其他作业,重要的是要单独运行它们。 这表示:

  • 每次执行使用一个进程。 单个进程一次不能处理多个任务。 如果一个进程崩溃,所有其他正在进行的作业将失败。
  • 将代码与核心环境隔离。 不允许用户编写与基础硬件,环境变量或其他关键资源相混淆的恶意代码。 我们将Docker容器和这些容器中的沙盒环境结合使用,以将代码与主要流程分开。
  • 将API层与工作层分开。 对我们来说,最重要的是每一项工作都要执行。 鉴于工作人员会定期停机,因此即使没有立即可用的工作人员,我们也需要确保始终有可靠的服务器来接受排队作业的请求。

规模

正如大多数敏捷团队所做的那样,我们拥有多种环境来测试我们不同版本的代码。 这意味着在一个开发环境中,可能正在运行零个作业,而在另一个开发环境中,可能有数千个工作。

为了确保我们能够在满足流量需求的同时仍优化资源,这是我们采用的一些关键基础架构元素。

  • 与容器一起水平缩放。 假设我们每个进程只运行一项任务,那么在功能更强大的服务器上(垂直扩展)运行代码并不等于更高的吞吐量。 因此,对我们来说,答案是水平扩展每个服务的较小实例以满足需求。
    所有这些机器都运行相同版本的代码以保持一致性很重要,因此我们使用Docker将我们每个版本的代码打包到可执行映像中。 我们在每次部署的CI环境中都构建映像,并且在部署新容器以满足需求时,它们会提取最新的映像。
  • 添加自动缩放监视器。 我们监视一些关键指标来确定伸缩逻辑,其中包括队列中的作业数量,队列中最旧的作业,计算机上的内存使用量,来自请求的响应时间以及端点运行状况检查。
  • 将特定于域的代码分离到微服务中。 我们的微服务架构允许我们独立地自动扩展资源,这意味着可能有一个Hermes实例接受请求,但有数百个Hercules实例处理请求。 此外,我们还有更多微服务,可满足Hermes或Hercules访问数据存储所需的各种功能。

持久状态

我们用户的工作流程可能会在几毫秒,几分钟或几天内运行,具体取决于他们的配置。 我们通常一天要多次部署新功能,这意味着服务器会终止以获取最新的映像,并且作业将在数量可变的服务器上以单独的流程执行。

这意味着工作流状态不能存储在内存中,否则其他计算机将无法访问它们。

步骤可能需要工作流中先前执行的步骤中的数据,这些时间是在未知时间之前运行的。 另外,作业只能执行一次,这意味着无论是一台处理服务器还是数千台,服务器之间都不会出现竞争状况。

这些都是工作者队列的常见方案。 所有这些的解决方案很简单:

  1. 不要在内存或容器中存储任何重要内容。
  2. 使用容器外部符合ACID的数据存储。 这允许在读取/写入数据时使用锁定机制来实现作业和可靠性。

缓存规则(我周围的一切)

我们的分布式体系结构包括具有自己的数据存储的多个微服务,其中一些微服务具有读取和写入的多个数据存储。 对一个微服务的单个API调用可能会触发对其他服务的十几个调用,读写,加密/解密方法等,这可能导致数百毫秒(如果不是几秒钟)的开销。

假设工作流可以包含任意数量的步骤,则每100毫秒添加到一个步骤可能会导致不理想的用户体验。

如果正确实现,则缓存可以在整个系统中极大地提高性能。 这里要考虑的一件事是,在容器化的n级微服务体系结构中,内存中缓存虽然易于实现且性能很高,但并不总是最佳选择。

如果微服务在负载均衡器后面有10个实例,每个实例运行在数据库前面实现的内存中缓存,则该缓存几乎每次都会丢失。 因此,我们将Redis用作实例之间的共享缓存。

此外,我们考虑了请求量和读写比率。 鉴于我们的工作流平均比部署工作执行多数千倍,这是我们缓存的第一件事,这反过来又为我们节省了数百万的数据库查询,微服务之间的API调用以及对API调用的响应时间。

结论

没有哪个系统是完美的,但是我们为Paragon的构建感到自豪。 Hercules负责所有繁重的工作,而Hermes负责所有谈话。 它们可以彼此独立地扩展和缩小以满足需求,并且当一个过程失败时,系统的其他部分将不被察觉并且不受影响。

我们希望听到您对我们实施的想法! 快乐的编码。

翻译自: https://hackernoon.com/scaling-to-infinity-innovating-the-worker-queue-uy3t30w8

php 队列扩展安装

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值