Функция Google Cloud при извлечении из подписки Pub / Sub вызывает исключение - превышен крайний срок - PullRequest
2 голосов
/ 01 февраля 2020

У меня есть функция Google Cloud для чтения Python 3.7 из подписки Pub / Sub в синхронном режиме извлечения.

После работы в течение часа в течение часа, он генерирует трассировку стека исключений:

Трассировка (последний вызов последнего): Файл
"/ env / local / lib / python3 .7 / site-packages / google / api_core / grpc_helpers.py ",
строка 57, в error_remapped_callable
вернуть вызываемый файл _ (* args, ** kwargs)" / env / local / lib /python3.7/site-packages/grpc/_channel.py ", строка 824,
in call
return _end_unary_response_blocking (файл состояния, вызова, False, None)" / env /local/lib/python3.7/site-packages/grpc/_channel.py ", строка
726, в _end_unary_response_blocking
повысить _InactiveRpcError (состояние) grp c ._ channel._InactiveRpcError: <_InactiveR RP C, оканчивающийся на: status = <br>StatusCode.DEADLINE_EXCEEDED details = "Крайний срок превышен"
debug_error_string =
"{" создан ":" @ 1580454091.145703535 "," описание ":" Ошибка получена от
peer
ipv4: 74.125.202.95: 443 "," file ":" src / core / lib / surface / call. cc "," file_line ": 1056," grpc_ message ":" Срок исполнения
Превышено "," grpc_status ": 4}"

Вышеуказанное исключение было прямой причиной следующего исключения:

Traceback (последний вызов был последним): файл
"/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py",
строка 346 , в run_http_function
result = _function_handler.invoke_user_function (flask .request) Файл
"/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py" ,
строка 217, в invoke_user_function
return call_user_function (request_or_event) Файл "/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py",
строка 210, в call_user_function
вернуть self._user_function (request_or_event) Файл "/user_code/main.py", строка 39, в итерации
response = sub.pull (sub_path, MAX_MESSAGES) Файл "/ env / local / lib / python3 .7 / site-packages / google / cloud / pubsub_v1 / _gapi c .py ",
строка 40, в
fx = лямбда-сам, * a, ** kw: wrapped_fx ( self.api , * a, ** kw) # noqa File
"/env/local/lib/python3.7/site-packages/google/cloud/pubsub_v1/gapic/subscriber_client.py",
строка 1005 , в запросе pull
, retry = retry, timeout = timeout, metadata = File metadata File "/env/local/lib/python3.7/site-packages/google/api_core/gapic_v1/method.py",
строка 143, вызов
возврат wrapped_fun c (* args, ** kwargs) Файл "/env/local/lib/python3.7/site-packages/google/ api_core / retry.py ",
строка 286, в retry_wrapped_fun c
on_error = on_error, File" /env/local/lib/python3.7/site-packages/google/api_core/retry. py ",
строка 184, в retry_target
return target () File" /env/local/lib/python3.7/site-packages/google/api_core/timeout.py",
line 214, в func_with_timeout
return fun * Файл 1087 * (* args, ** kwargs) "/env/local/lib/python3.7/site-packages/google/api_core/grpc_helpers.py",
строка 59, в error_remapped_callable
six.raise_from (exceptions.from_grpc_error (ex c), ex c) Файл "", строка 3, в rai se_from
google.api_core.exceptions.DeadlineExceeded: 504 Превышен крайний срок

О чем это? Это ожидаемый результат или результат какой-то проблемы с конфигурацией? Если и следовало ожидать, как это должно быть обработано?

В документации (источник представления: https://googleapis.dev/python/pubsub/latest/subscriber/api/client.html) по запросу ничего не говорится о том, что это возможное исключение.

Я подтверждаю сообщения сразу после завершения проверки. Я разрешаю выполнять только одну функцию за раз. У меня есть 600-секундный срок подтверждения. Кажется, что количество извлекаемых блоков сообщений не превышает 100. Если речь идет о невозможности подтверждения сообщения, похоже, что ошибку можно исправить гораздо лучше.

1 Ответ

2 голосов
/ 04 февраля 2020

Это исключение вызывается клиентом, когда в подписке нет сообщений для чтения. Это известная проблема из последних версий библиотеки PubSub> = 1.0.0. При необходимости вы можете вернуться к версии 0.45.0, где этой проблемы не было.

Однако в качестве обходного пути вы можете перехватить исключение DeadlineExceeded и повторить операцию снова. Кроме того, на основе комментария к Hemang приведен небольшой обезьян-патч, который вы можете добавить в свой работающий код, который может помочь получить то же поведение, что и в версии 0.45.0.

from google.cloud.pubsub_v1.gapic import subscriber_client_config as sub_config
sub_config.config['interfaces']['google.pubsub.v1.Subscriber']['retry_params']['messaging']['initial_rpc_timeout_millis'] = 25000

Наконец, имейте в виду, что при использовании синхронного извлечения наличие большого числа невыполненных запросов извлечения помогает снизить задержку доставки , что, в свою очередь, может привести к более высоким задержкам запросов извлечения (и ошибок DeadlineExceeded). Хотя, если задержка имеет решающее значение для приложения, вы можете рассмотреть возможность использования StreamingPull

...