@kkolorid

Почему сервер на Docker не справляется с aiohttp запросами?

Доброго времени суток. Пытаюсь воспользоваться данным Python-приложением - https://github.com/rahiel/open_nsfw-- Оно написано на Python, использует aiohttp библиотеку и по мануалу собирается/запускается через Докер. Если поднимаю это всё дело на виртуалке и с компа делаю одноразовые запросы - всё работает. Даже если в ВМ циклом с нескольких консолей запустить скрипт - работает. Но когда я пытаюсь слать запросы на сервер из своего Python приложения через aiohttp - сервер часто даёт 504 ошибку и в целом, работает не адекватно. Docker отвечает:

Error handling request
Error handling request
Error handling request
^C======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7face6e61d68>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7facde557388>, 5138.691)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde68eb40>, 4843.989)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde557c10>, 5124.785)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde68ea08>, 5135.462)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facf7ed0800>, 5124.289)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde52ece0>, 5130.191)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde557590>, 5137.217)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde5cf6c8>, 5128.721)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde59ca08>, 5119.731)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde52e0b0>, 5112.963), (<aiohttp.client_proto.ResponseHandler object at 0x7facde512c10>, 5113.93)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde52ef50>, 5133.297)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde7999a0>, 5136.193)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7face40f4ad8>, 5137.71)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde5574c0>, 5129.21)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde878250>, 4843.473)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde52e800>, 5107.494), (<aiohttp.client_proto.ResponseHandler object at 0x7facde52ea70>, 5107.516), (<aiohttp.client_proto.ResponseHandler object at 0x7facde52e590>, 5111.026), (<aiohttp.client_proto.ResponseHandler object at 0x7facde52eba8>, 5136.718)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde5cf5f8>, 5119.217), (<aiohttp.client_proto.ResponseHandler object at 0x7facde6f5048>, 5126.76)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde52ea08>, 5121.286)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7face409d6c8>, 5130.681)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde5570b0>, 5126.269)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde512d48>, 5122.311)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde52cb40>, 5120.225)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde557528>, 5134.891)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7face48152b8>, 5108.08)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde512730>, 5107.541), (<aiohttp.client_proto.ResponseHandler object at 0x7facde52c798>, 5133.84)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde504320>, 5138.2)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde52e528>, 5120.744)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7face4815d48>, 5134.35)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde52cdb0>, 5107.515), (<aiohttp.client_proto.ResponseHandler object at 0x7facde52c660>, 5108.589), (<aiohttp.client_proto.ResponseHandler object at 0x7facde7d52b8>, 5123.794)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde52e6c8>, 5125.281)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x7facde59c798>, 5118.149)]']
connector: <aiohttp.connector.TCPConnector object at 0x7face6e61dd8>


Или Докер не справляется с такими нагрузками или сам скрипт действительно "Unclosed client session
client_session: " и нужно просто что-то в репозитории поправить. Хотя не понятно, почему в других случаях работает?..

Гугл действительно говорит, что нужно в таких случаях где-то сессию aiohttp не забывать закрывать. Вот тут aiohttp в исходниках - https://github.com/rahiel/open_nsfw--/blob/master/... - попробовал вставлять закрытие сессии в нём и пересобирал проект локально - без толку.

Попробовал закастылить через Flask. На нем сделал сервер, через который просто нативно, якобы через консоль, запускаю скрипт, который уже на др порте обращается к докеру - работает, хоть и медленно + вм в шоке по нагрузке, иногда ответы мимо летят. Вообщем, тоже не подходит.

Создал вопрос в репозитории, но хозяину некогда поддерживать проект - https://github.com/rahiel/open_nsfw--/issues/3

Общая задача - получить заявленный функционал в виде сервера с api, на которые я могу слать много одновременных запросов средствами aiohttp.
  • Вопрос задан
  • 862 просмотра
Пригласить эксперта
Ответы на вопрос 1
zenwalker
@zenwalker
0xABADBABE
1. Если docker на сервере стоит за nginx или другой проксей, там может быть выставлено ограничение на ответ бэкенда (у nginx по умолчанию 30 сек), после чего соединение рвется, а клиент получает 504.

2. aiohttp применен не к месту, вызываемая здесь https://github.com/rahiel/open_nsfw--/blob/master/... функция classify() — не асинхронная и будет блокировать процесс, до тех пор, пока не завершится. Одним словом, у вас обычное однопоточное приложение, из коробки несколько одновременных запросов такое решение обработать не сможет. Нужно либо запускать несколько контейнеров, с балансировщиком перед ними, либо как-то менять подход, например запускать классификатор в отдельном пулле процессов через loop.run_in_executor() или разнести API и классификатор в разные сервисы, поставив между ними очередь сообщений.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы