Chúng tôi có ứng dụng web Node/express
đang phân phát nội dung tĩnh ngoài nội dung thông thường, qua express.static()
. Có máy chủ nginx
ở phía trước máy chủ hiện được định cấu hình thành gzip
các yêu cầu nội dung tĩnh này, nếu số user agent
phụ thuộc vào nó.Không thể tắt mã hóa chuyển chunked trong nginx với gzip cho các tài sản tĩnh được cung cấp từ Node backend
Tuy nhiên, mặc dù nginx
được làm gzip
như mong đợi, nó được thả Content-Length
đánh đầu từ nguồn gốc, và thiết lập Transfer-Encoding: chunked
để thay thế. Điều này phá vỡ bộ nhớ đệm trên CDN
của chúng tôi.
Dưới đây là các câu trả lời cho một yêu cầu tài sản tĩnh điển hình (một file JS
trong trường hợp này), từ backend nút, và từ nginx
:
Yêu cầu:
curl -s -D - 'http://my_node_app/res/my_js.js' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Connection: keep-alive' --compressed -o /dev/null
Tiêu đề phản hồi từ Node:
HTTP/1.1 200 OK
Accept-Ranges: bytes
Date: Wed, 07 Jan 2015 02:24:55 GMT
Cache-Control: public, max-age=0
Last-Modified: Wed, 07 Jan 2015 01:12:05 GMT
Content-Type: application/javascript
Content-Length: 37386 // <--- The expected header
Connection: keep-alive
Headers Phản hồi từ nginx:
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 07 Jan 2015 02:24:55 GMT
Content-Type: application/javascript
Transfer-Encoding: chunked // <--- The problematic header
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: public, max-age=0
Last-Modified: Wed, 07 Jan 2015 01:12:05 GMT
Content-Encoding: gzip
cấu hình hiện tại nginx
của chúng tôi cho các tài sản tĩnh location
trông giống như dưới đây:
nginx cấu hình:
# cache file paths that start with /res/
location /res/ {
limit_except GET HEAD { }
# http://nginx.com/resources/admin-guide/caching/
# http://nginx.org/en/docs/http/ngx_http_proxy_module.html
proxy_buffers 8 128k;
#proxy_buffer_size 256k;
#proxy_busy_buffers_size 256k;
# The cache depends on proxy buffers, and will not work if proxy_buffering is set to off.
proxy_buffering on;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 2s;
proxy_read_timeout 5s;
proxy_pass http://node_backend;
chunked_transfer_encoding off;
proxy_cache my_app;
proxy_cache_valid 15m;
proxy_cache_key $uri$is_args$args;
}
Như có thể thấy từ ở trên cấu hình, mặc dù chúng tôi đã đặt rõ ràng chunked_transfer_encoding
off
cho các đường dẫn như vậy theo tài liệu nginx
, có proxy_buffering
on
và có đủ lớn proxy_buffers
size
, phản hồi vẫn đang được chunked.
Chúng ta thiếu gì ở đây?
--edit 1: phiên bản info--
$ nginx -v
nginx version: nginx/1.6.1
$ node -v
v0.10.30
--edit 2: nginx
gzip config--
# http://nginx.org/en/docs/http/ngx_http_gzip_module.html
gzip on;
gzip_buffers 32 4k;
gzip_comp_level 1;
gzip_min_length 1000;
#gzip_http_version 1.0;
gzip_types application/javascript text/css
gzip_proxied any;
gzip_vary on;
Bạn đang nói nginx với gzip ở đâu? Nó đang làm một gzip streaming, mà chunked là lựa chọn hợp lý duy nhất. Thay vào đó, bạn nên có các tài sản tĩnh ở dạng thô và gzipped và cấu hình nginx để phục vụ các nội dung gziped khi được yêu cầu. Nói cách khác trước gzip thay vì gzipping trên bay. – generalhenry
@generalhenry Tôi cũng đã thêm cấu hình 'gzip'. Bạn nói đúng rằng các tài sản đang được nén trên bay. Tôi cũng thấy mô-đun 'gzip_static' giúp bạn làm những gì bạn đã mô tả. Vì vậy, tôi đoán trong trường hợp của chúng tôi, chúng tôi sẽ phải lưu trữ các tài nguyên thô gzipped trên 'nginx' chính nó, cấu hình' gzip_static' và sau đó nó sẽ làm điều đúng. Hoặc, có chúng được xây dựng sẵn trong giai đoạn xây dựng nội dung của chúng ta trong 'Node', xây dựng một số thông minh trên đầu trang' express.static() 'để phục vụ một hoặc khác dựa trên yêu cầu hiện tại và tắt' gzip' trên ' nginx'. – kodeninja
Yeah gzip_proxied any; có vẻ là thủ phạm (tuyên bố từ chối trách nhiệm, tôi không phải là chuyên gia về nginx, tôi chỉ nghĩ về luồng) – generalhenry