Мы разработали API REST с помощью Django
и mongoDB
(PyMongo
driver). Проблема заключается в том, что при некоторых запросах конечным точкам API курсор PyMongo
возвращает частичный ответ, который содержит меньше документов, чем должен (но его полностью действительный документ JSON).
Позвольте мне объяснить это на примере одного из наших представлений:
def get_data(key):
return collection.find({'key': key}, limit=24)
def my_view(request):
key = request.POST.get('key')
query = get_data(key)
res = [app for app in query]
return JsonResponse({'list': res})
Мы уверены, что имеется более 8000 документов, соответствующих запросу, но в
некоторые звонки мы получаем меньше 24 результатов (даже ноль). Первая проблема, которую мы имеем
что у нас в нашем коде было более одного определения MongoClient
. Решая это, количество случаев проблемы уменьшилось, но у нас все еще было много вызовов.
После всех этих исследований мы разработали тест, в котором мы одновременно выполнили 16 асинхронных запросов к серверу. При таком подходе мы могли бы воспроизвести проблему. По каждому из этих 16 запросов 6-8 из них имели частичные результаты. После выполнения этого теста мы сократили количество процессов uWsgi
s до 6 и перезапустили сервер. Все результаты были хорошими, но после применения еще одной большой нагрузки на сервер проблема снова началась. На этом этапе мы перезапустили сервис uwsgi, и снова все было в порядке. В этом последнем эксперименте мы теперь поняли, что при запуске службы uwsgi все работает правильно, но после определенного периода времени и большой нагрузки сервер снова начинает возвращать частичные или пустые результаты.
Последнее исследование, которое мы провели, заключалось в том, чтобы запустить API с помощью python manage.py
с DEBUG=False
, и у нас была проблема снова после определенного периода времени в этой ситуации.
Мы не можем понять, в чем проблема и как ее решить. Одна из причин, по которой мы можем думать, заключается в том, что Django закрывает соединения pymongos до завершения. Поскольку возвращаемый результат является допустимым JSON.
Наш стек:
- nginx (без кэширования)
- uWsgi
- MemCached (отключено во время процедуры отладки)
- Django (v1.8 на python 3)
- PyMongo (v3.0.3)
Ваша помощь действительно оценена.
Обновление:
Монго версия:
db version v3.0.7
git version: 6ce7cbe8c6b899552dadd907604559806aa2e9bd
- Мы запускаем одиночный экземпляр
mongod
. Нет осколков/репликации. -
Мы создаем соединение, используя этот фрагмент:
con = MongoClient ('localhost', 27017)