文档章节

FASTDFS(六)nginx+lua+GraphicsMagick 图片自动缩放

chaun
 chaun
发布于 2016/09/12 09:59
字数 1328
阅读 268
收藏 3

1.安装GraphicsMagick

--使用yum安装GraphicsMagick

Shell代码 

# yum install ImageMagick

--查看安装结果

Shell代码 

# yum list installed | grep ImageMagick*
ImageMagick.x86_64     6.5.4.7-7.el6_5  @base  

--验证安装结果

Shell代码 

# convert -sample 200x200 desktop.jpg desktop-200x200.jpg
# convert -sample 200x200 desktop.png desktop-200x200.png

2.安装lua-nginx-module

--下载安装LuaJIT

Shell代码 

# wget http://luajit.org/download/LuaJIT-2.0.4.tar.gz
# tar -zxvf LuaJIT-2.0.4.tar.gz 
# cd LuaJIT-2.0.2
# make
# make install

--安装lua-nginx-module

下载ngx_devel_kit,nginx_lua_module解压

Shell代码 

// 先导入环境变量,告诉nginx去哪里找luajit
# export LUAJIT_LIB=/usr/local/lib
# export LUAJIT_INC=/usr/local/include/luajit-2.0

// 查看ngixn版本极其编译参数
# /usr/local/nginx/sbin/nginx -V

// 添加ngx_devel_kit,lua-nginx-module模块,重新编译nginx
// 切勿make install,否则就成了覆盖安装
# ./configure --prefix=/usr/local/nginx \
--add-module=/usr/local/src/fastdfs-nginx-module/src \
--add-module=/usr/local/src/ngx_devel_kit-0.2.19 \
--add-module=/usr/local/src/lua-nginx-module-0.9.16
# make

// 备份旧的nginx程序,用新的nginx程序覆盖旧的
# cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
# cp ./objs/nginx /usr/local/nginx/sbin/nginx

// 再次查看ngixn版本极其编译参数,确认安装成功
# /usr/local/nginx/sbin/nginx -V
/usr/local/nginx/sbin/nginx: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory
// 将libluajit-5.1.so.2安装到/usr/lib中并重新加载
# ln -s /usr/local/lib/libluajit-5.1.so.2 /usr/lib/libluajit-5.1.so.2 
# ldconfig
# /usr/local/nginx/sbin/nginx -V

// 测试lua-nginx-module模块
// nginx配置文件加入如下配置:
location ~* ^/2328(/.*) {
      default_type 'text/plain';
      content_by_lua 'ngx.say("hello, ttlsa lua")';
}
# curl http://localhost/2328/
hello, ttlsa lua

--配置nginx实现简单自动生成缩略图

Txt代码 

// 修改nginx配置文件nginx.conf
location ~ '/images/([0-9a-z]+).jpg$' {
    root /var;
}

location ~ '/images/([0-9a-z]+)_([0-9]+)x([0-9]+).jpg$' {
    root /var;
    set $image_root '/var/images';
    set $fileName $1;
    set $width $2;
    set $height $3;
    set $origin $image_root/$fileName.jpg;
    set $file $image_root/${fileName}_${width}x$height.jpg;
    if (!-f $file) {
        rewrite_by_lua '
            local command = "convert -sample "..ngx.var.width.."x"..ngx.var.height.." "..ngx.var.origin.." "..ngx.var.file;
            os.execute(command);
         ';
  	}
}

// nginx重新加载配置
# /usr/local/nginx/sbin/nginx -s reload

// 在/var/images中上传desktop.jpg图片
访问
http://192.168.117.101/images/desktop_200x200.jpg
返回404
// 查看日志
# tail -f /usr/local/nginx/logs/error.log
convert: unable to open image `/var/images/desktop_100x100.jpg': Permission denied @ blob.c/OpenBlob/2480.

// nginx: worker process 的用户是nobody,没有root权限,无法操作/var/images的文件
// 修改/var/images的权限为所有人可修改# ps -ef | grep nginx
root     10065     1  0 00:05 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody   12100 10065  0 11:35 ?        00:00:00 nginx: worker process      
root     12108  9959  0 11:37 pts/1    00:00:00 grep nginx

访问
http://192.168.117.101/images/desktop_200x200.jpg
返回缩略图,/var/images多了对应的缩略图

--配置nginx实现简单自动生成缩略图

--进阶,将缩略图文件和原图分开存储

Txt代码 

location ~ '/images/thumbnail/([0-9a-z]+)_([0-9]+)x([0-9]+).jpg$' {
		root /var;
}

location ~ '/images/([0-9a-z]+)_([0-9]+)x([0-9]+).jpg$' { 
		root /var; 
    set $image_root '/var/images';  
    set $fileName $1;  
    set $width $2;  
    set $height $3;  
    set $origin $image_root/$fileName.jpg;  
    set $file $image_root/thumbnail/${fileName}_${width}x$height.jpg;
    set $uriNew /images/thumbnail/${fileName}_${width}x$height.jpg;
    if (-f $file) {  
    	rewrite ^ $uriNew;
    	break;
    }  
    if (!-f $origin) {
			return 404;
		} 
		rewrite_by_lua '  
			local width = tonumber(ngx.var.height);
			local height = tonumber(ngx.var.height);
			if width and height then
				local command = "convert -sample "..ngx.var.width.."x"..ngx.var.height.." "..ngx.var.origin.." "..ngx.var.file;  
      	os.execute(command); 
      	ngx.req.set_uri(ngx.var.uriNew, true);
			else 
				ngx.exit(ngx.HTTP_NOT_FOUND);
			end
   	';
}

3.nginx + lua-nginx-module + fastdfs 实现动态缩略图

/usr/local/nginx

|-conf

  |-lua

    |-fastdfs.lua

    |-restyfastdfs.lua

    |-storage.lua

    |-tracker.lua

    |-utils.lua

  |-nginx.conf

--主要的配置

nginx.conf

Txt代码 

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;
		
    <span style="color: #ff0000;">lua_package_path "/usr/local/nginx/conf/lua/?.lua;;";</span>
		
    server {
        listen       80;
        server_name  localhost;
				
	location ~ '/images/thumbnail/([0-9a-z]+)_([0-9]+)x([0-9]+).jpg$' {
		root /var;
	}
				
	location ~ '/images/([0-9a-z]+)_([0-9]+)x([0-9]+).jpg$' { 
		root /var; 
		set $image_root '/var/images';  
		set $fileName $1;  
		set $width $2;  
		set $height $3;  
		set $origin $image_root/$fileName.jpg;  
		set $file $image_root/thumbnail/${fileName}_${width}x$height.jpg;
		set $uriNew /images/thumbnail/${fileName}_${width}x$height.jpg;
		if (-f $file) {  
			rewrite ^ $uriNew;
			break;
		}  
		if (!-f $origin) {
		    	return 404;
		} 
	    	rewrite_by_lua '  
	    		local width = tonumber(ngx.var.height);
	    		local height = tonumber(ngx.var.height);
	    		if width and height then
	    			local command = "convert -sample "..ngx.var.width.."x"..ngx.var.height.." "..ngx.var.origin.." "..ngx.var.file;  
	            	        os.execute(command); 
	            	        ngx.req.set_uri(ngx.var.uriNew, true);
	    		else 
	    			ngx.exit(ngx.HTTP_NOT_FOUND);
	    		end
	         	';
		}
				
	location /group1/M00 {
            alias /var/images;

            #set $image_root "/usr/local/openresty/nginx/proxy_tmp/images";
            set $image_root "/var/images";
            if ($uri ~ "/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/(.*)") {
                set $image_dir "$image_root/$3/$4/";
                set $image_name "$5";
                set $file "$image_dir$image_name";
            }

            if (!-f $file) {
                # 关闭lua代码缓存,方便调试lua脚本
                #lua_code_cache off;
                content_by_lua_file "conf/lua/fastdfs.lua";
            }

            #ngx_fastdfs_module;
        }
				
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

fastdfs.lua

Txt代码 

-- 写入文件
local function writefile(filename, info)
    local wfile=io.open(filename, "w") --写入文件(w覆盖)
    assert(wfile)  --打开时验证是否出错		
    wfile:write(info)  --写入传入的内容
    wfile:close()  --调用结束后记得关闭
end

-- 检测路径是否目录
local function is_dir(sPath)
    if type(sPath) ~= "string" then return false end

    local response = os.execute( "cd " .. sPath )
    if response == 0 then
        return true
    end
    return false
end

-- 检测文件是否存在
local file_exists = function(name)
    local f=io.open(name,"r")
    if f~=nil then io.close(f) return true else return false end
end

local area = nil
local originalUri = ngx.var.uri;
local originalFile = ngx.var.file;
local index = string.find(ngx.var.uri, "([0-9]+)x([0-9]+)");  
if index then 
    originalUri = string.sub(ngx.var.uri, 0, index-2);  
    area = string.sub(ngx.var.uri, index);  
    index = string.find(area, "([.])");  
    area = string.sub(area, 0, index-1);  

    local index = string.find(originalFile, "([0-9]+)x([0-9]+)");  
    originalFile = string.sub(originalFile, 0, index-2)
end

-- check original file
if not file_exists(originalFile) then
    local fileid = string.sub(originalUri, 2);
    -- main
    local fastdfs = require('restyfastdfs')
    local fdfs = fastdfs:new()
    fdfs:set_tracker("192.168.117.100", 22122)
    fdfs:set_timeout(1000)
    fdfs:set_tracker_keepalive(0, 100)
    fdfs:set_storage_keepalive(0, 100)
    local data = fdfs:do_download(fileid)
    if data then
       -- check image dir
        if not is_dir(ngx.var.image_dir) then
            os.execute("mkdir -p " .. ngx.var.image_dir)
        end
        writefile(originalFile, data)
    end
end

-- 创建缩略图
local image_sizes = {"80x80", "800x600", "40x40", "60x60"};  
function table.contains(table, element)  
    for _, value in pairs(table) do  
        if value == element then
            return true  
        end  
    end  
    return false  
end 

if table.contains(image_sizes, area) then  
    local command = "convert " .. originalFile  .. " -thumbnail " .. area .. " -background gray -gravity center -extent " .. area .. " " .. ngx.var.file;  
    os.execute(command);  
end;

if file_exists(ngx.var.file) then
    --ngx.req.set_uri(ngx.var.uri, true);  
    ngx.exec(ngx.var.uri)
else
    ngx.exit(404)
end

参考资料:

https://github.com/openresty/lua-nginx-module
http://www.ttlsa.com/nginx/nginx-modules-ngx_lua/
http://www.2cto.com/os/201504/387948.html

http://houxiyang.com/archives/112/

https://github.com/hpxl/nginx-lua-fastdfs-GraphicsMagick

https://github.com/azurewang/lua-resty-fastdfs

本文转载自:http://siyuan-zhu.iteye.com/blog/2230246

chaun
粉丝 92
博文 271
码字总数 91117
作品 0
深圳
高级程序员
私信 提问
FastDFS安装 --> 测试

自己闲着没事,在小黑上虚拟了 4 个 centos 64 的系统,用来安装分布式 fastdfs 、 nginx 负载均衡,过程一路艰辛,搞了一个通宵都没弄好,终于在第二天的傍晚终于弄好了,记录一下过程。 有...

shking
2013/10/05
485
1
使用FastDFS搭建图片服务器(单实例)

FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux、FreeBSD、AIX等UNIX系统。它只能通过 专有API对文件进行存取访问,不支持POSIX接口方式,不能mount使用。准确地...

haoyuehong
2018/09/12
237
0
Ubuntu 14.04下部署FastDFS 5.08+Nginx 1.13.0

环境 Ubuntu 14.04 用户 admin 数据目录: /fastdfs 安装包:FastDFS v5.05 一、下载安装libfastcommon 1.1、上传或下载 libfastcommon-master.zip 到/usr/local/src 目录 1.2、解压 1.3、编...

paascloud
2017/05/29
0
0
FastDfs 分布式文件系统 (实测成功)

最近公司需要搭建一台FastDfs 分布式文件系统,查询和参考了网络很多资料,但是从头到尾按他们的配置,中间都会或多或少的出错,可能是版本的问题,也可能是其他问题,经过自己不断的研究,终...

神游1214
04/24
0
0
FastDFS服务器集群部署和集成客户端到SpringBoot

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题,同时也能做到在集群环...

maoqitian
2018/11/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部