انجیناکس؛ شب ۲۷: SSE، buffering و پاسخ جریانی
فهرست نوشته
SSE یا رویدادهای ارسالی سرور، پیام را یکطرفه روی HTTP میفرستد. امشب تفاوت انتظار backend و تأخیر ناشی از buffering را اندازه میگیریم.
این جلسه بخشی از دورهٔ انجیناکس در ۵۰ شب است. قرارداد آزمایشگاه، مسیرها و روال اعمال تغییر در راهنمای دوره آمده است.
محیط: app و Python 3؛ backend تازه روی 8082 و مسیر /events/.
جریان قابل مشاهده#
فایل events.py:
import time
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
class Events(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-Type", "text/event-stream")
self.send_header("Cache-Control", "no-cache")
self.end_headers()
try:
for n in range(5):
self.wfile.write(f"data: lab-{n}\n\n".encode())
self.wfile.flush()
time.sleep(2)
except (BrokenPipeError, ConnectionResetError):
pass
ThreadingHTTPServer(("127.0.0.1", 8082), Events).serve_forever()
در app:
location /events/ {
proxy_pass http://127.0.0.1:8082;
proxy_http_version 1.1;
include /etc/nginx/snippets/lab-proxy-headers.conf;
proxy_set_header Connection "";
proxy_buffering off;
proxy_cache off;
gzip off;
proxy_read_timeout 15s;
}
curl -N --cacert ~/nginx-lab/pki/ca.crt \
--resolve app.nginx.test:443:192.168.57.10 https://app.nginx.test/events/
-N بافر خروجی curl را خاموش میکند. باید پیامها تقریباً هر دو ثانیه برسند، نه همه در پایان. مستقیم روی 8082 و سپس از proxy مقایسه کن؛ لایههای بعدی نیز میتوانند بافر کنند. هدر X-Accel-Buffering از برنامه نیز میتواند روی رفتار اثر بگذارد.
سه نوع کنترل متفاوت#
proxy_buffering به پاسخ backend، proxy_request_buffering به body کلاینت و timeout خواندن به فاصلهٔ داده مربوطاند. خاموش کردن بافر همهٔ سایتها میتواند کارگر یا upstream را طولانیتر درگیر کند؛ تنظیم فقط روی مسیر لازم باشد.
آزمایش و بازگشت: فاصلهٔ پیام را از timeout بیشتر کن و قطع شدن را ببین. دوباره به مقدار سالم برگردان و سپس location و backend آزمایشگاهی را حذف کن. برنامهٔ streaming باید heartbeat و بازیابی اتصال داشته باشد.
منبع: proxy_buffering ، SSE .