使用 Nginx的image_filter 模块来构建动态缩略图服务器

在以前我们实现缩略图机制通常是在当用户上传一张图片后,后端程序会固定将图片生成前端页面需要的不同大小缩略图。不管前端页面是否有使用,后端都会先产生好,这样做明显有以下缺陷:

占用过多的磁盘空间大小

前端页面需要更多样格式的缩略图时,需要单独处理。

当出现第二个问题时会比较麻烦,后端程序就需要将系统的全部图片重新产生一次所需的缩略图。这个过程非常耗时,也比较耗费系统性能。

现在比较流行的做法是改成透过 URL 定义长宽来即时生成所需的缩略图,实现的方式也有多种多样,本文将介绍使用 Nginx 的 模块来实现动态生成缩略图。

从 Nginx 0.7.54 以后的版本,提供了一个 的集成图片处理模块。该模块可以实现实时缩放图片、旋转图片、验证图片有效性以及获取图片宽高以及图片类型信息等功能。

安装 image_filter 模块

模块在默认情况下是没有包含在官方预编译包中的,如果需要使用 模块需要重新编译 Nginx。

查看是否已安装 image_filter 模块

如果返回的结果中含有 字样就表明已经安装了 模块。

编译 Nginx 并加入 image_filter 模块

启用 模块的方法是比较简单的,由于 扩展需要 GD 库支持,首先需要安装相关依赖环境:

其次在原来的 Nginx 编译参数上加上 参数后重新编译 Nginx 就行了。

验证是否安装成功

如果返回的结果中含有 字样就表明安装成功了。

image_filter 模块常用参数说明

使用 image_filter 模块动态生成缩略图

配置 image_filter 模块

这里给出一个简单的例子,在你的 Nginx 配置文件中 Server 配置段增加如下内容:

重载 Nginx 配置

生成缩略图

通过在图片请求地址的文件名前加上 ,就可以访问到你想要的任意尺寸的缩略图。例如:要生成缩略图的图片地址为:,现在只需要将请求修改为: 将会自动返回对应的缩略图。

给 image_filter 模块加入缓存机制

默认情况下, 模块都是实时生成缩略图的。每一次请求 Nginx 都会需要处理,如果有 10000 次请求,就会处理 10000 次。这样就会在高并发请求时给 Nginx 服务器造成压力。

要解决这个问题,我们可以通过 Nginx 的 机制让 Nginx 在相同请求的情况下只产生一次缩略图,并且将缩略图放到缓存目录中以减少短时间内的不同请求所产生的运算次数。

由于 模块无法跟 同时处理,要实现这个功能必须要将请求拆成两个 Host 来达成。具体配置如下:

使用 Docker 容器快速构建

如果你和我一样比较偏爱使用 Docker,可以直接使用 项目。 项目是一个用 Docker 实现的实时图像调整大小和缓存的容器项目, 支持 Amazon S3 和 Minio 作为存储。

项目官方地址:http://t.cn/RBG2QWx

下面给一个使用 Minio 作为存储的 docker-compose 示例:

编写 docker-compose 配置文件

注:MINIO_ACCESS_KEY 和 MINIO_SECRET_KEY 分别为 Minio 的登陆帐号和密码,请根据实际情况修改。

启动相关容器

生成缩略图

生成缩略图的方法和前面方法类似,但由于这里使用了 Minio 做为文件存储服务,所以需要先在 Minio 中上传图片文件。在 Minio 中上传文件的方法大致分为以下几步:

登陆 Minio Web 管理界面, Web 管理界面访问地址默认为:。

创建 bucket,这里我们创建一个名为 test 的 bucket。

设置名为 test 的 bucket 的访问权限。

在名为 test 的 bucket 中上传图片文件。

完成以上几步后,和前面类似直接在访问的 URL 中加入需缩放图片比例即可生成对应缩略图。例如:访问 将会自动返回对应的缩略图。

其它相关说明

利用 Nginx 的 模块不仅仅能生成缩略图,你还可以通过修改配置来实现其它的功能,比如图片旋转、图片裁剪、图片透明化等等。关于 模块的更多使用方法可参考官方文档。

参考文档

https://www.google.com

http://t.cn/RBG2QWx

http://t.cn/RBGyUbz

http://t.cn/R7R9bZU

http://t.cn/RBGyxil

今日思想

只要你愿意投入时间和精力来培养新技能,那么你就能做你应该做的事。如果你只涉猎你能力所及的领域,那么你的技能就会过时。

—— 贝索斯

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180611G0PNVU00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券