大多数应用程序都需要后台工作来收发邮件、定期清理或任何其他不需要';不需要用户在场。
在Rails世界中,有几种Gem支持作业队列和后台处理——延迟作业和Sidekiq是两种最流行的Gem。
在这篇文章中,我们将详细介绍延迟工作和Sidekiq,包括它们彼此的表现。
延迟作业是直接从Shopify中提取的,并使用一个表来维护所有后台作业。它遵循一个非常简单的模式。任何响应perform方法的Ruby对象都可以在jobs表中排队。
此外,如果你没有';不需要维护特殊的作业对象(尽管强烈建议这样做是为了可测试性和长期运行操作的清晰分离),它还允许您调用。延迟任何Ruby对象上的方法(params)。它将在后台处理该方法。
许多团队选择延迟作业是因为它很简单,并且使用了他们已经存在的数据库。他们没有';不需要花费/维护其他资源。
但是,它仍然会占用数据库表中的空间。如果同时排队的作业太多,可能需要更多的磁盘空间来容纳所有作业。
另一方面,Sidekiq使用Redis作为其数据存储来维护所有作业元数据。这带来了明显的好处,比常规数据库系统快得多。除此之外,每个Sidekiq进程都会产生多个线程,以更快地处理作业。
对于Sidekiq中的每个后台作业,我们需要一个专门的类,该类包含Sidekiq::Worker关注点并响应perform方法。为了让作业排队,我们需要在带有参数的worker上调用perform_async(arg1,arg2)。
Rails已经为作业的顶级声明和处理提供了成熟的作业框架。延迟作业和Sidekiq都支持通过ActiveJob运行作业';这是一个统一的API。只需从ApplicationJob继承并稍后在作业类上调用perform_,即可将作业排队到配置的排队后端。
使用活动作业运行作业的优点是,应用程序代码变得与框架无关,从延迟作业切换到Sidekiq(反之亦然)变得非常容易。TestHelper还使测试排队作业变得轻而易举。
但活动作业提供的抽象也带来了性能开销,因为作业数据必须在它之前进行包装#39;他被推到了商店。Sidekiq声称,当推到Redis时,ActiveJob的速度大约慢2-20倍,处理开销约为3倍。
既然我们已经了解了延迟工作和Sidekiq的基本知识,那就让';让我们更深入地了解他们的差异,以及他们各自带来的好处。
对于基本应用程序,Sidekiq和Delayed Job都提供了一组现成的功能。其中包括分配作业优先级、命名队列和失败时自动重试。
延迟作业还提供了一种配置开箱即用的最大运行时间的方法(Sidekiq没有)。
另一方面,Sidekiq为中间件提供了更新作业元数据、跳过作业排队或执行作业的支持。Sidekiq支持更多回调,不过有些钩子可用于延迟的工作应用程序。您可以将延迟作业与活动作业(即嵌入Rails中的before_enqueue和about_perform回调)一起使用,而不是回调。
WebUI是Sidekiq提供的另一项功能。它提供了有关工作的历史统计数据和有关工人、当前排队工作和死亡工作的信息。无需通过控制台即可执行删除或运行作业等操作。
Delayed Job没有内置的Web UI,但Delayed_Job_Web提供了一个基本的Web UI,其功能与Sidekiq和#39类似;s
就性能而言,Sidekiq相当令人信服地击败了延迟工作。根据Sidekiq和#39;它是一个开源的基准测试,比延迟的作业快30倍左右。这主要有两个原因:
Redis查询数据的速度比Postgres等传统数据库快得多,因为它将数据存储在内存中,而不是磁盘中。
延迟作业运行单个线程来处理作业,而Sidekiq使用多个线程。
虽然所有这些在纸面上看起来都很好,但这些差异并不重要,除非你进行大规模的工作(大约每分钟10万个工作岗位)。确切的数字还取决于作业的平均运行时间。运行时间越长,延迟作业的性能开销就越小。
如果你';如果您担心延迟工作的性能,您可以进行一些性能优化。要使用的确切索引将取决于工作系统的统计数据。例如,如果您使用多个队列,但只有一个队列获得了大部分作业,那么在队列列上创建一个简单的索引(add_index:delayed_jobs,:queue)可以显著提高性能。
延迟工作和Sidekiq对员工都有类似的部署策略。使用Heroku,只需在Procfile中添加条目,即可启动作业处理器并运行workers。
这里';这是事情开始变得更有趣的地方。Sidekiq有一个并发选项来控制它运行的线程数。大多数Sidekiq与延迟工作基准都提到Sidekiq和#39;它有高达25个线程的高并发性,这有助于它的超高速性能。
但在实际环境中,你必须将线程限制在更保守的范围内。实际数量取决于你的应用程序有多重以及你执行的工作类型。我在实践中看到的是,如果在512MB内存(相当于Heroku上的standard-1x)上运行一个worker,线程数将介于2到5之间,而不是25个。
'驯服Rails内存膨胀';Sidekiq的创始人迈克·佩尔姆(Mike Perham)更详细地讨论了记忆问题,值得一读。我赢了';Don’不要直接进入完整的讨论,但他建议对所有运行Sidekiq的员工设置MALLOC_ARENA_MAX=2。
使用jemalloc代替常规malloc也有帮助。具体方法取决于您使用的平台,但在Heroku上非常简单。只需将heroku buildpack jemalloc设置为第一个buildpack(在heroku/ruby buildpack之前)。
正如我们所讨论的,延迟的作业在现有数据库实例上运行。您可能需要增加:
取决于工作负荷或运行的工人数量。但你唯一需要的资源就是作业处理器。
另一方面,Sidekiq需要一个Redis实例来处理作业。如果您还将Redis用作缓存存储,建议您使用配置为";持久存储";为Sidekiq工作。
由于Redis在所有东西都放在内存中时效果最好,如果你有太多的作业(例如,如果Sidekiq由于应用程序中的问题而停止处理它们一段时间),可能需要一些停机时间来清理所有东西。如果你的应用程序和Redis在同一台服务器上,这尤其麻烦。他们将开始争夺内存,导致交换并最终摧毁你的应用程序';这是她的表现。
关于Redis需要注意的一点是,它必须配置maxmemory策略noeviction,以避免Sidekiq';这是数据。否则,你会发现自己缺少需要执行的工作,没有任何痕迹。
Pro最值得注意的新增功能是批处理作业,这些作业可以并行运行、被监控,并作为一个组进行交互,在所有作业完成后调用回调。Pro还具有改进的可靠性功能,以确保即使在网络出现问题时,也不会有任何作业被悄无声息地丢弃。
企业版还具有更多功能。如果你正在寻找一些常规Sidekiq安装可以';t解决,探索付费Sidekiq功能。
实际上,Sidekiq的免费版本仍然非常有效。但很高兴知道,有一些付费选项可以根据需要升级,而不是切换到其他解决方案。
Sidekiq和延迟工作背后都有一个巨大的社区。然而,在StackOverflow或官方文档中找到问题的快速答案并不总是那么容易。
在发展方面,延迟工作的前景并不乐观。在2021年12月和2022年1月,一些延迟的工作做了一些小的工作,但不超过39。它似乎没有取得任何重大进展。它似乎处于仅维护模式,Github上有很多未解决的问题。
相比之下,Sidekiq仍在积极开发中,它的创建者正在全天致力于此。公开的问题很少,而且经常得到解决。
在这篇文章中,我们介绍了Rails应用程序的两个主要作业处理系统——Sidekiq和Delayed job,并分析了它们的一些优缺点。
每个应用程序都有不同的用例。这完全取决于你的预算和运营规模。
如果性能和长期可维护性很重要,那么Sidekiq是一个不需要动脑筋的工具。另一方面,如果运营成本是一个问题,延迟工作可以帮助你做到这一点。
无论你选择延迟工作还是Sidekiq,祝你的项目好运,编码愉快!
如果你';I’’我想在Ruby Magic的帖子出版后尽快阅读,订阅我们的Ruby Magic时事通讯,永远不要错过任何一篇帖子!