openresty + lua-resty-weedfs + weedfs + graphicsmagick动态生成缩略图(类似淘宝方案)

--大部分的网站都要涉及到图片缩略图的处理,比如新闻配图,电商,微信朋友圈等,贴别是电商类网站,每个商品图对应多个不同尺寸的缩略图,用于不同的页面。

网站刚开始的时候,大家为了赶工期,尽快完成开发任务,基本上都会选择比较简单的方式实现功能,直接使用web服务器的图片上传和下载的功能。而且是单机部署。但问题是,图片响应速度比较慢,而且当访问量逐渐加大,服务器由单台变为多台时,这种方式扩展性较差。

我们自己的解决方案规划了几种:

  1. 使用web server上传,后面使用openresty +lua + graphicsmagick 将生成缩略图功能独立出来,与web程序解耦。(目前在投入使用,准备换掉)
  2. 将图片的上传,管理交由ftpserver处理,后面使用openresty +lua + graphicsmagick 将生成缩略图功能独立出来,与web程序解耦。(目前在投入使用)
  3. 将图片的上传,分布式管理 交由seaweedfs管理,可提供更快的响应速度,更方便,无痛的分布式扩展节点,billion 级别的。后面使用openresty + lua-resty-weedfs + graphicsmagick 生成缩略图功能独立处理。(准备投入使用)
  4. 使用七牛、又拍云提供的云存储及数据处理服务,解决图片的处理、存储、多节点访问速度的问题,这种方式优点是方案成熟,相应的有一定费用和开发工作,另外有一些小概率的风险,比如云服务挂掉影响本站访问。(方便的解决方案,下一节阶段重点考虑)

1,2 中解决方案,比较简单,就不具体细说,下面重点配置实做一下方案3.

所用软件版本信息:

服务器环境: ubuntu 13.10

openresty: 1.7.10.2

lua-resty-weedfs: master

weedfs(seaweedfs): v0.70beta

graphicsmagick: 1.3.16

安装步骤如下:

1.安装依赖的软件包:

  1. sudo apt-get install libreadline-dev libpcre3-dev libssl-dev perl
  2. sudo apt-cache search libjpeg
  3. sudo apt-cache search libpng
  4. sudo apt-get install libjpeg62 libpng12-0

2:安装openresty,现在最新版本的openresty1.7.10.2:

  1. sudo mkdir working
  2. cd working
  3. sudo wget https://openresty.org/download/ngx_openresty-1.7.10.2.tar.gz
  4. tar xzvf ngx_openresty-VERSION.tar.gz
  5. cd ngx_openresty-VERSION/
  6. sudo ./configure --with-luajit \
  7. --with-http_iconv_module \
  8. --with-http_stub_status_module --with-openssl=/usr/local/ssl/lib --with-http_ssl_module
  9. 后面两个with,如果不能满足条件,不安装也可以
  10. sudo make
  11. sudo make install
  12. 安装成功后,在/usr/local/openresty/

3: 安装graphicsmagic

  1. sudo add-apt-repository ppa:dhor/myway
  2. sudo apt-get update
  3. sudo apt-get install graphicsmagick
  4. gm help

4:配置,并启动openresty 也即nginx

  1. cd ~/working
  2. mkdir logs/ conf/
  3. sudo vi conf/nginx.conf
  4. 输入一下内容
  5. =======start===========
  6. worker_processes 1;
  7. error_log logs/error.log;
  8. events {
  9. worker_connections 1024;
  10. }
  11. http {
  12. server {
  13. listen 8090;
  14. location / {
  15. default_type text/html;
  16. content_by_lua '
  17. ngx.say("<p>hello, world</p>")
  18. ';
  19. }
  20. }
  21. }
  22. =========end==============

添加nginx 到path,方便执行

  1. PATH=/usr/local/openresty/nginx/sbin:$PATH
  2. export PATH
  3. nginx -p `pwd`/ -c conf/nginx.conf
  4. curl http://localhost:8090/

输出:

  1. <p>hello, world</p>

5.安装weedfs

  1. sudo wget https://bintray.com/artifact/download/chrislusf/seaweedfs/weed_0.70beta_linux_amd64.tar.gz
  2. tar zxvf weed_0.70beta_linux_amd64.tar.gz

start master server

./weed master

start volume server

  1. cd ~/working
  2. mkdir 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:

  1. {"fid":"7,02a3a52531","url":"127.0.0.1:9080","publicUrl":"127.0.0.1:9080","count":1}

second:

  1. curl -X PUT -F file=@./detail_01.jpg http://127.0.0.1:9080/7,02a3a52531

output:

  1. {"name":"detail_01.jpg","size":176946}

read file:

  1. curl http://localhost:9333/dir/lookup?volumeId=7

output:

  1. {"volumeId":"7","locations":[{"url":"127.0.0.1:9080","publicUrl":"127.0.0.1:9080"}]}

或者通过网页显示图片:

  1. http://192.168.15.201:9080/7/02a3a52531/detail_01.jpg
  2. http://192.168.15.201:9080/7/02a3a52531.jpg
  3. http://192.168.15.201:9080/7,02a3a52531.jpg
  4. http://192.168.15.201:9080/7/02a3a52531
  5. http://192.168.15.201:9080/7,02a3a52531

6.openresty 与 weedfs结合,配置 lua_resty_weedfs

  1. cd ~/woring
  2. git clone https://github.com/medcl/lua-resty-weedfs.git
  3. cd /usr/local/openresty/nginx/conf
  4. mv nginx.conf nginx.conf.backup
  5. mv ~/woring/lua-resty-weedfs/resty ./resty
  6. mv ~/woring/lua-resty-weedfs/nginx.conf ./nginx.conf
  7. mv ~/woring/lua-resty-weedfs/weedfs.lua ./weedfs.lua

创建 www-data 组和用户,创建路径/home/wwwroot/weedfs.

nginx.conf 如下:

  1. user www-data www-data;
  2. worker_processes 8;
  3. daemon on;
  4. master_process off;
  5. error_log logs/error.log error;
  6. #error_log logs/error.log info;
  7. pid logs/nginx.pid;
  8. env MOCKEAGAIN_VERBOSE;
  9. env MOCKEAGAIN_WRITE_TIMEOUT_PATTERN;
  10. env LD_PRELOAD;
  11. env DYLD_INSERT_LIBRARIES;
  12. worker_rlimit_nofile 65535;
  13. events {
  14. worker_connections 65535;
  15. }
  16. http {
  17. include mime.types;
  18. default_type application/octet-stream;
  19. # default_type text/plain;
  20. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  21. '$status $body_bytes_sent "$http_referer" '
  22. '"$http_user_agent" "$http_x_forwarded_for"';
  23. access_log logs/access.log main;
  24. server_names_hash_bucket_size 128;
  25. client_header_buffer_size 32k;
  26. large_client_header_buffers 4 32k;
  27. client_max_body_size 8m;
  28. keepalive_timeout 0;
  29. sendfile on;
  30. tcp_nopush on;
  31. tcp_nodelay on;
  32. fastcgi_connect_timeout 300;
  33. fastcgi_send_timeout 300;
  34. fastcgi_read_timeout 300;
  35. fastcgi_buffer_size 64k;
  36. fastcgi_buffers 4 64k;
  37. fastcgi_busy_buffers_size 128k;
  38. fastcgi_temp_file_write_size 128k;
  39. ##cache##
  40. proxy_connect_timeout 5;
  41. proxy_read_timeout 60;
  42. proxy_send_timeout 5;
  43. proxy_buffer_size 16k;
  44. proxy_buffers 4 64k;
  45. proxy_busy_buffers_size 128k;
  46. proxy_temp_file_write_size 128k;
  47. proxy_temp_path temp_dir;
  48. proxy_cache_path cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;
  49. ##end##
  50. open_file_cache max=1000 inactive=20s;
  51. open_file_cache_min_uses 5;
  52. open_file_cache_valid 30s;
  53. gzip on;
  54. gzip_min_length 1k;
  55. gzip_buffers 4 16k;
  56. gzip_http_version 1.1;
  57. gzip_comp_level 2;
  58. gzip_types text/plain application/x-javascript text/css application/xml;
  59. gzip_disable "MSIE [1-6]\.";
  60. gzip_vary on;
  61. #keepalive_timeout 65;
  62. #problematic
  63. #lua_code_cache off;
  64. lua_package_path "/usr/local/openresty/lualib/?.lua;;";
  65. resolver 8.8.8.8;
  66. server {
  67. listen 80;
  68. server_name localhost;
  69. rewrite_log on;
  70. charset utf-8,gbk;
  71. #access_log logs/host.access.log main;
  72. #note:must end with“/”
  73. set $weed_audio_root_url "http://127.0.0.1:9080/";
  74. set $weed_audio_root_url "http://127.0.0.1:9081/";
  75. set $weed_img_root_url "http://127.0.0.1:9080/";
  76. set $weed_img_root_url "http://127.0.0.1:9081/";
  77. set $local_img_fs_root "/home/wwwroot/weedfs/";
  78. set $local_audio_fs_root "/home/wwwroot/weedfs/";
  79. location / {
  80. root /home/wwwroot/weedfs/;
  81. index index.html index.htm;
  82. }
  83. #sample:/_img/?size=orig&volumn=1&id=1234
  84. location /_img/{
  85. default_type image/jpeg;
  86. if ($request_method = 'DELETE' ) {
  87. return 405;
  88. }
  89. if ($request_method = 'PUT' ) {
  90. return 405;
  91. }
  92. if ($request_method = 'POST' ) {
  93. return 405;
  94. }
  95. #content_by_lua 'ngx.say("<p>process here</p>")';
  96. content_by_lua_file conf/weedfs.lua;
  97. expires 30d;
  98. # access_log off;
  99. }
  100. # location /img/orig/{
  101. # proxy_set_header X-Real-IP $remote_addr;
  102. # proxy_set_header X-Forwarded-For $remote_addr;
  103. # proxy_set_header Host $http_host;
  104. #
  105. # # if ($uri ~* "/img/orig/([0-9]+)/([a-z0-9]+)(\.[a-z]+)?") {
  106. # # rewrite "/img/orig/([0-9]+)/([a-z0-9]+)(\.[a-z]+)" /img/orig/$1,$2$3 permanent;
  107. # # break;
  108. # # }
  109. #
  110. # proxy_pass http://192.168.2.100:8080/;
  111. # expires 7d;
  112. # break;
  113. # }
  114. location /img/{
  115. 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;
  116. 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;
  117. rewrite "/img/orig/([0-9]+)[,/]([a-z0-9]+)(\.[a-z]+)?" /_img/?type=img&size=orig&volumn=$1&id=$2 last;
  118. expires 30d;
  119. # access_log off;
  120. }
  121. location /_audio/{
  122. default_type audio/mp3;
  123. if ($request_method = 'DELETE' ) {
  124. return 405;
  125. }
  126. if ($request_method = 'PUT' ) {
  127. return 405;
  128. }
  129. if ($request_method = 'POST' ) {
  130. return 405;
  131. }
  132. content_by_lua_file conf/weedfs.lua;
  133. expires 30d;
  134. # access_log off;
  135. }
  136. #if you specified audio_fs_root separately,you should change this.
  137. #location /audios{
  138. # default_type audio/mp3;
  139. # root /home/wwwroot/audios;
  140. # expires 30d;
  141. # access_log off;
  142. # }
  143. location /audio/{
  144. rewrite "/audio/(mp3)/([0-9]+)/([a-z0-9]+)(\.[a-z]+)?" /_audio/?type=audio&size=$1&volumn=$2&id=$3 last;
  145. rewrite "/audio/(mp3)/([0-9]+),([a-z0-9]+)(\.[a-z]+)?" /_audio/?type=audio&size=$1&volumn=$2&id=$3 last;
  146. rewrite "/audio/orig/([0-9]+),([a-z0-9]+)(\.[a-z]+)?" /_audio/?type=audio&size=orig&volumn=$1&id=$2 last;
  147. expires 30d;
  148. # access_log off;
  149. }
  150. # location /upload{
  151. # if ($request_method = 'DELETE' ) {
  152. # return 405;
  153. # }
  154. # if ($request_method = 'PUT' ) {
  155. # return 405;
  156. # }
  157. #
  158. # proxy_pass $weed_xxx_root_url;
  159. # proxy_redirect default ;
  160. # }
  161. location /favicon.ico{
  162. root /home/wwwroot/;
  163. # access_log off;
  164. }
  165. error_page 404 /404.html;
  166. error_page 500 502 503 504 /50x.html;
  167. location = /50x.html {
  168. root html;
  169. }
  170. location ~ /\.ht {
  171. deny all;
  172. }
  173. location /status {
  174. stub_status on;
  175. access_log off;
  176. }
  177. }
  178. }

7.重新启动nginx 运行

  1. 访问 http://192.168.15.201/img/100x100/7,02a3a52531.jpg 成功
  2. http://192.168.15.201/img/100x100s/7,02a3a52531.jpg
  3. 增加s后,自动适应比例生成缩略图

8、参考文档

http://soltex.iteye.com/blog/2064749

https://github.com/chrislusf/seaweedfs

http://openresty.org/

openresty + lua-resty-weedfs + weedfs + graphicsmagick动态生成缩略图(类似淘宝方案)的更多相关文章

  1. Nginx 整合 Lua 实现动态生成缩略图

    原文地址:Nginx 整合 Lua 实现动态生成缩略图 博客地址:http://www.extlight.com 一.前提 最近在开发一个项目,涉及到缩略图的功能,常见的生成缩略图的方案有以下几个: ...

  2. 如何安装nginx_lua_module模块,升级nginx,nginx-lua-fastdfs-GraphicsMagick动态生成缩略图,实现图片自动裁剪缩放

    如何安装nginx_lua_module模块,升级nginx,nginx-lua-fastdfs-GraphicsMagick动态生成缩略图,实现图片自动裁剪缩放 参考网站:nginx-lua-fas ...

  3. nginx利用image_filter动态生成缩略图

    转自:http://www.nginx.cn/2160.html "我如今是有些图片须要生成缩略图.这个如今加了image_filter这个已经实现了.但我不知道怎么样才干訪问我上传的原图& ...

  4. 动态权限<二>之淘宝、京东、网易新闻 权限申请交互设计对比分析

    移动智能设备的快速普及,给生活带来巨大的精彩,但是智能设备上用户的信息数据很多,隐私数据也非常多,各种各样的app可能通过各种方式在悄悄的收集用户数据,而用户的隐私就变得耐人寻味了.比如之前的可以无限 ...

  5. (转)php 根据url自动生成缩略图并处理高并发问题

    分享是一种精神,与技术高低无关!   图片缩略图动态生成- [代码编程] 2011-08-23 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明http://www.blogbus.c ...

  6. axure 动态面板实现图片轮播效果(淘宝)

    淘宝中经常可以看到店铺中的图片轮播效果,本经验将通过axure7.0实现 工具/原料   axure7.0 方法/步骤     下载需要轮播的图片   将图片引入至axure中,将引入的第一张图片转为 ...

  7. LUA+resty 搭建验证码服务器

    使用Lua和OpenResty搭建验证码服务器 雨客 2016-04-08 16:38:11 浏览2525 评论0 云数据库Redis版 摘要: Lua下有个Lua-GD图形库,通过简单的Lua语句就 ...

  8. openresty+lua劫持请求,有点意思

    0x01 起因 几天前学弟给我介绍他用nginx搭建的反代,代理了谷歌和维基百科. 由此我想到了一些邪恶的东西:反代既然是所有流量走我的服务器,那我是不是能够在中途做些手脚,达到一些有趣的目的. op ...

  9. openresty+lua在反向代理服务中的玩法

    openresty+lua在反向代理服务中的玩法 phith0n · 2015/06/02 10:35 0x01 起因 几天前学弟给我介绍他用nginx搭建的反代,代理了谷歌和维基百科. 由此我想到了 ...

随机推荐

  1. android开发要避免的那些坑

    SparseArray 目前有很多地方从性能优化方说使用SparseArray来替换hashMap,来节省内存,提高性能. Linkify.addLinks() 这个类可以更方便的为文本添加超链接. ...

  2. ASP.NET实现网页版小优盘

    今天看到了一篇不错的文章,就拿来一起分享一下吧. 实现的是文件的上传与下载功能. 关于文件上传: 谈及文件上传到网站上,首先我们想到的就是通过什么上传呢?在ASP.NET中,只需要用FileUploa ...

  3. 深度剖析malloc、free和new、delete

    1.malloc,free是C语言的函数,而new,delete是操作符,属于C++的语法,一定注意这两个不再是函数了,而是操作符. 2.malloc和new对于分配基础类型变量和数组变量,它们除了语 ...

  4. 从JDK源码角度看线程的阻塞和唤醒

    目前在Java语言层面能实现阻塞唤醒的方式一共有三种:suspend与resume组合.wait与notify组合.park与unpark组合.其中suspend与resume因为存在无法解决的竟态问 ...

  5. Mybatis接口编程原理分析(三)

    前面两篇博客Mybatis接口编程原理分析(一)和Mybatis接口编程原理分析(二)我们介绍了MapperProxyFactory.MapperProxy和MapperMethod的操作及源码分析, ...

  6. javascript之自定义数组工具对象

    <pre name="code" class="html">/* 需求:编写一个js文件,在js文件中自定义一个数组工具对象, 该工具对象要有一个找 ...

  7. rt-thread的位图调度算法分析

    转自:http://blog.csdn.net/prife/article/details/7077120 序言 期待读者 本文期待读者有C语言编程基础,后文中要分析代码,对其中的一些C语言中的简单语 ...

  8. OC语言(七)Block复习

    看下面一道Block的面试题: int i = 10; void(^myBlock)() = ^{ NSLog(@"%d",i); }; i = 100; myBlock(); 经 ...

  9. ZooKeeper 客户端的使用

    连接zk 1 2 cd bin zkCli.sh -timeout 5000 -server 27.154.242.214:5091 输入h,回车查看帮助 1 2 3 4 5 6 7 8 9 10 1 ...

  10. python的安装,IDLE基本操作

    §一.安装Python 1. 下载Active Python安装包 根据你机器型号download Python,32b选择for windows X86,64b选择for window 64b 2. ...