SSE (Server-Sent Events)의 경우 어떤 Nginx 프록시 구성이 적합합니까? 질문을 읽었으며 사용할

Sgin에 적합한 Nginx 구성에 대한 여러 가지 질문을 읽었으며 사용할 설정에 관한 몇 가지 혼란스러운 결과가 나왔습니다.

정답은 무엇입니까?



답변

장기 연결

SSE (Server-Sent Events)는 오래 실행되는 HTTP 연결 **이므로 초보자에게는 다음이 필요합니다.

proxy_http_version 1.1;
proxy_set_header Connection "";

참고 : HTTP / 1.1의 TCP 연결은 기본적으로 영구적이므로 연결 헤더를 비워두면 올바른 작업이며 Nginx 제안입니다.

청크 전송 인코딩

이제 제쳐두고; SSE 응답은 전송할 데이터 양을 알 수 없기 때문에 Content-Length 헤더를 설정하지 않습니다. 대신 스트리밍 연결을 허용하는 Transfer-Encoding 헤더 [0] [1]를 사용해야합니다. 참고 : Content-Length를 추가하지 않으면 대부분의 HTTP 서버가 설정 Transfer-Encoding: chunked;됩니다. 이상하게도 HTTP 청크는 경고하고 혼란을 야기합니다.

혼란은 W3 EventSource 설명의 Notes 섹션에서 다소 모호한 경고로 인해 발생합니다.

저자는 HTTP 청킹이이 프로토콜의 신뢰성에 예기치 않은 부정적인 영향을 미칠 수 있음을주의해야합니다. 가능한 경우 메시지 속도가 중요하지 않은 경우를 제외하고 이벤트 스트림을 제공하기 위해 청킹을 비활성화해야합니다.

Transfer-Encoding: chunked;SSE에게는 나쁜 일 이라고 믿게 될 것입니다. 그러나 이것은 반드시 그런 것은 아니며 웹 서버가 청크를 수행 할 때만 발생합니다 (데이터에 대한 정보를 모름). 따라서 대부분의 게시물은 chunked_transfer_encoding off;일반적인 경우에는 추가 할 필요가 없다고 제안합니다 [3].

버퍼링 (실제 문제)

대부분의 문제는 앱 서버와 클라이언트 사이에 모든 유형의 버퍼링이 발생합니다. 기본적으로 [4], Nginx에 사용하는함으로써
proxy_buffering on(도에서 살펴 uwsgi_bufferingfastcgi_buffering응용 프로그램에 따라) 당신이 당신의 클라이언트에 나가 원하는 청크를 버퍼링 할 수도 있습니다. SSE의 실시간 특성이 깨지기 때문에 이것은 나쁜 것입니다.

그러나 proxy_buffering off모든 것을 처리하는 대신 실제로 X-Accel-Buffering: noSSE 기반 응답에 대해서만 버퍼링을 해제하고 앱에서 오는 모든 응답에 대해 버퍼링을 해제하려면 애플리케이션 서버 코드에 응답 헤더로 를 추가하는 것이 가장 좋습니다 (가능한 경우). 섬기는 사람. 보너스 :이 또한 위해 작동 uwsgi하고 fastcgi.

해결책

따라서 실제로 중요한 설정은 실제로 앱 서버 응답 헤더입니다.

Content-Type: text/event-stream;
Cache-Control: no-cache;
X-Accel-Buffering: no;

연결이 너무 오랫동안 유휴 상태로 유지되지 않도록 핑 메커니즘을 구현할 가능성이 있습니다. Nginx가 설정을 사용하여 keepalive설정 한대로 유휴 연결을 닫을 위험이 있습니다.


[0] https://tools.ietf.org/html/rfc2616#section-3.6
[1] https://en.wikipedia.org/wiki/Chunked_transfer_encoding
[2] https://www.w3.org/TR / 2009 / WD-eventsource-20091029 / # text-event-stream
[3] https://github.com/whatwg/html/issues/515
[4] http://nginx.org/en/docs/http/ ngx_http_proxy_module.html # proxy_buffering
[5] https://tools.ietf.org/html/rfc7230#section-6.3
[6] https://gist.github.com/CMCDragonkai/6bfade6431e9ffb7fe88


답변