Heroku worker dyno上的进程之间的TCP Socket通信

时间:2012-02-17 03:48:23

标签: ruby sockets tcp heroku worker

我想知道如何在Heroku工作者dyno上的进程之间进行通信。

我们希望Resque工作者读取队列并将数据发送到在同一个dyno上运行的另一个进程。 “其他进程”是一种现成的软件,通常使用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阻止同一个dyno上的TCP套接字通信。有办法解决这个问题吗?

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

nc localhost 12345 -w 1 </dev/null

但这也没有连接。

我们目前正在调查更改客户端/服务器代码以使用UNIXSocket而不是TCPSocket,但由于它是一个现成的软件,我们宁愿避免我们自己的叉子如果可能的话。

5 个答案:

答案 0 :(得分:4)

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

例如IronMQ例如

答案 1 :(得分:2)

答案 2 :(得分:1)

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

这种设置流程的方式很奇怪,因为你在一个Heroku dyno中运行两个进程,这消除了Heroku的许多好处,即independant process scalingisolation和{{3} }。

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

答案 3 :(得分:1)

Heroku只允许你在每个dyno的给定端口($ PORT)中收听,我想。

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

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

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

答案 4 :(得分:1)

@makdad,是&#34;第三方软件&#34;用Ruby编写?如果是这样,我会使用一个猴子补丁运行它,它会伪造TCPSocket或者用于访问TCP套接字的任何类。将Monkey补丁放在自己的文件中,运行第三方软件的Ruby进程只需要 。猴子补丁甚至可以直接从队列中读取数据,并使TCPSocket的行为就像收到了数据一样。

是的,它不是很优雅,而且我确定可能有更好的方法去做,但是你什么时候才能完成工作(不是花几天做研究),有时候你只需要咬紧牙关做一些丑陋的事情,但是有效。无论您选择哪种解决方案,请务必将其记录在以后为项目工作的人员身上。