先上全部代码吧
nginx.conf
worker_processes auto;
user hubs;
# 日志级别调试时可设为notice,生产环境请设为error
error_log /usr/local/openresty/nginx/logs/error.log notice;
events
{
use epoll;
worker_connections 51200;
multi_accept on;
}
http
{
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
# sendfile on;
#tcp_nopush on;
lua_package_path '/usr/local/openresty/nginx/lua/?.lua;;';
lua_shared_dict imgsrv_locks 10m; #Shared memory segment for locking mechanism
lua_shared_dict imgsrv_cache 50m;
server {
listen 80;
server_name wnew.tt;
#root /home/hubs/桌面/html;
root /opt/lampp/htdocs/wowo-new/public;
#/thumbnail目录下的图片请求不经过缩略图模块
# location ^~ /imgcache/ {
# }
# lua_code_cache off ;
location / {
#开启ssi支持shtml
ssi on;
ssi_silent_errors on;
ssi_types text/shtml;
index index.shtml index.php index.htm index.html;
#框架路由设置
if ( !-e $request_filename ) {
rewrite ^(.*)$ /index.php?url=$1 last;
}
}
location ~\.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
#对类似_100x100.gif/jpg/png/jpeg进行缩略图处理
location ~*(.*)\/(.*)\.(gif|jpg|png|jpeg)@([0-9]+)x([0-9]+)\.(gif|jpg|png|jpeg)$ { #匹配文件名规则
set $remote_url "https://wowoyoo.com$1/$2.$3"; #visit url
# set $src_save_root "/home/hubs/桌面/html";
set $src_save_root "/opt/lampp/htdocs/wowo-new/public";
set $src_save_file_path "$src_save_root$1/$2.$3"; #save filename
set $thumbnail_root "$src_save_root"; #缩略图存放目录
set $thumb_file "$thumbnail_root$uri"; #如果缩略图文件存在,直接返回
set $type 1 ;
#如果缩略图文件不存在,则应用缩略图模块处理
if (!-f $thumb_file) {
rewrite_by_lua_file lua/build.lua;
}
}
location ~*(.*)\/(.*)\.(gif|jpg|png|jpeg)$ { #匹配文件名规则
set $remote_url "https://wowoyoo.com$1/$2.$3"; #visit url
#set $src_save_root "/home/hubs/桌面/html";
set $src_save_root "/opt/lampp/htdocs/wowo-new/public";
set $src_save_file_path "$src_save_root$1/$2.$3"; #save filename
set $type 2 ;
#如果缩略图文件不存在,则应用缩略图模块处理
if (!-f $src_save_file_path) {
rewrite_by_lua_file lua/build.lua;
}
}
}
}
build_config.lua
-- nginx thumbnail module
-- last update : 2014/8/21
-- version : 0.4.1
module(...,package.seeall)
--[[
enabled_log: 是否打开日志
lua_log_level: 日志记录级别
gm_path: graphicsmagick安装目录
img_background_color: 填充背景色
enabled_default_img: 是否显示默认图片
default_img_uri: 默认图片链接
default_uri_reg: 缩略图正则匹配模式,可自定义
_[0-9]+x[0-9] 对应:001_100x100.jpg
_[0-9]+x[0-9]+[.jpg|.png|.gif]+ 对应:001.jpg_100x100.jpg
]]
enabled_log = false
lua_log_level = ngx.NOTICE
gm_path = '/usr/bin/gm'
img_background_color = 'white'
enabled_default_img = true
default_img_uri = '/default/notfound.jpg'
default_uri_reg = '@[0-9]+x[0-9]+[.jpg|.png|.gif]+'
default_wh_reg = '@([0-9]+)x([0-9]+)' -- width-height
quality = 80 -- 质量
direction = 'southeast' --位置
warter_dissolve = 50 --百分比
warter_img_uri = '/default/water.png'
--[[
配置项,对目录、缩略图尺寸、裁剪类型进行配置,匹配后才进行缩略图处理
1.sizes={'350x350'} 填充后保证等比缩图
2.sizes={'300x300_'}等比缩放
3.sizes={'50x50^'}裁剪等比缩放 (缺点:裁剪了图片的一部分)
dir="/" 对应根目录,请放在default之前
dir="default" 对应默认图片尺寸,当原图不存在时,请求该尺寸会以默认图片生成缩略图
]]
cfg = {
{
dir = '/',
sizes = {'50x50^','100x100^','250x250^','300x300_^','350x350^','80x80^','120x120^'},
},
{ dir = 'default',
sizes = {'50x50^','100x100^','250x250^','300x300^','350x350^','80x80^'},
}
}
build.lua
-- nginx thumbnail module
-- last update : 2014/8/21
-- version : 0.4.1
local lock = require 'resty.lock'
local c = require 'build_config'
local P = require("path")
local src_save_file_path = ngx.var.src_save_file_path -- full file path
local remote_url = ngx.var.remote_url
local ngx_img_root = ngx.var.src_save_root -- save root
local uri = ngx.var.uri
local ntype = ngx.var.type
function print_log (msg,log_level)
log_level = log_level or c.lua_log_level
if(c.enabled_log) then
ngx.log(log_level,msg)
end
end
-- must before print_log under
local fetch = require 'build_fetch'
local thumb = require 'build_thumb'
local lockid = src_save_file_path
-- get lock start
local _lock = lock:new('imgsrv_locks',{timeout=03})
local elapsed,err = _lock:lock(lockid)
if not elapsed then
print_log("Failed to acquire the lock : "..err)
return false;
end
print_log("---------------------------------------------------------------------------------LOCK ")
-- get lock end
local function start_thumb()
local ngx_thumbnail_root = ngx.var.thumbnail_root -- thumb root
local down = thumb.start_thumb(uri,ngx_img_root,ngx_thumbnail_root)
if not down then
local ok ,err = _lock:unlock()
if not ok then
print_log("failed start_thumb : "..err)
return false
end
end
return true
end
local function start_fetch()
local fok = fetch.start_fetch(remote_url,lockid)
if not fok then
local ok ,err = _lock:unlock()
if not ok then
print_log("failed start_fetch : "..err)
return false
end
end
return true
end
local function start_unlock()
local ok,err = _lock:unlock()
print_log("--------------------------------------------------------------------------------- @@@@@@@@@@ UN LOCK ")
if not ok then
print_log("failed to unlock: "..err)
return false
end
return fok
end
if ntype == 1 then
print_log("ntype = "..ntype)
-- exist src file
if P.exists(lockid) then
start_thumb()
start_unlock()
else
start_fetch()
start_thumb()
start_unlock()
end
else
print_log("ntype 2 = "..ntype)
if P.exists(lockid) then
start_unlock()
else
start_fetch()
start_unlock()
end
end
build_fetch.lua
-- https://phpb.com/portfolio/create-image-server-with-nginx-lua-openresty-graphicsmagick-part-ii/
-- https://github.com/openresty/lua-resty-lock#for-cache-locks
local _M = {}
local P = require("path")
local curl = require"cURL"
local lfs = require 'lfs'
local os = require 'os'
local math = require 'math'
local function mkdir(absdir)
local temp_abs_dir = absdir
local dir,base = P.split(temp_abs_dir)
local dir_exist = P.isdir(temp_abs_dir)
if dir_exist then
return true
end
local temp_dir = P.isdir(dir)
local temp_base = P.isdir(base)
if temp_dir and not temp_base then
local ok ,err= lfs.mkdir(temp_abs_dir)
if not ok then
print_log("temp_dir _ create 1: "..err)
return false
end
return ok
else
mkdir(dir)
local ok ,err = lfs.mkdir(temp_abs_dir)
if not ok then
print_log("temp_dir _ create 2: "..err)
return false
end
return ok
end
end
_M.start_fetch = function(remote_url,save_file_path)
local http_url = remote_url
local temp_file = save_file_path..".temp"
-- math.randomseed(os.time())
-- local temp_file = save_file_path.. math.random(100)
local ok = mkdir(P.dirname(save_file_path))
if not ok then
return false
end
local save_file = io.open(temp_file,"w+b")
if not save_file then
print_log("can't open tmpe_fiel = "..temp_file)
return false
end
-- HTTP Get
curl.easy{
url = http_url,
writefunction = save_file ,
}
:perform()
:close()
save_file:close()
if P.isfile(temp_file) then
os.rename(temp_file,save_file_path)
print_log("OK YES!! --------------------------------------------------------------------------------------------- down! ->")
return true
else
print_log("down fails --------------------------------------------------------------------------------------------- ! ="..http_url)
os.remove(temp_file)
return false
end
end
return _M;
build_thumb.lua
-- nginx thumbnail module
-- last update : 2014/8/21
-- version : 0.4.1
local _M = {}
local c = require 'build_config'
--[[
uri :链接地址,如/goods/0007/541/001_328x328.jpg
ngx_img_root :图片根目录
ngx_thumbnail_root:缩略图根目录
img_width :缩略图宽度
img_width :缩略图高度
img_size :缩略图宽x高
img_crop_type :缩略图裁剪类型
cur_uri_reg_model :缩略图uri正则规则
]]
local img_width,img_height,img_size,img_crop_type = 0
local cur_uri_reg = c.default_uri_reg
-- 匹配链接对应缩略图规则
local function contains(table,uri)
local i = 1
img_crop_type = 0
for _, value in pairs(table) do
local dir = value['dir']
local sizes = value['sizes']
local uri_reg = value['uri_reg']
_,_,img_width,img_height = string.find(uri,''..dir..'+.*'..c.default_wh_reg)
if(img_width and img_height and img_crop_type==0) then
img_size = img_width..'x'..img_height
for _, value in pairs(sizes) do
cur_uri_reg = uri_reg or cur_uri_reg
if (img_size == value) then
img_crop_type=1
return true
elseif (img_size..'_' == value) then
img_crop_type=2
return true
elseif (img_size..'^' == value) then
img_crop_type=3
return true
end
end
end
i=i+1
end
return false
end
-- 拼接gm命令
-- /usr/bin/gm convert -quality 80 /usr/local/nginx/html/test/3.jpg -resize "300x300^" -gravity center -crop 300x300+0+0 -|
-- gm composite -watermark 50 -gravity southeast /usr/local/nginx/html/default/water.png - /usr/local/nginx/html/imgcache/test.jpg
local function generate_gm_command(img_crop_type,img_original_path,img_size,img_thumbnail_path,img_warter_path)
local cmd = c.gm_path .. ' convert -quality '.. c.quality..' '.. img_original_path
if (img_crop_type == 1) then
cmd = cmd .. ' -thumbnail ' .. img_size .. ' -background ' .. c.img_background_color .. ' -gravity center -extent ' .. img_size
elseif (img_crop_type == 2) then
cmd = cmd .. ' -thumbnail ' .. img_size
elseif (img_crop_type == 3) then
--cmd = cmd .. ' -resize "' .. img_size .. '^" -gravity center -crop '..img_size.."+0+0"
cmd = cmd .. ' -resize "' .. img_size .. '" -gravity center -crop '..img_size.."+0+0"
else
print_log('img_crop_type error:'..img_crop_type,ngx.ERR)
return false
end
local warter_cmd = c.gm_path .. ' composite -watermark '.. c.warter_dissolve..' -gravity southeast '.. img_warter_path..' - '..img_thumbnail_path
cmd = cmd .. ' - |' .. warter_cmd
return cmd
end
_M.start_thumb = function(uri,ngx_img_root,ngx_thumbnail_root)
if not contains(c.cfg, uri) then
print_log(uri..' is not match! = ',ngx.ERR)
return false
else
print_log(uri..' is match!')
local img_original_uri = string.gsub(uri, cur_uri_reg, '')
local img_exist = io.open(ngx_img_root .. img_original_uri)
if not img_exist then
if not c.enabled_default_img then
print_log(img_original_uri..' is not exist top!',ngx.ERR)
return false
else
img_exist=io.open(ngx_img_root .. c.default_img_uri)
if img_exist then
print_log(img_original_uri .. ' is not exist! crop image with default image')
img_original_uri = c.default_img_uri
else
print_log(img_original_uri..' is not exist!',ngx.ERR)
return false
end
end
end
local img_original_path = ngx_img_root .. img_original_uri
local img_thumbnail_path = ngx_thumbnail_root .. uri
local img_warter_path = ngx_img_root..c.warter_img_uri
local gm_command = generate_gm_command(img_crop_type,img_original_path,img_size,img_thumbnail_path,img_warter_path)
if (gm_command) then
print_log('gm_command======'..gm_command)
-- _,_,img_thumbnail_dir,img__thumbnail_filename=string.find(img_thumbnail_path,'(.-)([^/]*)$')
-- os.execute('mkdir -p '..img_thumbnail_dir)
os.execute(gm_command)
return true
end
-- ngx.req.set_uri(uri)
return false
end
end
return _M
完工,参考文章
https://moonbingbing.gitbooks.io/openresty-best-practices/content/lua/if_else.html
https://phpb.com/portfolio/create-image-server-with-nginx-lua-openresty-graphicsmagick-part-ii/
#!/bin/sh
sudo /opt/openresty/luajit/bin/luarocks install graphicsmagick --server=https://raw.github.com/torch/rocks/master
sudo /opt/openresty/luajit/bin/luarocks install Lua-cURL --server=https://rocks.moonscript.org/dev
sudo /opt/openresty/luajit/bin/luarocks install lua-resty-readurl
sudo /opt/openresty/luajit/bin/luarocks install luafilesystem
sudo /opt/openresty/luajit/bin/luarocks install lua-path