Nginx图片压缩及防盗链

背景

前段时间搞了一个Midjourney中文代理的项目,因为接口什么的都是对接第三方的,相对来说还是比较顺利。由于是通过第三方对接的Midjourney,导致图片都是源站的(虽然Midjourney已经上了CDN,但是由于GFW的原因并不能直接访问),在这种情况下我们又加了一台香港的代理服务器用于代理源站的图片。测试的时候看起来还是比较正常的,但是很快就发现一个问题,图片加载非常的慢。

问题分析

经过简单查看图片大小,发现Midjourney返回的图片基本都在10Mb左右,而我们的代理服务器的上行带宽为10Mbps,也就是说就算是我们的代理服务器加载这个图片都需要花费10s左右。所以简单来说只需要升级服务器带宽即可解决这个问题。

既然要升级带宽,那就不可避免的要会增加预算。但更大的问题是所在的运营商(野鸡运营商,不用在意)根本不提供100Mbps带宽的服务器,同时发现北美地区100Mbps的服务器价格也很美丽。经过测试:

香港服务器:带宽低,但是延迟低
北美服务器:带宽高,但是延迟高

由于延迟过高,同样会导致图片加载缓慢,甚至加载失败。问题还是没有得到解决,后面我灵机一动,用香港的服务器ping了一下北美服务器,发现速度还不错,于是选择用香港的服务器代理北美的服务器。这样延迟大大的降低了,但是图片加载缓慢的问题依然还是没有解决(因为香港的服务器上行带宽只要10Mbps)。

问题解决

上面已经分析出了问题,那其实解决办法已经呼之欲出了—— 就是使用北美的代理服务器在代理Midjourney图片的同时进行压缩。

配置Nginx图片压缩

  1. 判断是否安装了ngx_http_image_filter_module 模块
1
nginx -V

会输出类似结果

1
2
3
4
5
nginx version: nginx/1.24.0
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-22) (GCC)
built with OpenSSL 1.1.1q 5 Jul 2022
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --add-module=/www/server/nginx/src/ngx_http_substitutions_filter_module-master --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module

因为我这个版本已经安装 ngx_http_image_filter_module 模块了,就不需要再重新安装了;如果没有安装则需要重新编译安装。

2.安装ngx_http_image_filter_module 模块

一般来说非源码安装是内置了这个模块的,只有源码安装的情况可能没有这个模块,首先进入源码目录,然后执行

1
./configure --prefix=nginx目录 第一步输出的需要使用的模块(--add-module=...) --with-http_image_filter_module(这次需要编译的模块)

3.make 编译nginx

注意不是make install,make install 会覆盖之前的安装

4.替换编译后的可执行文件

5.重启nginx并重新查看已安装的模块,顺利的话就能看到 http_image_filter_module 已经成功安装了

6.配置图片压缩选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
server {
listen 80;
server_name your_domain.com;

location /compressed/ {
# 动态设置图片大小
set $w 800;
set $h 600;
if ($arg_width) {
set $w $arg_width;
}
if ($arg_height) {
set $h $arg_height;
}

# 动态设置压缩比
set $quality 75; # 默认质量
if ($arg_quality) {
set $quality $arg_quality; # 从 query 参数获取质量
}

# 处理图片请求
image_filter resize $w $h; # 使用动态大小
image_filter_buffer 50M;
image_filter_jpeg_quality $quality; # 使用动态质量
# 转发到实际的图片文件
proxy_pass https://cdn.discordapp.com;
}

# 此处直接代理是因为需要保存原始图片以供将来使用
location / {
proxy_pass https://cdn.discordapp.com;
}
}

nginx 防盗链

为了防止代理服务器被其他人白嫖,所以还需要加上防盗链

1
2
3
4
5
6
7
location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
}

[越努力,越幸运!]