Django + Activemq и долго работающие соединения в веб-сервере - PullRequest
0 голосов
/ 25 мая 2018

Я уже много лет использую stomp.py и stompest для взаимодействия с activemq, но это в основном происходит с автономными демонами Python.

Я хотел бы использовать эти две библиотеки с веб-серверадля связи с бэкэндом, но у меня возникают проблемы с поиском способа сделать это без создания нового соединения при каждом запросе.

Существует ли стандартный подход для безопасной обработки TCP-соединений в веб-сервере?В других языках какой-то глобальный объект на этом уровне будет использоваться для пула соединений.

1 Ответ

0 голосов
/ 26 мая 2018

HTTP - синхронный протокол.Каждый ожидающий клиент потребляет ресурсы сервера (процессор, память, файловые дескрипторы), ожидая ответа.Это означает, что веб-сервер имеет для быстрого ответа.Веб-сервер HTTP не должен блокировать внешних длительных процессов при ответе на запрос.

Решение состоит в том, чтобы обрабатывать запросы асинхронно.Существует два основных варианта:

  1. Использовать опрос.

    POST выдвигает новую задачу в очередь сообщений:

    POST /api/generate_report
    {
         "report_id": 1337
    }
    

    GET проверяет MQ (или базу данных) на результат:

    GET /api/report?id=1337
    {
        "ready": false
    }
    
    GET /api/report?id=1337
    {
        "ready": true,
        "report": "Lorem ipsum..."
    }
    

    Асинхронные задачи в экосистеме Django обычно реализуются с использованием Celery , но вы можете использовать любой MQ напрямую.

  2. Использовать WebSockets.

Полезные ссылки:

  1. Что такое Long-Polling, Websockets, Отправленные на сервер события (SSE) и Comet?
  2. https://en.wikipedia.org/wiki/Push_technology
  3. https://www.reddit.com/r/django/comments/4kcitl/help_in_design_for_long_running_requests/
  4. https://realpython.com/asynchronous-tasks-with-django-and-celery/
  5. https://blog.heroku.com/in_deep_with_django_channels_the_future_of_real_time_apps_in_django

Редактировать:

Вотпример псевдокода о том, как можно повторно использовать соединение с MQ:

projectName/appName/services.py:

import stomp

def create_connection():
    conn = stomp.Connection([('localhost', 9998)])
    conn.start()
    conn.connect(wait=True)
    return conn

print('This code will be executed only once per thread')
activemq = create_connection()

projectName/appName/views.py:

from django.http import HttpResponse
from .services import activemq

def index(request):
    activemq.send(message='foo', destination='bar')
    return HttpResponse('Success!')
...