Каков наилучший уровень сжатия ggin в nginx?

44

Я использую кеш обратного прокси nginx с включенным gzip. Однако у меня возникли проблемы с HTTP-запросами приложений Android к моему веб-сервису Rails JSON. Кажется, когда я отключаю кеш обратного прокси, он работает нормально, потому что заголовок ответа приходит без gzip. Поэтому я думаю, что проблема вызвана gzip. Каков наиболее подходящий уровень сжатия gzip?

gzip               on;
gzip_http_version  1.0;
gzip_vary          on;
gzip_comp_level    6;
gzip_proxied       any;
gzip_types         text/plain text/css text/javascript application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss;
Chamnap
источник

Ответы:

18

Уровень сжатия gzip просто определяет степень сжатия данных по шкале от 1 до 9, где 9 является наиболее сжатым. Компромисс заключается в том, что для сжатия / распаковки наиболее сжатых данных обычно требуется больше всего работы, поэтому, если вы установите их достаточно высоко на большом веб-сайте, вы можете почувствовать его эффект.

Похоже, ваши проблемы больше связаны с заголовками HTTP в запросах. Обычно сжатый gzip HTTP-трафик сопровождается Content-Encoding: gzipзаголовком. Если это где-то отбрасывается, то клиент может не знать, что нужно распаковывать ответ.

growse
источник
Как отключить ответ gzip с помощью заголовка http-запроса от клиента? Я пробую Accept-Encoding: '', но это не работает.
Чамнап
Из RFC2616 ( w3.org/Protocols/rfc2616/rfc2616-sec14.html ) я думаю, что вы хотите просто «Accept-Encoding:», после чего ничего не происходит.
Growse
Да, я добавил заголовок Accept-Encoding с пустой строкой с надписью плаката на Mozilla, а ответ вернулся без Content-Encoding: 'gzip'. Однако в приложении для Android оно всегда возвращается обратно в gzip. Я проверил, что было кешировано в каталогах кеша прокси, nginx кеширует содержимое gzip, так что, вероятно, это ответы обратно в gzip. Как это решить?
Chamnap
Некоторые источники предполагают, что ресурсы распаковки не увеличиваются с увеличением уровня сжатия. Ресурсы фактически уменьшаются в некоторых случаях при увеличении уровня сжатия. stackoverflow.com/questions/28452429/…
user2208096
90

Я проверил это в nginx 1.3.9 с двумя файлами, и это были результаты, которые я получил для различных уровней:


text/html - phpinfo ():

0    55.38 KiB (100.00% of original size)
1    11.22 KiB ( 20.26% of original size)
2    10.89 KiB ( 19.66% of original size)
3    10.60 KiB ( 19.14% of original size)
4    10.17 KiB ( 18.36% of original size)
5     9.79 KiB ( 17.68% of original size)
6     9.62 KiB ( 17.37% of original size)
7     9.50 KiB ( 17.15% of original size)
8     9.45 KiB ( 17.06% of original size)
9     9.44 KiB ( 17.05% of original size)

application/x-javascript - jQuery 1.8.3 (без сжатия):

0    261.46 KiB (100.00% of original size)
1     95.01 KiB ( 36.34% of original size)
2     90.60 KiB ( 34.65% of original size)
3     87.16 KiB ( 33.36% of original size)
4     81.89 KiB ( 31.32% of original size)
5     79.33 KiB ( 30.34% of original size)
6     78.04 KiB ( 29.85% of original size)
7     77.85 KiB ( 29.78% of original size)
8     77.74 KiB ( 29.73% of original size)
9     77.75 KiB ( 29.74% of original size)

Я не уверен, насколько это репрезентативно, но это должно служить примером. Кроме того, я не принял во внимание использование процессора, но из этих результатов идеальный уровень сжатия находится между 4и 6.


Кроме того, если вы используете gzip_staticмодуль, вы можете предварительно сжать файлы (в PHP):

function gzip_static($path)
{
    if ((extension_loaded('zlib') === true) && (is_file($path) === true))
    {
        $levels = array();
        $content = file_get_contents($path);

        foreach (range(1, 9) as $level)
        {
            $levels[$level] = strlen(gzencode($content, $level));
        }

        if ((count($levels = array_filter($levels)) > 0) && (min($levels) < strlen($content)))
        {
            if (file_put_contents($path . '.gz', gzencode($content, array_search(min($levels), $levels)), LOCK_EX) !== false)
            {
                return touch($path . '.gz', filemtime($path), fileatime($path));
            }
        }
    }

    return false;
}

Это позволяет получить наилучшее возможное сжатие, не жертвуя процессором при каждом запросе.

Аликс Аксель
источник
это согласуется с результатами на weblogs.asp.net/owscott/iis-7-compression-good-bad-how-much, которые показывают значительное снижение уровней сжатия после уровней 5 и 6.
Джефф Этвуд,
6

Если вы действительно можете сэкономить ресурсы ЦП, вы можете использовать 9, но для большинства сайтов достаточно значения 2, так как gzip не сильно уменьшает файл после уровня 1.

Изменить: Я посмотрел на Amazon CloudFront, и он, кажется, использует уровень 6, вероятно, потому, что этот уровень быстрее выполняет декомпрессию, таким образом улучшая производительность рендеринга страницы.

DiegoG
источник
Это не правильно
Calumbrodie
2
Облако, ты объяснишь, что в этом плохого? В любом случае, я обновил ответ, я исследовал немного больше, и я вижу, что сайты, такие как Amazon CloudFront, используют уровень сжатия 6, вероятно, потому что это лучше всего по скорости распаковки (таким образом, страницы будут загружаться быстрее).
DiegoG
1) Разница между 2 и 6 нетривиальна, она может доходить до 10-15%, посмотрите на данные или попробуйте сами. 2) уровень сжатия не влияет на сложность распаковывать (см stackoverflow.com/questions/28452429/... )
calumbrodie
0

Если у вас большой веб-сайт и вы хотите иметь полный уровень сжатия (9), лучше всего разместить статический контент в Amazon S3 или аналогичных сервисах хранения объектов и загрузить сжатые файлы.

Вы все еще хотели бы использовать nginx для сжатия своего HTML, поэтому лучше сохранить это значение на нормальном уровне, я использую 5 там.

Афтаб Навид
источник
Я хотел бы использовать ваше предложение, но в настоящее время я не включил comp_levelв свою конфигурацию, поэтому я не могу сказать, на каком уровне я сейчас нахожусь. Знаете ли вы, что по умолчанию? Источник?
Хасан Бэйг