Время ожидания urfetch в движке приложения python истекло

У меня есть два запущенных экземпляра приложений движка приложений, которые я хочу взаимодействовать с интерфейсом Restful. Как только данные одного из них обновляются, он вызывает веб-перехватчик на втором, который извлекает свежую копию данных для своей собственной системы. Внутри «site1» у меня есть:

 from google.appengine.api import urlfetch

 url = www.site2.com/data_updated
 result = urlfetch.fetch(url)

Внутри обработчика для data_updated на «site2» у меня есть:

 url = www.site1.com/get_new_data
 result = urlfetch.fetch(url)

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

 DeadlineExceededError: ApplicationError: 5 

Может ли кто-нибудь дать представление о том, что может происходить?

Спасибо - Ричард


person probably at the beach    schedule 17.06.2011    source источник
comment
urlfetch имеет некоторые несоответствия, как я заметил, вы пробовали стандартный python urllib2.urlopen(url).read() вместо urlfetch.fetch(url)   -  person Adithya Surampudi    schedule 17.06.2011
comment
Это на dev_appserver? Сервер dev_app является однопоточным, поэтому, если что-то попытается извлечь из него во время обработки запроса, произойдет тайм-аут.   -  person Nick Johnson    schedule 20.06.2011
comment
@Nick - Привет, Ник, нет, оба сервера работали на движке производственного приложения.   -  person probably at the beach    schedule 20.06.2011
comment
@ Adithya - да, мы тоже это пробовали.   -  person probably at the beach    schedule 20.06.2011


Ответы (5)


urlfetch App Engine не всегда ведет себя так, как ожидается, у вас есть около 10 секунд, чтобы получить URL-адрес. Предполагая, что URL-адрес, который вы пытаетесь получить, запущен и работает, вы сможете перехватить DeadlineExceededError, вызвав from google.appengine.runtime import apiproxy_errors, а затем заключив вызов urfetch в блок try/except, используя except apiproxy_errors.DeadlineExceededError:.

Соответствующий ответ здесь.

person Can Bascil    schedule 18.06.2011

Изменение метода с

  result = urlfetch.fetch(url)

to

  result = urlfetch(url,deadline=2,method=urlfetch.POST)

исправил ошибки Крайнего срока.

Из документации по urlfetch:

deadline Максимальное время ожидания ответа от удаленного узла в секундах. Если удаленный хост не отвечает в течение этого времени, возникает ошибка DownloadError.

Время, затраченное на ожидание запроса, не засчитывается в квоту ЦП для запроса. Это действительно учитывается в таймере запроса. Если время таймера запроса приложения истекает до возврата вызова URL Fetch, вызов отменяется.

Крайний срок может составлять максимум 60 секунд для обработчиков запросов и 10 минут для очереди задач и обработчиков заданий cron. Если крайний срок равен None, крайний срок устанавливается равным 5 секундам.

person probably at the beach    schedule 18.06.2011

Пробовали ли вы вручную запрашивать URL-адреса (www.site2.com/data_updated и www.site1.com/get_new_data) с помощью curl или иным образом, чтобы убедиться, что они отвечают в течение установленного срока? Даже если объем данных, которые необходимо передать, невелик, возможно, возникла проблема с обработчиком, из-за которой возвращаются результаты с задержкой.

person Dan    schedule 17.06.2011
comment
Привет Дэн, да, я пытался это сделать. Оба они отвечают нормально через время ‹ несколько секунд - person probably at the beach; 18.06.2011

Здесь проблема не в количестве передаваемых данных, а в задержке.

Если приложению, с которым вы разговариваете, часто требуется> 10 секунд для ответа, вам придется использовать «прокси-сервер обратного вызова» на другой облачной платформе (EC2 и т. д.). предполагается несколько ослабить временные ограничения urfetch.

Если среднее время отклика составляет ‹ 10 секунд, и только относительно небольшое число запросов не работает, просто повторите попытку несколько раз. Ради вас я надеюсь, что вызовы являются идемпотентными (т. е. чтобы повторная попытка не имела побочных эффектов). Если нет, вы можете накатить свой собственный слой поверх — это немного болезненно, но работает нормально, это то, что мы делаем.

J

person Jan Z    schedule 18.06.2011
comment
(еще одна вещь, которая может застать вас врасплох, — это время запуска — если ваша служба данных холодная, первоначальный запрос может истечь по тайм-ауту. Попробуйте сохранить ее теплой с помощью некоторых запросов cron и посмотрите, поможет ли это?) - person Jan Z; 25.06.2011

В документе GAE теперь указано, что крайний срок может составлять 60 секунд:

result = urlfetch(url,deadline=60,method=urlfetch.POST)
person 1qazxsw2    schedule 03.11.2011