添加nginx扩展支持webp自动生成,自动判断来源浏览器或者设备是否支持webp。

浏览:1447 发布日期:2019/08/04 分类:技术分享 关键字: nginx webp
什么是 webp这里就不在赘述,不懂的童鞋直接百度。

需要实现功能:

不改变现有网站结构的情况下实现对webp的支持。
生成缓存web文件夹,不用每次访问都重新生成,提高效率。

逻辑思考:

浏览器发起请求,nginx localtion拦截请求。
转发到lua脚本,lua脚本处理图片转换成 webp(生成缓存)。
处理完成返回新生成的图片。

思路分析完成,开干。

没有nginx的先安装nginx

sudo apt-get install nginx-full

安装lua及相关组件(此项非必须,根据需求安装)

apt-get install lua5.2 lua5.2-doc liblua5.2-dev

安装luajit

sudo apt-get install luajit

关于JIT :

通常,程序有两种运行方式:静态编译与动态直译。
静态编译的程序在执行前全部被翻译为机器码,而动态直译执行的则是一句一句边运行边翻译。
即时编译(Just-In-Time Compiler)则混合了这二者,一句一句编译源代码,但是会将翻译过的代码缓存起来以降低性能损耗。

此外,使用luajit可以大大提高lua的运行效率,由此也被官方钦定。

安装nginx的lua模块 lua-nginx-module(重点是这个 nginx扩展API)

sudo apt-get install libnginx-mod-http-lua

如果出现找不到源的情况,请根据自己系统版本在ubuntu官方源寻找,修改source.list文件,增加支持。

官方源库地址:官方地址,进入官方源库地址,选择自己的系统版本,搜索软件名即可。

感谢这位大佬的安装说明:https://www.centos.bz/2017/09/debianubuntu-%E4%B8%8B-nginxlua-%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/

注:楼主ubuntu 18.04系统在安装的时候出现安装成功但无法识别的情况:unknown device content_by_lua_file ,解决方案卸载 nginx 重新安装即可,或者升级nginx1.16, 系统默认是1.14.

安装webp命令

apt install webp

配置nginx

nginx的配置中,核心在于content_by_lua_file。

关于 content_by_lua_file 的官方文档: https://github.com/openresty/lua-nginx-module#content_by_lua_file

本人的配置代码供参考:

location ~ \.(gif|jpg|jpeg|png|bmp) {

if (!-e $request_filename) { #如果文件不存在直接返回404
return 404;
}
expires 30d;
if ( $http_accept ~* '(image/webp)' ){ #判断来源设备是否支持webp
set $tmppath "/temp_webp/"; #设置缓存路径,分2个变量脚本里面需要
set $tmp $document_root$tmppath; # 设置绝对路径缓存地址 缓存目录请勿必给权限,不然报错
content_by_lua_file "/etc/nginx/webp.lua"; #脚本存放位置勿必给执行权限
}
}

Lua脚本代码

function file_exists(name) --检查文件是否存在
local f=io.open(name,"r")
if f~=nil then io.close(f) return true else return false end
end
local originalFile = ngx.var.request_filename; --原文件地址
local tmpFile =ngx.var.tmp .. ngx.md5(originalFile) .. '.webp'; --缓存 webp文件地址(绝对路径)
local tmpPathFile =ngx.var.tmppath .. ngx.md5(originalFile) .. '.webp'; --缓存webp文件路径(相对路径),后续返回

if file_exists (tmpFile) then --判断是否有缓存文件,有就直接输出
return ngx.exec(tmpPathFile);
end

if not file_exists(originalFile) then -- 原文件不存在
return ngx.exit(404);
end
executeCmd = "/usr/bin/cwebp -q 80 " .. originalFile .. " -o " .. tmpFile
os.execute(executeCmd); -- 转换原图片到 webp 格式,这里的质量是 75 ,你也可以改成别的

if file_exists(tmpFile) then -- 如果新文件存在(转换成功)
return ngx.exec(tmpPathFile) -- Internal Redirect
else
---------------------
return ngx.exit(404)
end

测试

转成webp图片后:



未转成webp图片:


webp大小为:144KB ,png大小:453KB 。

详细看:https://blog.csdn.net/fenghaofhyy/article/details/98094361

最佳答案
评论( 相关
后面还有条评论,点击查看>>