openresty + lua-resty-weedfs + weedfs + graphicsmagick动态生成缩略图(类似淘宝方案) --大部分的网站都要涉及到图片缩略图的处理,比如新闻配图,电
openresty + lua-resty-weedfs + weedfs + graphicsmagick动态生成缩略图(类似淘宝方案)
--大部分的网站都要涉及到图片缩略图的处理,比如新闻配图,电商,微信朋友圈等,贴别是电商类网站,每个商品图对应多个不同尺寸的缩略图,用于不同的页面。
网站刚开始的时候,大家为了赶工期,尽快完成开发任务,基本上都会选择比较简单的方式实现功能,直接使用web服务器的图片上传和下载的功能。而且是单机部署。但问题是,图片响应速度比较慢,而且当访问量逐渐加大,服务器由单台变为多台时,这种方式扩展性较差。
我们自己的解决方案规划了几种:
- 使用web server上传,后面使用openresty +lua + graphicsmagick 将生成缩略图功能独立出来,与web程序解耦。(目前在投入使用,准备换掉)
- 将图片的上传,管理交由ftpserver处理,后面使用openresty +lua + graphicsmagick 将生成缩略图功能独立出来,与web程序解耦。(目前在投入使用)
- 将图片的上传,分布式管理 交由seaweedfs管理,可提供更快的响应速度,更方便,无痛的分布式扩展节点,billion 级别的。后面使用openresty + lua-resty-weedfs + graphicsmagick 生成缩略图功能独立处理。(准备投入使用)
- 使用七牛、又拍云提供的云存储及数据处理服务,解决图片的处理、存储、多节点访问速度的问题,这种方式优点是方案成熟,相应的有一定费用和开发工作,另外有一些小概率的风险,比如云服务挂掉影响本站访问。(方便的解决方案,下一节阶段重点考虑)
1,2 中解决方案,比较简单,就不具体细说,下面重点配置实做一下方案3.
所用软件版本信息:
.服务器环境: ubuntu 13.10
. .openresty: 1.7.10.2
. .lua-resty-weedfs: master
. .weedfs(seaweedfs): v0.70beta
. .graphicsmagick: 1.3.16
.安装步骤如下:
1.安装依赖的软件包:
sudo apt-get install libreadline-dev libpcre3-dev libssl-dev perlsudo apt-cache search libjpegsudo apt-cache search libpngsudo apt-get install libjpeg62 libpng12-0
2:安装openresty,现在最新版本的openresty1.7.10.2:
sudo mkdir workingcd workingsudo wget https://openresty.org/download/ngx_openresty-1.7.10.2.tar.gztar xzvf ngx_openresty-VERSION.tar.gzcd ngx_openresty-VERSION/sudo ./configure --with-luajit / --with-http_iconv_module / --with-http_stub_status_module --with-openssl=/usr/local/ssl/lib --with-http_ssl_module后面两个with,如果不能满足条件,不安装也可以sudo makesudo make install安装成功后,在/usr/local/openresty/
3: 安装graphicsmagic
sudo add-apt-repository ppa:dhor/mywaysudo apt-get updatesudo apt-get install graphicsmagickgm help
4:配置,并启动openresty 也即nginx
cd ~/workingmkdir logs/ conf/sudo vi conf/nginx.conf输入一下内容=======start===========worker_processes 1;error_log logs/error.log;events { worker_connections 1024;}http { server { listen 8090; location / { default_type text/html; content_by_lua ' ngx.say("<p>hello, world</p>") '; } }}=========end==============
添加nginx 到path,方便执行
PATH=/usr/local/openresty/nginx/sbin:$PATHexport PATHnginx -p `pwd`/ -c conf/nginx.confcurl http://localhost:8090/
输出:
<p>hello, world</p>
5.安装weedfs
sudo wget https://bintray.com/artifact/download/chrislusf/seaweedfs/weed_0.70beta_linux_amd64.tar.gztar zxvf weed_0.70beta_linux_amd64.tar.gz
start master server
../weed master
.start volume server
cd ~/workingmkdir data
. weed volume -dir="../data" -max=5 -mserver="localhost:9333" -port=9080 &
. .weed volume -dir="../data" -max=5 -mserver="localhost:9333" -port=9081 &
.write file
.curl -X POST http://localhost:9333/dir/assign
.output:
{"fid":"7,02a3a52531","url":"127.0.0.1:9080","publicUrl":"127.0.0.1:9080","count":1}
second:
curl -X PUT -F file=@./detail_01.jpg http://127.0.0.1:9080/7,02a3a52531
output:
{"name":"detail_01.jpg","size":176946}
read file:
curl http://localhost:9333/dir/lookup?volumeId=7
output:
{"volumeId":"7","locations":[{"url":"127.0.0.1:9080","publicUrl":"127.0.0.1:9080"}]}
或者通过网页显示图片:
http://192.168.15.201:9080/7/02a3a52531/detail_01.jpghttp://192.168.15.201:9080/7/02a3a52531.jpghttp://192.168.15.201:9080/7,02a3a52531.jpghttp://192.168.15.201:9080/7/02a3a52531http://192.168.15.201:9080/7,02a3a52531
6.openresty 与 weedfs结合,配置 lua_resty_weedfs
cd ~/woringgit clone https://github.com/medcl/lua-resty-weedfs.gitcd /usr/local/openresty/nginx/confmv nginx.conf nginx.conf.backupmv ~/woring/lua-resty-weedfs/resty ./restymv ~/woring/lua-resty-weedfs/nginx.conf ./nginx.confmv ~/woring/lua-resty-weedfs/weedfs.lua ./weedfs.lua
创建 www-data 组和用户,创建路径/home/wwwroot/weedfs.
nginx.conf 如下:
user www-data www-data;worker_processes 8;daemon on;master_process off;error_log logs/error.log error;#error_log logs/error.log info;pid logs/nginx.pid;env MOCKEAGAIN_VERBOSE;env MOCKEAGAIN_WRITE_TIMEOUT_PATTERN;env LD_PRELOAD;env DYLD_INSERT_LIBRARIES;worker_rlimit_nofile 65535;events { worker_connections 65535;}http { include mime.types; default_type application/octet-stream; # default_type text/plain; 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; server_names_hash_bucket_size 128; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 8m; keepalive_timeout 0; sendfile on; tcp_nopush on; tcp_nodelay on; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; ##cache## proxy_connect_timeout 5; proxy_read_timeout 60; proxy_send_timeout 5; proxy_buffer_size 16k; proxy_buffers 4 64k; proxy_busy_buffers_size 128k; proxy_temp_file_write_size 128k; proxy_temp_path temp_dir; proxy_cache_path cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g; ##end## open_file_cache max=1000 inactive=20s; open_file_cache_min_uses 5; open_file_cache_valid 30s; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_disable "MSIE [1-6]/."; gzip_vary on; #keepalive_timeout 65; #problematic #lua_code_cache off; lua_package_path "/usr/local/openresty/lualib/?.lua;;"; resolver 8.8.8.8; server { listen 80; server_name localhost; rewrite_log on; charset utf-8,gbk; #access_log logs/host.access.log main; #note:must end with“/” set $weed_audio_root_url "http://127.0.0.1:9080/"; set $weed_audio_root_url "http://127.0.0.1:9081/"; set $weed_img_root_url "http://127.0.0.1:9080/"; set $weed_img_root_url "http://127.0.0.1:9081/"; set $local_img_fs_root "/home/wwwroot/weedfs/"; set $local_audio_fs_root "/home/wwwroot/weedfs/"; location / { root /home/wwwroot/weedfs/; index index.html index.htm; } #sample:/_img/?size=orig&volumn=1&id=1234 location /_img/{ default_type image/jpeg; if ($request_method = 'DELETE' ) { return 405; } if ($request_method = 'PUT' ) { return 405; } if ($request_method = 'POST' ) { return 405; } #content_by_lua 'ngx.say("<p>process here</p>")'; content_by_lua_file conf/weedfs.lua; expires 30d;# access_log off; } # location /img/orig/{# proxy_set_header X-Real-IP $remote_addr;# proxy_set_header X-Forwarded-For $remote_addr;# proxy_set_header Host $http_host;## # if ($uri ~* "/img/orig/([0-9]+)/([a-z0-9]+)(/.[a-z]+)?") {# # rewrite "/img/orig/([0-9]+)/([a-z0-9]+)(/.[a-z]+)" /img/orig/$1,$2$3 permanent;# # break;# # }## proxy_pass http://192.168.2.100:8080/;# expires 7d;# break;# } location /img/{ rewrite "/img/([0-9]+x[0-9]+s?)/([0-9]+)/([a-z0-9]+)(/.[a-z]+)?" /_img/?type=img&size=$1&volumn=$2&id=$3 last; rewrite "/img/([0-9]+x[0-9]+s?)/([0-9]+),([a-z0-9]+)(/.[a-z]+)?" /_img/?type=img&size=$1&volumn=$2&id=$3 last; rewrite "/img/orig/([0-9]+)[,/]([a-z0-9]+)(/.[a-z]+)?" /_img/?type=img&size=orig&volumn=$1&id=$2 last; expires 30d; # access_log off; } location /_audio/{ default_type audio/mp3; if ($request_method = 'DELETE' ) { return 405; } if ($request_method = 'PUT' ) { return 405; } if ($request_method = 'POST' ) { return 405; } content_by_lua_file conf/weedfs.lua; expires 30d; # access_log off; } #if you specified audio_fs_root separately,you should change this. #location /audios{ # default_type audio/mp3; # root /home/wwwroot/audios; # expires 30d; # access_log off; # } location /audio/{ rewrite "/audio/(mp3)/([0-9]+)/([a-z0-9]+)(/.[a-z]+)?" /_audio/?type=audio&size=$1&volumn=$2&id=$3 last; rewrite "/audio/(mp3)/([0-9]+),([a-z0-9]+)(/.[a-z]+)?" /_audio/?type=audio&size=$1&volumn=$2&id=$3 last; rewrite "/audio/orig/([0-9]+),([a-z0-9]+)(/.[a-z]+)?" /_audio/?type=audio&size=orig&volumn=$1&id=$2 last; expires 30d; # access_log off; }# location /upload{# if ($request_method = 'DELETE' ) {# return 405;# }# if ($request_method = 'PUT' ) {# return 405;# }## proxy_pass $weed_xxx_root_url;# proxy_redirect default ;# } location /favicon.ico{ root /home/wwwroot/; # access_log off; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location ~ //.ht { deny all; } location /status { stub_status on; access_log off; } }}
7.重新启动nginx 运行
访问 http://192.168.15.201/img/100x100/7,02a3a52531.jpg 成功 http://192.168.15.201/img/100x100s/7,02a3a52531.jpg 增加s后,自动适应比例生成缩略图
8、参考文档
.http://soltex.iteye.com/blog/2064749
. .https://github.com/chrislusf/seaweedfs
. .http://openresty.org/
.