首页 文章

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

提问于
浏览
10

我想知道如何在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 ,但是因为它尽可能避免使用我们自己的fork .

5 回答

  • 2

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

    例如IronMQ

  • 1

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

    这种设置过程的方式很奇怪,因为你在一个Heroku dyno中运行两个进程,这消除了Heroku的很多好处,即independant process scalingisolationclean depenedency declaration and isolation .

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

  • 1

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

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

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

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

  • 1

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

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

相关问题