Какова правильная технология сердечного ритма / поддержки активности для Java REST? Http? Tcp? Кодировка: чанки?

Настройка:

У нас есть сайт https://main.externaldomain/xmlservlet, который, например, выполняет аутентификацию / проверку / геолокацию и прокси (слегка измененные) запросы к http://london04.internaldomain/xmlservlet.

Прямой доступ к внутреннему домену, доступному для конечных пользователей, отсутствует. Связь между сайтами иногда прерывается, а иногда внутренние доменные узлы становятся недоступными / мертвыми.

Главный сайт использует org.apache.http.impl.client.DefaultHttpClient (я знаю, что он устарел, мы постепенно обновляем этот устаревший код) с readTimeout, установленным в 10.000 миллисекунд. Запрос и ответ имеют полезную нагрузку xml / тело переменной длины и Transfer-Encoding: chunked используется также Keep-Alive: timeout=15 используется.

Эта проблема:

Иногда London04 действительно требуется более 10 секунд (скажем, 2 минуты) для выполнения. Иногда это изящно вылетает. Иногда возникают другие (сетевые) проблемы. Иногда в течение этих 2 минут - части response-xml-данных заполняются так постепенно, что между порциями нет 10-секундного промежутка, и поэтому readTimeout никогда не превышается, иногда есть 10-секундный интервал и время ожидания HttpClient...

Мы могли бы попытаться увеличить время ожидания на главной стороне, но это могло бы легко увеличить / перегрузить пул слушателей (просто обычным трафиком, даже не будучи DDOSed). Нам нужен способ различать внутренний сайт, который все еще работает над генерацией ответа, и случаи, когда он действительно аварийно завершился / network_lost / etc. И самое лучшее во время общения - это биение сердца (каждые 5 секунд).

Мы думали, что Keep-Alive спасет нас, но, похоже, он защищает только промежутки между запросами (не во время запросов), и, похоже, он не делает сердцебиение в течение промежутка (просто имея / wait_for timeout).

Мы думали, что chunked-кодирование может спасти нас, посылая некоторые тактовые импульсы (0-bytes-size-chunks), чтобы дать понять другой стороне, но, похоже, нет такой реализации по умолчанию для поддержки любого тактового импульса таким образом, и тем более кажется, что 0- блок размером в байты сам по себе является индикатором EOD...

Вопросы):

Если мы правы в предположении, что KeepAlive/ChunkedEncoding не поможет нам в достижении keepAlive/hearbeat/fastDetectionOfDeadBackend, тогда:

1) в каком слое должно быть реализовано такое сердцебиение? Http? Tcp?

2) какие-нибудь стандартные фреймворки / библиотеки / настройки / и т. Д. Уже реализуют это? (если возможно: Java, REST)


ОБНОВИТЬ

Я также изучил реализации heartbeat для WADL/WSDL, хотя не нашел ни одного для REST, проверил WebSockets... Также посмотрел TCP-keepalive, которые, кажется, подходят для этой задачи:

НО в соответствии с теми, что я должен был бы настроить что-то вроде:

  • tcp_keepalive_time = 5
  • tcp_keepalive_intvl = 1
  • tcp_keepalive_probes = 3

что кажется контррекомендованием (рекомендуется 2 часа, 10 минут, уже представленных как нечетное значение, переходят в 5 с вменяемым / безопасным, если это так - может быть, мое решение заранее...)

также где я должен настроить это? на London04 один или на мэйн тоже? (если я настрою его на Main - не затопит ли он клиента ->Main frontend communication? или могут ли NAT / etc между сайтами легко испортить намерение / поддержку keepalive?)

PS любая ссылка на RTFM приветствуется - я мог бы просто упустить что-то очевидное:)

2 ответа

Решение

Мой совет будет не использовать сердцебиение. Ваш внешний API должен вернуть 303 See Other с заголовками, указывающими, когда и где желаемый ответ может быть доступен.

Так что вы можете позвонить:

POST https://public.api/my/call

и вернуться

303 See Other
Location: "https://public.api/my/call/results"
Retry-After: 10

Если ваш сервер может догадаться, сколько времени потребуется для создания ответа, он должен учитывать это в Retry-After значение. Если позже GET вызов сделан на новое место, и результаты еще не сделаны, возвращают ответ с обновленным Retry-After значение. Так что, возможно, вы попробуете 10и если это не сработает, вы говорите клиенту подождать другого 110Всего две минуты.

В качестве альтернативы, используйте протокол, который разработан, чтобы оставаться открытым в течение длительных периодов времени, например, WebSockets.

Другие вопросы по тегам