作者:MeshCloud脉时云 公有云架构师 王高利
导读:当网站包含大量 CSS 和 JS 文件时,对这些静态文件启用 Gzip 压缩可以显著加快网站的加载速度。缩小传输文件大小,提升文件传输效率,减少带宽消耗,节省开销。
一、GCS GZIP 压缩介绍
Content-Encoding 元数据可用于指示对象是否已被压缩,同时您仍可保留对象的基本 Content-Type。例如,以 gzip 格式压缩的文本文件可能具有以下特征:Content-Type 表明这是一个文本文件,而 Content-Encoding 表明该文件已采用 gzip 格式进行压缩。您应确保在上传文件之前,确实已使用指定的 Content-Encoding 压缩文件;否则,在尝试下载对象时,可能会发生意外行为。
对于可压缩的内容(例如文本),使用 Content-Encoding: gzip 可节省网络和存储费用,并提高内容传送性能。但是,对于本身已经压缩的内容(例如归档和许多媒体格式),再压缩一次并在 Content-Encoding 元数据中进行标记通常不利于对象的大小和性能,因此应避免此操作。
某些对象(例如许多视频、音频和图片文件)已进行压缩处理,更不用说 gzip 文件本身了。对此类对象使用 gzip 实际上没有任何好处:在几乎所有情况下,由于 gzip 开销,这样做都会使对象变得更大。为此,通常不鼓励对已经压缩的内容使用 gzip,以防导致意外行为。
例如,尽管 Cloud Storage 允许上传和存储“双重压缩”对象(即不但对象本身已经过 gzip 压缩,而且其基础 Content-Type 本身也进行了压缩),但它不允许以双重压缩状态传送对象,除非对象的 Cache-Control 元数据包含 no-transform。Cloud Storage 会移除外部 gzip 压缩层,删除 Content-Encoding 响应标头,并传送生成的对象。即使是包含 Accept-Encoding: gzip 的请求也是如此。 因此,客户端接收的文件与上传并存储在 Cloud Storage 中的文件没有相同的校验和,于是,任何完整性检查都会失败。
二、实现方式
需使用gsutil工具实现压缩功能
gsutil cp命令介绍:https://cloud.google.com/storage/docs/gsutil/commands/cp#options
格式gsutil -m cp -Z [ LOCAL_DIR ] gs:// [ BUCKET ] / [ REMOTE_DIR ]
参数介绍:
-m 此选项告诉cp子命令执行并行多线程/多处理复制,适用于大量文件上传使用。
-Z 将 gzip 内容编码应用于文件上传。此选项的工作方式与-z选项类似,但它适用于所有上传的文件,无论扩展名如何。
LOCAL_DIR 我们要上传到 Google Cloud Storage 的文件的目录路径或文件名称。
BUCKET Google Cloud Storage 存储分区的名称。
REMOTE_DIR 文件将被复制到的存储桶中的远程目录或文件名称。
1. 上传前大小
Shell [wanggaoli@WangGaoli:] ~/Downloads $ du -h index.js 1.7M index.js |
2. 上传压缩文件
Shell [wanggaoli@WangGaoli:] ~/Downloads $ gsutil -m cp -Z index.js gs://wanggaoli-test Copying file://index.js [Content-Type=application/javascript]... \ [1/1 files][106.2 KiB/ 1.7 MiB] 100% Done Operation completed over 1 objects/1.7 MiB. |
3. 不加Z参数,上传的是原大小
Shell [wanggaoli@WangGaoli:] ~/Downloads $ gsutil -m cp index.js gs://wanggaoli-test/index-test.js Copying file://index.js [Content-Type=application/javascript]... | [1/1 files][ 1.7 MiB/ 1.7 MiB] 100% Done Operation completed over 1 objects/1.7 MiB. |
4. 通过gsutil验证大小
Shell [wanggaoli@WangGaoli:] ~/Downloads $ gsutil du -h gs://wanggaoli-test/ 1.73 MiB gs://wanggaoli-test/index-test.js 106.18 KiB gs://wanggaoli-test/index.js |
5. 通过curl、浏览器、wget验证压缩
检查响应头中是否包含content-encoding: gzip和content-type: application/javascript(对于 JS)标头。
5.1 通过curl验证
Shell [wanggaoli@WangGaoli:] ~/Downloads $ curl -I https://storage.googleapis.com/wanggaoli-test/index.js HTTP/2 200 x-guploader-uploadid: ADPycduPuZtfQL0jKnpGhAgBrrgTAnb6vQevqqRkPOhs_Rm8_TsXvne2jnxJN3Nf6bM6_U7V3I5sU0N4bJfOkhb-I7vFQRJuiW_l date: Wed, 13 Jul 2022 02:57:12 GMT cache-control: no-transform expires: Thu, 13 Jul 2023 02:57:12 GMT last-modified: Wed, 13 Jul 2022 02:43:59 GMT x-goog-generation: 1657680239234033 x-goog-metageneration: 1 x-goog-stored-content-encoding: gzip x-goog-stored-content-length: 108730 content-type: application/javascript content-language: en x-goog-hash: crc32c=unr3pw== x-goog-hash: md5=AeZSEfQH46zncB8WLltlgA== x-goog-storage-class: STANDARD accept-ranges: none server: UploadServer alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43" vary: Accept-Encoding |
指定Accept-Encoding:gzip头测试
Plain Text [wanggaoli@WangGaoli:] ~/Downloads $ curl -o a.js -H 'Accept-Encoding:gzip' https://storage.googleapis.com/wanggaoli-test/index.js % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 106k 100 106k 0 0 2589k 0 --:--:-- --:--:-- --:--:-- 2589k [root@RN-87:] ~ # du -h a.js 108K a.j |
5.2 通过浏览器验证
Shell accept-ranges: bytes alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43" cache-control: no-transform content-encoding: gzip content-language: en content-length: 108730 content-type: application/javascript date: Wed, 13 Jul 2022 03:03:26 GMT etag: "01e65211f407e3ace7701f162e5b6580" expires: Thu, 13 Jul 2023 03:03:26 GMT last-modified: Wed, 13 Jul 2022 02:43:59 GMT server: UploadServer x-goog-generation: 1657680239234033 x-goog-hash: crc32c=unr3pw== x-goog-hash: md5=AeZSEfQH46zncB8WLltlgA== x-goog-metageneration: 1 x-goog-storage-class: STANDARD x-goog-stored-content-encoding: gzip x-goog-stored-content-length: 108730 x-guploader-uploadid: ADPycdtPKe5UNhPgfRzeClIaS9HJNtQnVBz9FCI4rORgLt7PraCGb502UEXTyT7IJ1s3o4O434dES6ahChycKlzvXp6u0ickF2ct |
5.3 通过wget模拟压缩测试
会发现wget下载的是源文件大小,说明wget请求时,没有携带Accept-Encoding:gzip头
Plain Text [wanggaoli@WangGaoli:] ~/Downloads $ wget https://storage.googleapis.com/wanggaoli-test/index.js --2022-07-13 16:25:58-- https://storage.googleapis.com/wanggaoli-test/index.js Resolving storage.googleapis.com (storage.googleapis.com)... 142.250.72.240, 142.250.176.16, 142.250.217.144, ... Connecting to storage.googleapis.com (storage.googleapis.com)|142.250.72.240|:443... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [application/javascript] Saving to: ‘index.js’ index.js [ <=> ] 1.73M --.-KB/s in 0.04s 2022-07-13 16:25:58 (41.8 MB/s) - ‘index.js’ saved [1815586] [wanggaoli@WangGaoli:] ~/Downloads $ du -h index.js 1.8M index.js |
注:当Bucket权限设置为公共读时,访问Object格式为:https://storage.googleapis.com/[BUCKET_NAME]/[FILE_PATH]