У нас есть веб-приложение Node/express
, которое обслуживает статические ресурсы в дополнение к обычному контенту через express.static()
. Перед ним находится nginx
сервер, который в настоящее время настроен на gzip
эти запросы статических активов, если user agent
готов для этого.
Однако, хотя nginx
выполняет gzip
, как и ожидалось, он удаляет заголовок Content-Length
из источника и вместо этого устанавливает Transfer-Encoding: chunked
. Это нарушает кеширование нашего файла CDN
.
Ниже приведены ответы на типичный запрос статического актива (в данном случае файл JS
), от серверной части узла и от nginx
:
Запрос:
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
Заголовки ответа от узла:
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
Заголовки ответа от 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
Наша текущая конфигурация nginx
для статических ресурсов location
выглядит следующим образом:
Конфигурация nginx:
# 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;
}
Как видно из приведенной выше конфигурации, несмотря на то, что мы явно установили chunked_transfer_encoding
off
для таких путей в соответствии с документами nginx
, имеем proxy_buffering
on
и достаточно большое proxy_buffers
size
, ответ все еще разбивается на части.
Что нам здесь не хватает?
--Редактировать 1: информация о версии--
$ nginx -v
nginx version: nginx/1.6.1
$ node -v
v0.10.30
--Изменить 2: nginx
конфигурация gzip--
# 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;
gzip
. Вы правы, активы архивируются на лету. Я также видел модульgzip_static
, который помогает делать то, что вы описали. Так что, я думаю, в нашем случае нам придется либо разместить сырые + сжатые ресурсы на самомnginx
, настроитьgzip_static
, и тогда он сделает все правильно. Или сделайте их предварительно созданными на этапе создания активов вNode
, создайте некоторые умные устройства поверхexpress.static()
, чтобы обслуживать одно или другое в зависимости от текущего запроса, и отключитеgzip
наnginx
. - person kodeninja   schedule 08.01.2015gzip
наnginx
иchunked_transfer_encoding off
и установил заголовок в node.jsres.header('transfer-encoding', ''); res.header('Content-Length', 0);
все это не работает... - person user1575921   schedule 24.12.2015