当前位置: 首页 > 工具软件 > lua-epoll > 使用案例 >

nginx-lua-openresty-graphicsmagick 下载远程图片,本地缩图红缓存加水印 大结局

宋育
2023-12-01
  1. 先上全部代码吧

  2. 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;
                            }
                    }
            }
    }

  3. 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^'},
    		}
    	
    }
    	

  4. 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  

  5. 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;

  6. 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

  7. 完工,参考文章

    1. https://moonbingbing.gitbooks.io/openresty-best-practices/content/lua/if_else.html

    2. https://phpb.com/portfolio/create-image-server-with-nginx-lua-openresty-graphicsmagick-part-ii/

  8. 安装依赖
    #!/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


 类似资料: