Поток событий в буфере nginx в образе Docker

У меня есть бэкэнд API REST с python / flask и я хочу передать ответ в потоке событий. Все работает внутри док-контейнера с помощью nginx / uwsgi ( https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/).

API работает нормально, пока не доходит до потока событий. Похоже, что-то (вероятно, nginx) буферизует "доходность", потому что клиентом ничего не получено, пока сервер не завершит вычисление и все не будет отправлено вместе.

Я попытался адаптировать настройки nginx (в соответствии с инструкциями для образа докера) с помощью дополнительного файла config (nginx_streaming.conf), в котором говорится:

server {
  location / {
        include uwsgi_params;
        uwsgi_request_buffering off;
  }
}

dockerfile:

FROM tiangolo/uwsgi-nginx-flask:python3.6
COPY ./app /app
COPY ./nginx_streaming.conf /etc/nginx/conf.d/nginx_streaming.conf

Но я не очень знаком с настройками nginx и уверен, что я здесь делаю ^^ По крайней мере, это не работает.. какие-либо предложения?

Моя реализация на стороне сервера:

from flask import Flask
from flask import stream_with_context, request, Response
from werkzeug.contrib.cache import SimpleCache
cache = SimpleCache()
app = Flask(__name__)

from multiprocessing import Pool, Process
@app.route("/my-app")
def myFunc():
    global cache

    arg = request.args.get(<my-arg>)
    cachekey = str(arg)
    print(cachekey)

    result = cache.get(cachekey)
    if result is not None:
        print('Result from cache')
        return result
    else:
        print('object not in Cache...calculate...')
        def calcResult():
            yield 'worker thread started\n'

            with Pool(processes=cores) as parallel_pool:
                [...]

            yield 'Somewhere in the processing'
            temp_result = doSomethingWith(

            savetocache = cache.set(cachekey, temp_result, timeout=60*60*24) #timeout in seconds

            yield 'saved to cache with key:' + cachekey +'\n'
            print(savetocache, flush=True)
            yield temp_result

        return Response(calcResult(), content_type="text/event-stream")

if __name__ == "__main__":
    # Only for debugging while developing
    app.run(host='0.0.0.0', debug=True, port=80)

3 ответа

Я столкнулся с той же проблемой. Попробуйте изменить

return Response(calcResult(), content_type="text/event-stream")

в

return Response(calcResult(), content_type="text/event-stream", headers={'X-Accel-Buffering': 'no'})

столкнулся с той же проблемой, что и буферизация Nginx. Когда я запускаю приложение без докера, оно работает как положено.

После ответа от @u-rizwan здесь я добавил это в /etc/nginx/conf.d/mysite.conf и это решило проблему:

add_header  X-Accel-Buffering  no;

Я добавил это в location /, но, вероятно, будет хорошей идеей поместить его в определенное место потока событий (у меня здесь пример использования интрасети с низким трафиком).

Примечание. Похоже, что nginx может удалять этот заголовок по умолчанию, если он поступает из приложения: https://serverfault.com/questions/937665/does-nginx-show-x-accel-headers-in-response

Другие вопросы по тегам