ホームページ  >  記事  >  運用・保守  >  Nginxリクエスト圧縮を実装する方法

Nginxリクエスト圧縮を実装する方法

WBOY
WBOY転載
2023-05-15 11:55:061495ブラウズ

1. はじめに

リクエスト圧縮とは、ネットワークの送信圧力を軽減し、送信効率を向上させるために、Nginx を通じてサーバーの結果を圧縮してクライアントに送信することです。

一般的なリクエスト メソッドは、gzip と brotli (Google) の 2 つで、brotli と同等であり、より効率的です。詳細は後ほど説明します。

圧縮の要求は動的圧縮と静的圧縮に分かれており、動的圧縮を行うと Nginx 内の sendfile が失敗します。一部の変更されていないコンテンツについては、静的圧縮を使用してリクエストの効率を向上させることができます。

リクエストの結果を圧縮するために使用されます。クライアントとサーバーの両方が圧縮プロトコルをサポートする必要があります。サーバーは結果を圧縮し、クライアントはデータを解凍します。圧縮はサーバー側でパフォーマンス効率の一部を占めます。この損失は圧縮レベルに依存し、レベルが高いほど損失が大きくなります。ネットワークの送信圧力を軽減できます。

圧縮はプロキシ リクエストに対してのみ有効です。

2. リクエスト圧縮プロセス

Nginxリクエスト圧縮を実装する方法

実行プロセスは次のとおりです: クライアントがサーバーにリクエストを送信し、nginx がリクエストを受信した後、リクエストを送信すると、Nginx と上流サーバーの間にネットワーク チャネルが作成され、両者の間でデータが送信されます。ここで圧縮操作がオンになっている場合、Nginx は結果データを圧縮してデータを返しますブラウザが nginx からリクエストを受信すると、まずリクエスト ヘッダーを処理し、圧縮プロトコルがあることを確認します。次に、現在のブラウザがそのプロトコルをサポートしているかどうかを判断します。サポートしている場合は、圧縮プロトコルを解凍します。データを取得し、ユーザーにデータを表示します。

圧縮をオンにすると、ユーザーは鈍感になり、送信圧力を軽減できます。ただし、結果のサイズがあまり変わらないため、画像やビデオを圧縮することはお勧めできません。Gzip はネットワーク送信用に圧縮されています。クライアントのサポートが必要です。サーバー側も、送信データの圧縮と送信データのサイズの縮小をサポートする必要があります。設定することができます。もちろん、圧縮率が高くなるほど、解凍と圧縮の時間は長くなり、より長くなります。サーバー側のプレッシャー。

3. Gzip 圧縮

3.1 gzip の概要

Gzip は GNUzip の略称で、UNIX システムでのファイル圧縮に最初に使用されました。 HTTP プロトコルでの Gzip エンコードは、Web アプリケーションのパフォーマンスを向上させるために使用されるテクノロジであり、Web サーバーとクライアント (ブラウザー) の両方が Gzip をサポートしている必要があります。現在、主流のブラウザ: Chrome、Firefox などはすべてこのプロトコルをサポートしており、一般的なサーバー: Apache、Nginx、IIS も Gzip をサポートしています。

Gzip の圧縮率は約 3 ~ 10 倍 (プレーン テキスト) であり、サーバーのネットワーク帯域幅を大幅に節約できます。実際のアプリケーションでは、すべてのファイルが圧縮されるわけではなく、通常は静的ファイル (js\css\html) のみが圧縮されます。 JPEG などのファイルは Gzip では十分に圧縮されず、圧縮により CPU リソースが消費されます。

それでは、Gzip はどのように圧縮するのでしょうか?簡単に言うと、Gzip 圧縮はテキスト ファイル内で類似した文字列を見つけて一時的に置き換えて、ファイル全体を小さくします。 HTML および CSS ファイルにはスペースやタグなどの繰り返し文字列が大量に含まれることが多いため、この形式の圧縮は Web に最適です。

Nginxリクエスト圧縮を実装する方法

3.2 gzip の使用

gzip モジュールは Nginx に組み込まれているため、他のデフォルトを追加する必要はなく、Nginx を構成してインストールするだけです。 。

使用範囲: http、サーバー、場所

Nginx は次のように構成されています

gzip on ;

  • 圧縮を有効にするかどうか。

  • デフォルト値: gzip off はデフォルトでオフになります

gzip_buffers 32 4k | 16 8k

  • ##圧縮バッファのサイズ。

  • デフォルト値: gzip_buffers 32 4k | 16 8k

gzip_comp_level 1 ;

  • 圧縮レベル1 ~ 9 の数字が大きいほど圧縮率が高くなります。

  • 圧縮速度が小さいほど、解凍速度は速くなり、圧縮率は小さくなります。

  • デフォルト値: gzip_comp_leve 1

gzip_http_version 1.1

  • gzip を使用する最小の http バージョン。

gzip_min_length

  • gzip 圧縮される応答の最小長を設定します。長さは、「Content-Length」応答ヘッダー フィールドによってのみ決定されます。

gzip_proxied 複数選択

  • アップストリーム サーバーが圧縮するかどうかを決定するためにさまざまなヘッドを返すには、2 つの一般的なものがあります: off Any

  • 一般に、キャッシュが有効になっている場合、キャッシュはすでに圧縮されているため、一部の詳細は回避できます。

  • off は制限されません。

  • リバース プロキシとして機能する場合、上流サーバーから返されるヘッダー情報を圧縮します。

  • expired - ヘッダー ヘッダーに「Expires」ヘッダー情報が含まれる場合、圧縮を有効にします。

  • no-cache - ヘッダー ヘッダーに「Expires」ヘッダー情報が含まれる場合、圧縮を有効にします。 contains 「Cache-Control:no-cache」ヘッダー情報が含まれます

  • no-store - ヘッダーに「Cache-Control:no-store」ヘッダー情報が含まれる場合、圧縮を有効にします

  • private - ヘッダーに「Cache-Control:private」ヘッダー情報が含まれる場合、圧縮を有効にします。

  • no_last_modified - ヘッダーに含まれない場合、圧縮を有効にします。 「Last-Modified」ヘッダー情報が含まれます

  • ##no_etag - ヘッダーに「ETag」ヘッダー情報が含まれていない場合に圧縮を有効にします

  • auth - 圧縮を有効にします、ヘッダーに「Authorization」ヘッダーが含まれる場合

  • any - 圧縮は無条件で有効になります。

gzip_vary on ;

  • 古いブラウザに適応するヘッダーを追加します: Accept-Encoding

  • #gzip_types:

    圧縮されるファイルの MIME タイプ。
  • gzip_disable:

    gzip の使用が禁止されているブラウザ。
  • #設定しないことをお勧めします
  • デフォルト値: gzip_disable 'msie6MSIE [4-6]\.MSIE 6.0'
  • location / {
      
      gzip off ;  # 开启gzip压缩
      gzip_buffers 32 4k ; # 设置缓冲区大小
      gzip_comp_level 5; # 设置压缩等级 1-9 
      gzip_disable 'msie6MSIE [4-6]\.MSIE 6.0';  # 禁止哪些浏览器不使用压缩
      gzip_http_version 1.1; # 设置压缩所需要的最低的http版本。 
      gzip_min_length 20 ; # 设置响应的数据最小限制,在这个限制之后再回进行压缩
      gzip_vary on ; # 增加一个header ,适用于老的浏览器 Vary:Accept-Encoding 
      gzip_proxied any; # 无条件启动压缩
      # 哪些mime类型的文件进行压缩 
      #gzip_types text/plain application/x-javascript text/css application/xml; 
      gzip_types
        text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
        text/javascript application/javascript application/x-javascript
        text/x-json application/json application/x-web-app-manifest+json
        text/css text/plain text/x-component
        font/opentype application/x-font-ttf application/vnd.ms-fontobject
        image/x-icon;
    }

    3.3 gzip リクエスト

gzip が開始されると、リクエストは nginx サーバーに送信され、nginx はすでに応答を生成しています。しかし、データはまだそこにあります それは生成されておらず、nginx は非同期応答リクエストであるため、特定のデータがどのくらいの大きさであるか彼は知りませんでした 彼はそれを段階的に実行しました 彼は最初にヘッダーを準備し、次にコンテンツをリクエストしました最後に、2 つのコンテンツを結合して圧縮し、最終的に送信しました。つまり、非同期であるため、具体的なサイズはわかりません。 Nginxリクエスト圧縮を実装する方法

彼は最初にリクエスト ヘッダーを返し、次にゆっくりとデータを読み取ります。

----------------------------------响应体-------------------------------------------------
Connection: keep-alive
Content-Encoding: gzip # 结果启动了gzip压缩 
Content-Type: application/json # 响应结果 
Date: Mon, 13 Feb 2023 09:13:19 GMT
Keep-Alive: timeout=65
Server: nginx/1.20.2
Transfer-Encoding: chunked # 传输的格式这个对应的就是length,这个是他会发送一个一个的包,当最后一个包是0表示传输结束
Vary: Accept-Encoding
 
 
 
------------------------------------请求头-----------------------------------------------
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
Host: 192.168.101.128
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36

注: 上記は動的圧縮です。つまり、すべてのリクエストが一度圧縮されます。これには、sendfile がサポートされていないという致命的な欠点があります。sendfile はデータのゼロ コピーであり、データはロードされませんnginx に転送しますが、ネットワーク インターフェイスはデータを送信しますが、gzip 動的圧縮をオンにすると、sendfile は無効になります。静的圧縮は使用できます。

マルチレイヤー Nginx を使用する場合は、サーバーに接続されている Nginx で Gzip を有効にすることをお勧めします。これにより、gzip がサポートされ、どのサーバーでも gzip が有効になります。

3.4 静的圧縮

Nginxリクエスト圧縮を実装する方法#静的圧縮を使用する理由

まず第一に、動的圧縮では sendfile を使用できませんが、静的圧縮ではこの問題が完全に解決されます。

静的圧縮は補完または拡張機能であり、要求されたリソース ファイルを事前に圧縮パッケージに圧縮できます。

まず、静的リソースは動的リソースよりも効率的である必要があり、圧縮後はディスク サイズを削減でき、ネットワーク チャネル リソースも節約できます。

静的圧縮とは

静的圧縮はリバース プロキシには適しておらず、リソース サーバーにのみ適しています。圧縮されたファイルをクライアントに渡すことができます。静的圧縮はリソース内にあります。パスの下にリソース ファイルと、対応する名前の圧縮パッケージがあります。また、Nginx は圧縮パッケージの検索を優先し、sendfile を通じてデータを直接渡します。

Nginx は圧縮ファイルをネットワーク経由で送信し、ブラウザは Nginx から送信された圧縮パッケージ ファイルを受信すると、それを解凍します。彼は、クライアントに送信する前に、圧縮パッケージ インターフェイスをクライアントに送信します。

3. 設定

http_gzip_static_module モジュールを使用すると、通常のファイルの代わりに、"" ファイル拡張子 (.gz) が付いた事前圧縮ファイルを送信できます。このモジュールはデフォルトでは構築されません。 --with-http_gzip_static_module 構成パラメータを使用して有効にする必要があります。このモジュールはプリコンパイルされたパッケージに含まれていないため、手動で追加する必要があります。このモジュールの機能は、圧縮されたパッケージを解凍することです。

with は内部モジュールで、add は外部モジュールです。

初めて nginx をインストールするときに使用します

./configure --prefix==/usr/local/nginx --with-hhtp_gzip_static_module

make && make install

すでに nginx をインストールした後、nginx クライアントをアップグレードするときに、コマンド
./configure --prefinx==/usr/local/nginx --with-http_gzip_static_module

make を使用します。前のファイル
objsのnginxプログラムを/usr/local/nginx/sbin·にコピーします、元のnginxプログラムをバックアップする必要があることに注意してください。

構文: gzip_static on | off | always;

機能: 静的圧縮機能をオンにするかどうか。

パラメータ値:

on: 静的圧縮をオンにし、ブラウザがサポートしているかどうかを確認し、サポートしていない場合は静的圧縮を実行しません。
  • ##off: 静的圧縮をオフにする

  • always: ブラウザーが静的圧縮機能をサポートしているかどうかに関係なく、静的圧縮を使用するかどうか。

  • これにより問題が発生します。クライアントがこれをサポートしていない場合、解凍できません。ディスク上に非圧縮ファイルがない場合、デフォルトで 404 が報告されます. ngx_http_gunzip_moduleと連携できます. モジュールの使い方。
    • #デフォルト値: gzip_static on

  • 適用対象: http、server、location

使用的需要将本地的资源文件进行压缩 ,压缩成 xxx.gz的文件

cd /usr/local/nginx/html 
gzip *

注意:开启之后默认就会先访问 .gz 的文件了,如果不支持 静态压缩则会访问 正常文件,如果没有正常的文件只有 .gz 那么就会报错 。

4. nginx_http_gunzip_module 模块

Nginxリクエスト圧縮を実装する方法

这个模块是配合 gzip_static always时使用的 ,因为 当配置程 always 时,所有的请求会都进行找压缩文件,在文件存不存在或者说浏览器支不支持 静态压缩,nginx都会将静态压缩文件返回给浏览器,如果浏览器不支持的话会导致文件解不开,也就是 404 。

这个模块它没有在预编译的包里,需要手动添加,这个模块的作用就是把静态的压缩包解压开,他会在发送给客户端之前将压缩包接口在发送给客户端,它相当于是一层拦截器,它的作用就是可以把源文件进行压缩,我们可以把源文件进行删除了,节省磁盘空间,但是一般会用到。

注意 : with 是内部 、 add 是外部的

安装命令 :

./configure --prefix=/usr/local/nginx --add-module=/tools/nginx-sticky --with-http_gzip_static_module --with-http_gunzip_module

make

如果是替换的话,则将这个文件中的这个文件 cp 到 nginx的安装目录下的 sbin

Nginxリクエスト圧縮を実装する方法

移动命令:

 cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old2
 
 cd /tools/nginx/objs 
 mv nginx /usr/local/nginx/sbin/

这里没有gzip,但也没有 context-length 因为nginx需要把文件解压缩,他也不知道具体文件有多大,这个 gzip_static 适用场景 :在作为cdn服务器或者 cdn上游服务器文件存储服务器时,我们就可以把本地原始文件删了,只展示zip 包,把解压缩的压力丢弃给客户端 , 同时可以把本地压缩等级,提高不是 gzip的压缩等级 ,经常高配访问的一些页面 css js ,也可以通过 static压缩。

Nginxリクエスト圧縮を実装する方法

静态压缩 响应结果会有 Context-Encoding : gzip 、Conten-Length:392 有展示 context-length 表示他开启了静态压缩,预压缩直接返回zip包 没有源文件 ,1.速度快,2节省服务器资源。

四、Brotli

Brotli 是 Google 推出的开源压缩算法,通过变种的 LZ77 算法、Huffman 编码以及二阶文本建模等方式进行数据压缩,与其他压缩算法相比,它有着更高的压缩效率,性能也比我们目前常见的 Gzip 高17-25%,可以帮我们更高效的压缩网页中的各类文件大小及脚本,从而提高加载速度,提升网页浏览体验。需要说明的是 Brotli 压缩只在 https 下生效,因为 在 http 请求中 request header 里的 Accept-Encoding: gzip, deflate 是没有 br 的。

Brotli 如此高的压缩比率,得益于其使用一个预定义的字典,该字典包含超过 13000 个来自文本和 HTML 文档的大型语料库的常用字符串,预定义的算法可以提升较小文件的压缩密度,而压缩与解压缩速度则大致不变。

Brotli 凭借它优异的压缩性能迅速占领了市场,从下图可以看到,除了 IE 和 Opera Mini 之外,几乎所有的主流浏览器都已支持 Brotli 算法,因此处于资源占用的考虑,比如说流量,建议启用:

Brotil 规范由 Google 员工 Jyrki Alakuijala 和 Zoltan Szabadka 于 2013-2016开发,并伴随着规范的俩个作者Evgenii Kuliuchniko 和 Lode Vandevenne共同开发的参考实现,后者之前开发了谷歌的zopfli在2013年重新实现了收缩 /gzip 压缩格式。与zopfli不同,后者是对现有数据格式规范的重新实现,Brotli 是一种新的数据格式,并允许作者进一步提高压缩比。

4.1 Brotli 概述

Brotli 的编码器提供了 12 个质量级别 (从 0 到 11)。它们是压缩速度换取压缩效率的压缩模式:更高质量的几倍速度较慢,但会产生更好的压缩比。

一个 Brotli 压缩文件由 元块(meta-blocks)集合组成。每个元块最多可容纳 16 MiB,由俩部分组成:一个 数据部分(data part),它存储 LZ77 压缩的放入快,以及一个 标题(header),每个块的压缩遵循经典的 ①LZ77 压缩方案并由 ②计算具有良好的LZ77解析和计算 LZ 短语的简洁编码这俩个主要阶段组成。

它效率高是因为内置了 n多个字典,包含都是一些常见的文件文件 css 、js 等等一些标签,如果我们将这些标签归类生成一个字典之后,我们就可以按照序号去解压这个文件了。

并且它在 Nginx 中话是可以和 Gzip 共存,开启了Brotli 不会导致 Gzip失效,如果浏览器支持brotli 那么优先使用 Brotli ,不支持在使用 Gzip。

4.2 Brotli 的安装

--add-dynamic-module表示动态的引入模块在配置文件中还需要单独加入 load_module path/xxx

官网

  • https://github.com/google/ngx_brotli

  • https://codeload.github.com/google/brotli/tar.gz/refs/tags/v1.0.9

下载 俩个项目

解压缩

  • brotli-1.0.9 是 brotli 算法模块,需要先解压。

    • tar -zxvf brotli-1.0.9.tar.gz

  • ngx_brotli-1.0.0rc 是nginx的 brotli的模块。这模块里需要引入 brotli 算法模块

    • tar -zxvf ngx_brotli-1.0.0rc.tar.gz

接下来讲 brotli 的内容全部 复制到 ngx_brotli 的 deps/brotli/目录

  • cd /tools/brotli-1.0.9

  • cp -r * /tools/ngx_brotli-1.0.0rc/deps/brotli/

模块化编译 :

./configure --with-compat --add-dynamic-module=/tools/ngx_brotli-1.0.0rc --prefix=/usr/local/nginx/

--add-dynamic-module=brotli目录

加载所有的压缩模块

./configure --with-compat --add-dynamic-module=/tools/ngx_brotli-1.0.0rc --prefix=/usr/local/nginx/ --add-module=/tools/nginx-sticky --with-http_gzip_static_module --with-http_gunzip_module

make && make install

下载的两个模块 拷贝到 /usr/local/nginx/modules/

Nginxリクエスト圧縮を実装する方法

首先在 /usr/local/nginx创建一个modules文件夹 mkdir modules

mv ngx_http_brotli_filter_module.so ngx_http_brotli_static_module.so /usr/local/nginx/modules/

最后将新编译的 nginx 启动程序复制到 /usr/local/nginx/sbin下 做好之前程序复制。

  • cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.oid3

  • mv /tools/nginx-12.0/objs/nginx /usr/local/nginx/sbin/

在配置文件中动态加载模块

load_module "/usr/local/nginx/modules/ngx_http_brotli_filter_module.so";
load_module "/usr/local/nginx/modules/ngx_http_brotli_static_module.so";

4.3 配置选项

具体的配置选项可以查看GitHub: https://github.com/google/ngx_brotli

brotli的配置可以参考Gzip的配置,几乎一致。

brotli

  • 语法:brotli on | off

  • 默认值 :brotli off

  • 适用于: http、server、location、if

  • 作用:开启或者禁用brotli 压缩功能。

brotli_static

  • 语法:brotli_static on | off | always

  • 默认值:brotli_static off

  • 适用于:http、server、location

  • 作用:brotli 也是支持预先压缩文件,启用或禁用检查是否存在带扩展名的预压缩文件.br 。使用该always值,在所有情况下都使用预压缩文件,而不检查客户端是否支持它。

brotli_types

  • 语法:brotli_types [...]

  • 默认值:brotli_types text/html

  • 适用于: http、server、location

  • 作用:指定哪些资源类型需要进行压缩操作,特殊值*匹配任何 MIME类型。

brotli_buffers

  • 语法:brotli_buffers

  • 默认值: 32 4k | 16 8 k

  • 适用于: http、server、location

  • 作用:设置压缩缓冲区大小,最新版本以及弃用了 。

brotli_comp_level

  • 语法:brotli_comp_level

  • 默认值 :6'

  • 适用于 : http、server、location

  • 作用 : 设置即时压缩 Brotli 质量(压缩)level。0可接受的值在从到 的范围内11。

brotli_window

  • 语法:brotli_window

  • 默认值 : 512k

  • 适用于 :http、server、 location

  • 作用:设置 Brotli 窗口size。可以比作是一个桌子,将要压缩的文件同时放在这个桌子上,这个桌子上可以放多少文件的大小,这个值也不越大越好,他比较占内存,值增加建议是2的倍数,可接受的值为1k, 2k, 4k, 8k, 16k, 32k, 64k, 128k, 256k, 512k, 1m, 2m,和4m。8m 16m

brotli_min_length

  • 语法:brotli_min_length

  • 默认值:20

  • 适用于: http、server、location

  • 作用:指定进行压缩的文件最小的长度,如果小于这个值则不压缩。

#加载动态模块 
load_module "/usr/local/nginx/modules/ngx_http_brotli_filter_module.so";
load_module "/usr/local/nginx/modules/ngx_http_brotli_static_module.so";
worker_processes  1;
events {
    worker_connections  1024;
}
 
http {
    server {
    listen       80;
    server_name  localhost;
        location  / {
          #brotli配置 
          brotli on;  # 开启 压缩
        brotli_static on; # 是否开启预先压缩,开启之后就会 .br的压缩包
          brotli_comp_level 6; # 压缩等级
          brotli_buffers 16 8k; # 缓冲区大小 ,已经启用 
          brotli_min_length 20; # 压缩时文件最小限制 
          # 对哪些mime.types类型进行压缩
          brotli_types text/plain text/css text/javascript application/javascript text/xml application/xml application/xml+rss application/json image/jpeg image/gif image/png;
    
          }
  }
}

4.4 brotli 测试

因为默认 brotli 是必现 https 请求才能使用的,因为 http的请求 请求头的 Accept-Encoding 是没有 br的,所以服务器是无法知道客户端可以使用的。

测试方案:

使用 linux 的 curl 命令 :

curl -H 'Accept-Encding : br' -I 192.168.101.128/index.html
[root@localhost sbin]# curl -H Accept-Encoding:br  -I http://192.168.101.128/static_page.html
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Fri, 17 Feb 2023 08:11:05 GMT
Content-Type: text/html
Last-Modified: Fri, 17 Feb 2023 03:28:14 GMT
Connection: keep-alive
Keep-Alive: timeout=65
Vary: Accept-Encoding
ETag: W/"63eef44e-31"
Content-Encoding: br
[root@localhost sbin]# curl  -I http://192.168.101.128/static_page.html
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Fri, 17 Feb 2023 08:11:54 GMT
Content-Type: text/html
Last-Modified: Fri, 17 Feb 2023 03:28:14 GMT
Connection: keep-alive
Keep-Alive: timeout=65
Vary: Accept-Encoding
ETag: W/"63eef44e-31"

以上がNginxリクエスト圧縮を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。