12

我想知道如何在 Heroku 工作人员测功机上的进程之间进行通信。

我们希望 Resque 工作人员读取队列并将数据发送到在同一个测功机上运行的另一个进程。“其他进程”是一个现成的软件,通常使用 TCP 套接字(端口 xyz)来侦听命令。它被设置为在 Resque 工作程序启动之前作为后台进程运行。

但是,当我们尝试在本地连接到该 TCP 套接字时,我们一无所获。

我们用于设置队列的 Rake 任务执行以下操作:

task "resque:setup" do
  # First launch our listener process in the background
  `./some_process_that_listens_on_port_12345 &`

  # Now get our queue worker ready, set up Redis backing store
  port = 12345
  ENV['QUEUE'] = '*'  
  ENV['PORT'] = port.to_s
  Resque.redis = ENV['REDISTOGO_URL']

  # Start working from the queue
  WorkerClass.enqueue
end

这很有效——我们的侦听器进程运行,Resque 尝试处理排队的任务。但是,Resque 作业失败,因为它们无法连接到localhost:12345(特别是Errno::ECONNREFUSED)。

很可能,Heroku 在同一个测功机上阻止了 TCP 套接字通信。有没有解决的办法?

我试图将“代码”从这种情况中取出并在命令行上执行(在服务器进程声称它已正确绑定到 12345 之后):

nc localhost 12345 -w 1 </dev/null

但这也没有联系。

我们目前正在研究更改客户端/服务器代码以UNIXSocket在双方使用而不是 . TCPSocket,但由于它是现成的软件,如果可能,我们宁愿避免使用自己的分叉。

4

5 回答 5

5

使用消息队列 Heroku 附加组件...,

例如IronMQ _

于 2012-02-22T15:03:35.127 回答
2

你试过 Fifo 吗?

http://www.gnu.org/software/libc/manual/html_node/FIFO-Special-Files.html#FIFO-Special-Files

于 2012-02-26T13:23:36.020 回答
1

阅读您的问题,您已经回答了自己的问题,您无法连接到 localhost 12345。

这种设置进程的方式很奇怪,因为您在一个 Heroku dyno 中运行两个进程,这消除了 Heroku 的许多好处,即独立的进程缩放隔离干净的依赖声明和隔离

我强烈建议将其作为两个独立的进程运行,它们通过第三方支持服务进行交互。

于 2012-02-20T11:17:25.450 回答
1

我认为 Heroku 只允许您在每个测功机的给定端口($PORT)中收听。

我在这里看到两个解决方案:

  • 使用 Redis 作为通信中间件,因此工作人员将再次在 Redis 上写入,而侦听器进程将查询 redis 以获取新作业,而不是在端口中侦听。

  • 获取另一个heroku dyno(或者更好,一个完全不同的应用程序)并在那里启动监听过程(在$PORT上)并与两个应用程序通信

于 2012-02-20T11:30:36.897 回答
1

@makdad,“第三方软件”是用 Ruby 编写的吗?如果是这样,我会使用一个猴子补丁来运行它,该补丁可以伪造出来,TCPSocket或者使用它用来访问 TCP 套接字的任何类。将猴子补丁放在它自己的文件中,只有运行第 3 方软件的 Ruby 进程才需要该文件。猴子补丁甚至可以直接从队列中读取数据,并使其TCPSocket表现得好像已收到数据一样。

是的,它不是很优雅,我相信可能有更好的方法来做,但是你什么时候试图完成工作(而不是花几天时间做研究),有时你只需要硬着头皮去做丑陋但有效的东西。无论您选择何种解决方案,请务必将其记录在案,以供以后从事该项目的人员使用。

于 2012-02-23T10:27:16.057 回答