nginx-image模块和fastdfs module的协作

来源:互联网 发布:怎么跟淘宝办理假护照 编辑:程序博客网 时间:2024/06/15 22:02

Weakyon blog


http://weakyon.com/2014/11/06/nginx-image-modules-with-fastdfs.html

转自别人博客,找了好多这个解决了我的问题,放这里以备忘,上面链接为原文地址。

nginx-image模块和fastdfs module的协作

FastDFS组合nginx的httpimagefilter_module建立的图片服务器,实现动态缩略图

用fastdfs存储图片,然后用nginx的图片处理模块httpimagefilter_module处理图片,根据输入的地址中的图片大小动态生成缩略图

原图http://192.168.8.127:801/group1/ ... WAAL8RoEHXq8410.jpg

动态生成的缩略图地址

http://192.168.8.127:801/group1/ ... HXq8410,222x222.jpg

http://192.168.8.127:801/group1/ ... HXq8410,555x555.jpg

通过在图片后面加入,axb

就能生成a,b为参数的缩略图

方法:

1、首先安装好fastdfs,并可以保证上传图片和访问图片正常(不会了,参考群里“Richard老兄写的FASTDFS 安装配置指南”这个文章写的很简单明了)

2、然后下载FastDFS的fastdfs-nginx-module模块

3、编译安装nginx,编译nginx的时候,注意带上这个2个模块,一个是nginx调用fastdfs的模块,一个是nginx的图片处理模块

--add-module=/software/fastdfs-nginx-module/src       --with-http_image_filter_module

4、安装好nginx后,启动nginx和fastdfs,修改nginx的配置文件nginx.conf,修改/etc/fdfs/mod_fastdfs.conf

mod_fastdfs.conf需要修改的如下:

base_path=/fastdfstracker_server=172.16.3.15:22122tracker_server=172.16.3.16:22122group_name=group1url_have_group_name = truestore_path_count=1store_path0=/fastdfsresponse_mode=proxy鱼大说responese_mode如果为redirect,那么手机看图片会有问题

nginx.conf需要修改的如下:

在server段插入如下配置段

location ~ /group[0-9]/M[0-1][0-9]/.*,([0-9]+)x([0-9]+)\.(jpg|png|gif)$ {            alias   /fastdfs/data;    ngx_fastdfs_module;    set $img_width2 $1;    set $img_height2 $2;    rewrite ^(.*),[0-9]+x[0-9]+\.(jpg|png|gif)$ $1.$2  break;    image_filter resize  $img_width2   $img_height2;}location ~ /group[0-9]/M[0-1][0-9]/(.*){    alias   /fastdfs/data;    ngx_fastdfs_module;}

配置就是这么多

... HXq8410.jpg是group1的图片

... HXq8411.jpg是group2的图片

http://192.168.8.127:801/group1/ ... HXq8410.jpg

http://192.168.8.127:801/group2/ ... HXq8411.jpg

http://192.168.8.127:801/group1/ ... HXq8410,222x222.jpg

http://192.168.8.127:801/group2/ ... HXq8411,222x222.jpg

都应该能访问的到

然而http://192.168.8.127:801/group2/ ... HXq8411,222x222.jpg,这个跨组调用,经常会返回HTTP/1.1 415 Unsupported Media Type

经过初步的诊断,由于nginx的流式处理,fdfsmodule有时候在尚未完全下载到图片的时候,image module就开始运作了,这时image module的缓冲区是0字节数据,因此直接对图片格式判断不支持,从而导致出错。对image module简单的修改,使得fdfsmodule和image_module可以协作不报错。

修改了image模块的一部分来使得两模块协作正常


在贴代码之前,首先稍微对Nginx的I/O机制做一定的介绍,Nginx允许handler一次产生一组输出,可以产生多次,Nginx将输出组织成一个单链表结构,链表中的每个节点是一个chaint,定义在core/ngxbuf.h:

struct ngx_chain_s {    ngx_buf_t    *buf;    ngx_chain_t  *next;};

其中ngxchaint是ngxchains的别名,buf为某个数据缓冲区的指针,next指向下一个链表节点,可以看到这是一个非常简单的链表。ngxbuft的定义比较长而且很复杂,这里就不贴出来了,请自行参考core/ngxbuf.h。ngxbutt中比较重要的是pos和last,分别表示要缓冲区数据在内存中的起始地址和结尾地址,这里我们将配置中字符串传进去,lastbuf是一个位域,设为1表示此缓冲区是链表中最后一个元素,为0表示后面还有元素。因为我们只有一组数据,所以缓冲区链表中只有一个节点,如果需要输入多组数据可将各组数据放入不同缓冲区后插入到链表。下图展示了Nginx缓冲链表的结构:

nginx io介绍图

缓冲数据准备好后,用ngxhttpoutputfilter就可以输出了(会送到filter进行各种过滤处理)。ngxhttpoutputfilter的第一个参数为ngxhttprequestt结构,第二个为输出链表的起始地址&out。ngxhttpoutput_filter会遍历链表,输出所有数据。


下面是修改的代码

if (ctx->type == NGX_HTTP_IMAGE_NONE) {    if (conf->filter == NGX_HTTP_IMAGE_SIZE) {        out.buf = ngx_http_image_json(r, NULL);        if (out.buf) {            out.next = NULL;            ctx->phase = NGX_HTTP_IMAGE_DONE;            return ngx_http_image_send(r, ctx, &out);        }    }    if(in->buf->last == in->buf->pos)        return NGX_OK;    return ngx_http_filter_finalize_request(r,            &ngx_http_image_filter_module,            NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);}

插入的代码只有一句

if(in->buf->last == in->buf->pos)    return NGX_OK;

如果last和pos地址相同,说明图片尚未完整接收到,那么返回NGX_OK来跳过下面的步骤,等待下次流式处理。

用http_load对缩略图模块进行压测,全部是200的返回值,TPS并不高,瓶颈在nginx服务器的CPU上

如果比较懒,可以直接用https://github.com/tedcy/fastdfs_build这个我的开源fastdfs部署脚本进行部署

解压后./build -n trackerip1,trackerip2 -g group_name即可

如./build -n 192.168.1.1,192.168.1.2 -g 1

参考资料:

解剖Nginx·模块开发篇(1)跑起你的 Hello World 模块!

Nginx模块开发入门

06 Nov 2014


0 0
原创粉丝点击