TCP-сокет связи между процессами на Heroku рабочий dyno - PullRequest
10 голосов
/ 17 февраля 2012

Я хотел бы знать, как обмениваться данными между процессами в рабочей станции 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 на одном и том же Dyno.Есть ли способ обойти это?

Я попытался вывести «код» из ситуации и просто выполнить в командной строке (после того, как процесс сервера заявил, что он правильно связан с 12345):

nc localhost 12345 -w 1 </dev/null

Но это также не соединяет.

В настоящее время мы изучаем возможность изменения кода клиент / сервер для использования UNIXSocket с обеих сторон, а не TCPSocket, но так как эточасть программного обеспечения, мы бы предпочли избегать нашего собственного форка, если это возможно.

Ответы [ 5 ]

4 голосов
/ 22 февраля 2012

Использовать очереди сообщений дополнения Heroku ...,

как IronMQ для примера

2 голосов
/ 26 февраля 2012
1 голос
/ 23 февраля 2012

@ makdad, "стороннее программное обеспечение" написано на Ruby?Если это так, я бы запустил его с патчем обезьяны, который подделывает TCPSocket или любой другой класс, который он использует для доступа к сокету TCP.Поместите патч обезьяны в собственный файл, который только потребуется для процесса Ruby, на котором запущено стороннее программное обеспечение.Патч обезьяны может даже считывать данные непосредственно из очереди и заставить TCPSocket вести себя так, как если бы эти данные были получены.

Да, это не очень элегантно, и я уверен, что может быть лучший способчтобы сделать это, но когда вы пытаетесь выполнить работу (не тратить дни на исследования), иногда вам просто нужно укусить пулю и сделать что-то уродливое, но работающее.Какое бы решение вы ни выбрали, обязательно документируйте его для тех, кто работает над проектом позже.

1 голос
/ 20 февраля 2012

Heroku позволяет вам прослушивать только данный порт ($ PORT) за динам, я думаю.

Я вижу здесь два решения:

  • Используйте Redis какпромежуточное программное обеспечение, поэтому рабочий снова будет писать в Redis, а процесс слушателя вместо прослушивания в порту будет запрашивать redis для новых заданий.

  • Получить еще одну героиню (или лучше,совершенно другое приложение) и запустите там процесс прослушивания (в $ PORT) и обменивайтесь данными обоими приложениями

1 голос
/ 20 февраля 2012

Читая ваш вопрос, вы ответили на свой вопрос, вы не можете подключиться к локальному хосту 12345.

Этот способ настройки ваших процессов является странным, так как вы выполняете два процесса в рамках одного Heroku dyno, который удаляетмногие преимущества Heroku, например независимое масштабирование процесса , изоляция и декларация чистой зависимости и изоляция .

Я настоятельно рекомендую запуститьэто как два отдельных процесса, которые взаимодействуют через стороннюю службу поддержки.

...