Heroku worker dyno上的进程之间的TCP套接字通信

我想知道如何在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 ,但由于它是一个现成的软件,我们宁可避免使用自己的分支。

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

比如IronMQ例如

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

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

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

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

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

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

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

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

是的,它不是很优雅,我相信可能有更好的方法可以做到这一点,但是你什么时候想要完成工作(而不是花几天做研究),有时你只需要咬紧牙关做一些丑陋但有效的东西。 无论您选择哪种解决方案,请务必为稍后处理该项目的人员记录。