天天看點

squid配合nginx的gzip壓縮的完美解決方案

Squid3.0之前,一直不能完美支援http1.1。是以對gzip内容的支援,始終有很多問題。我也看過很多文章,号稱解決了這個問題。但是其實一直沒有把問題說清楚。我今天試着把問題的原因和解決方法徹底說清楚。

squid不支援常見的gzip壓縮的原因,有以下兩點:

1,  squid隻支援gzip的靜态壓縮,不支援動态壓縮。具體一點說,就是response header裡必須有content-length, 不可以用chunked方式。

2,  response header中必須有Vary : Accept-Encoding

隻要具備以上幾點,squid就可以完美的識别壓縮和不壓縮的内容。

下面說一下nginx針對這個問題的解決方案:

nginx預設的NginxHttpGzipModule, 采用的是chunked方式的動态壓縮,而squid是不支援的。需要使用http_gzip_static_module這個子產品,進行pre-compress。

具體方法如下:

ngx_http_gzip_static_module was introduced in nginx 0.6.24. You must enable support at compile time:

    ./configure --with-http_gzip_static_module ...

配置檔案寫法:

    gzip             on

    gzip_static on;

    gzip_http_version   1.0;

    gzip_proxied        any;

    gzip_disable        "MSIE [1-6]\.";

    gzip_comp_level     9;

注意,這裡沒有加入gzip_vary on;。這是因為http_gzip_static_module這個子產品,隻給沒壓縮的内容加入了vary header,而不是所有内容都加。

是以不能打開這個參數。可以在nginx.conf中手動設定vary header。這樣不管壓縮與否,傳回的檔案都會被加上Vary: Accept-Encoding。

至此,nginx的gzip壓縮,就能夠被squid完美支援了。如果你使用Http1.0,就會傳回你沒壓縮的内容。如果你使用http1.1,并且發送Accept-Encoding:gzip,deflate,就會傳回壓縮後的内容。

PS: 我又發現了一個問題,就是squid的cache儲存問題。按照文檔上說,squid是根據url來緩存對象的。

      也就是說,一個url應該隻保留一個cache。如果你交替的申請壓縮的和不壓縮的内容,是會出現反複MISS的情況的。

      但是我實際測試的過程中,發現不是這樣的,交替的申請壓縮的和不壓縮的内容,是會一直HIT的。這說明squid是同時儲存兩份cache的(壓縮的和不壓縮的)。

squid是根據url來緩存對象的。

如果打開了broken_vary_encoding,就可以同時儲存兩份cache了。

繼續閱讀