如何在Heroku上的两个不同应用程序之间共享工作进程?

10

我有两个应用程序在Heroku上运行,指向同一个数据库,第一个负责用户界面,第二个负责管理员界面,我正在使用带有Redis的Sidekiq处理后台作业。我添加了一个工作进程,通过设置环境变量指向相同的Redis Addon,我能够共享“redis-server”。现在我希望也能够共享worker,因为添加额外的worker将会增加成本。

请建议一下,这是否可能?

3个回答

15
如果两个应用程序都使用相同的Redis URL和相同的命名空间,您可以使用相同的Redis配置启动一个worker,并且两者将共享该worker。
请注意,Sidekiq进程将启动其中一个应用程序。您的Worker的代码必须在该应用程序中。另一个应用程序将无法引用该代码,但可以使用以下方法推送作业:
Sidekiq::Client.push('class' => 'SomeWorker', 'args' => [1,2,3])
请注意,'class' 是一个字符串,因此 SomeWorker 实际上可以在另一个应用程序中定义。

是的,两个应用程序都指向同一个 Redis URL,并且两个应用程序都将作业添加到队列中。如果我在任何一个应用程序上不添加工作程序,则该应用程序无法将作业添加到 Redis 服务器以进行处理。 - Sachin Singh
@SachinSingh 如果这不是你问题的答案,那我就不明白你的问题是什么了。 - Old Pro
你如何测试作业是否已经推送到客户端? - Daniel Pietzsch
这个解决方案还适用吗?我正在使用 Sidekiq 5.2.2,但是我遇到了以下错误:irb(main):014:0> Sidekiq::Client.push('class' => 'SomeWorker', 'args' => [1,2,3]) Traceback (most recent call last): 2: from (irb):14 1: from (irb):14:in rescue in irb_binding' NoMethodError (undefined method get_sidekiq_options' for "SomeWorker":String) - Shanky Munjal
是的,这个答案仍然是最佳实践。如果您遇到错误,请打开一个问题或提出一个新问题。 - Mike Perham

0

虽然Mike的答案仍然是一个安全的选择,但是在每次将此类排队时都必须内联包含所有相关的sidekiq选项有点不太好看。

这里有一篇博客文章详细介绍了这个问题,并提供了第二种方法:

http://coderascal.com/ruby/using-sidekiq-across-different-applications/

基本上,另一种选择是在排队应用程序上拥有一个“代理”类,控制sidekiq的行为(队列,重试等)。然后,在接收/取消队列应用程序上会有一个匹配的类名。
博客文章的作者覆盖了一些标准的Sidekiq逻辑,以便在接收端从代理类重定向到非代理类。覆盖宝石的行为有点冒险,并且强制执行额外的类命名约定。但您可能可以避免执行该部分。

截至2018年11月15日,该博客文章已下线。 - Ven'Tatsu
可以在Wayback Machine上找到:https://web.archive.org/web/20180130194742/http://coderascal.com/ruby/using-sidekiq-across-different-applications/ - Slicedpan

0

使用3个不同的Heroku应用程序怎么样?

  1. 用户界面应用程序(UI存储库)
    • web:bundle exec rails server
  2. 管理员界面应用程序(管理员存储库)
    • web:bundle exec rails server
  3. 工作程序(管理员存储库)
    • worker:bundle exec sidekiq(文档

即使2和3使用相同的代码库,您也可以拥有2个不同的Heroku应用程序。一个启动管理员,一个实际启动sidekiq。这样能解决您的问题吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接