`
russelltao
  • 浏览: 157714 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

nginx module 开发谈(4)

 
阅读更多

3、对HTTP body的处理

上面我们已经开始处理http request header了,接下来,如果请求中有body内容,那么需要处理body了。这里你肯定不会想要去阻塞式的读取body吧?body的长度可大可小,网络环境也巨复杂,只要有阻塞操作肯定玩完。Nginx这时已经准备了一个现成的读取body的非阻塞模式给用户,就是ngx_http_read_client_request_body方法。

大家看下ngx_http_read_client_request_body方法的原型:

ngx_int_t

ngx_http_read_client_request_body(ngx_http_request_t *r,ngx_http_client_body_handler_pt post_handler)

参数r就是要处理的请求,post_handler则是body接收完成后的回调方法。

所以,在worker进程中,调用ngx_http_read_client_request_body是不会阻塞的,要么读完socket上的buffer发现不完整立刻返回,等待下一次EPOLLIN事件,要么就是读完body了,调用用户定义的post_handler方法去处理body

ngx_http_read_client_request_body提供两种保存body的方式,一种是把body存储在内存中,另一种是把body存储到临时文件里。这个临时文件也有不同的处理方法,一种是请求结束后nginx便清理掉,另外就是永久保留这个临时文件。例如下面这两个参数就会设定为每个body都存放到临时文件里,并且这个临时文件在请求结束后不会被删除:

r->request_body_in_persistent_file = 1;

r->request_body_in_file_only = 1;

貌似ngx_http_read_client_request_body已经提供了很足够的功能了,其实不然。比如,我现在实现的业务中,就要求针对不同的请求,我要把body放到不同的目录下,也就是不同的mountpoint点上。这样,如果我把临时body指定到同一个mountpoint点下,相当于已经存储到远程机器上了,但是nginxngx_http_read_client_request_body方法是不提供这个功能的,它的临时文件目录早在编译时已经通过--http-client-body-temp-path=指定了,无法在运行时更改,比较恶心的实现。我想实现这个功能,只能自己重构下接收body这套方法了。这里我把我的处理方法(修改自ngx_http_read_client_request_body处理步骤)说下,方便大家理解body的接收过程。

在我决定开始接收body后,首先调用ngx_http_read_webex_DMD_request_body方法,同时把处理完整body的勾子函数ngx_webex_DMD_handler_request_body也传进去。如果需要把temp body file放到指定目录,这时需要按照自己的方式把临时目录传进去,通过参数或者通过自定义的ngx_Module_ctx_t方式,这个随意。

ngx_http_read_webex_DMD_request_body方法首先判断是否存在body,如果不存在,立刻回调ngx_webex_DMD_handler_request_body方法;如果存在body,那么根据已经收到的buffer判断是否已经接收完body,如果已经收到完整的body,判断是否需要写入临时文件中,若需要则调用webex_DMD_ngx_http_write_request_body方法写临时文件,然后回调ngx_webex_DMD_handler_request_body。则如果没有收完,调用webex_DMD_ngx_http_do_read_client_request_body方法。

webex_DMD_ngx_http_do_read_client_request_body方法里,首先查看无阻塞的socket上是否仍有buffer,有则读出,再次判断是否body完整,如果已经收到完整的body,判断是否需要写入临时文件中,若需要则调用webex_DMD_ngx_http_write_request_body方法写临时文件,然后回调ngx_webex_DMD_handler_request_body。如果不完整,注册EPOLLIN事件的回调函数为webex_DMD_ngx_http_read_client_request_body_handler,把控制权交回给nginx epoll,等待下一次的EPOLLIN事件。下次EPOLLIN事件到达时,调用webex_DMD_ngx_http_read_client_request_body_handler,然后该函数会继续调用webex_DMD_ngx_http_do_read_client_request_body读取buffer,重复上一个步骤,直到body完整。

为了大家方便理解,我再画一幅活动图吧。

分享到:
评论

相关推荐

    nginx module开发指南(中文版)

    ### Nginx Module 开发详解 #### 模块的角色与功能 Nginx 的模块扮演着不同的角色,这些角色共同确保了服务器能够高效且灵活地处理 HTTP 请求。 1. **Handlers** (处理器): 这些模块负责处理 HTTP 请求并构造响应...

    fastdfs-nginx-module-1.24

    《FastDFS-Nginx-Module 1.24:高效文件服务器集成详解》 FastDFS-nginx-module 1.24 是一个针对 FastDFS 文件系统的 Nginx 模块,它使得 Nginx 可以无缝地与 FastDFS 集成,提供了高效的文件上传、下载服务。这一...

    nginx-module-vts.tar.gz

    Nginx-Module-VTS是Nginx的一个增强模块,主要功能是提供详细的Web服务器访问统计和性能监控。Prometheus是一款流行的开源监控和警报工具,广泛用于收集和分析各种系统的指标。在本场景中,Nginx-Module-VTS与...

    fastdfs-nginx-module_v1.16.tar.gz源码包,nginx支

    4. **安装与配置**:首先,需要在服务器上安装FastDFS和Nginx,然后编译并安装FastDFS-nginx-module。配置Nginx的配置文件,包括设置FastDFS的连接参数、URL重写规则等,以实现Nginx与FastDFS的交互。 5. **使用...

    lua-nginx-module-0.10.13

    Lua-Nginx-Module由OpenResty团队开发,旨在提供一种轻量级、高效且易于使用的机制,使开发者能够在Nginx内部处理复杂的业务逻辑,如动态内容生成、流量控制、API网关等功能,从而避免了传统的CGI或FastCGI等模型...

    fastdfs-nginx-module-正版V1.19-亲测可用 .zip

    《FastDFS-Nginx-Module V1.19:构建高效稳定的文件服务器系统》 FastDFS-Nginx-Module V1.19 是一个专为Nginx设计的FastDFS扩展模块,它允许Nginx直接与FastDFS进行交互,从而实现高效的文件上传和下载服务。...

    lua-nginx-module-master.zip

    总之,"lua-nginx-module-master.zip"包含的lua-nginx-module是将Lua语言的强大功能引入Nginx的关键,它为开发人员提供了一种灵活且高效的方式,以应对复杂的Web服务场景。正确理解和使用这个模块,可以显著提升...

    fastdfs-nginx-module-1.22.zip

    《FastDFS-Nginx-Module 1.22:构建高效Web服务器的融合解决方案》 在互联网服务领域,Nginx以其高效的性能和强大的反向代理能力被广泛应用于Web服务器,而FastDFS作为轻量级的分布式文件系统,能够有效地解决...

    headers-more-nginx-module-0.34

    《headers_more_nginx_module_0.34:深入解析Nginx扩展模块的增强功能》 在Web服务器领域,Nginx以其高性能、高并发能力而广受赞誉。而headers_more_nginx_module作为Nginx的一个扩展模块,进一步提升了其在处理...

    fastdfs-nginx-module-1.20.zip

    本文将详细解析如何将FastDFS的Nginx模块(fastdfs-nginx-module-1.20.zip)安装并配置到Nginx中,实现高效、稳定的服务。 首先,确保你已经安装了FastDFS和Nginx的基础环境。FastDFS提供了数据存储和文件管理的...

    fastdfs-nginx-module_master.zip

    4. 启动Nginx,测试文件上传和下载功能是否正常。 在使用过程中,需要注意的是,FastDFS的文件ID由Group、Volume和File ID三部分组成,Nginx在处理请求时会根据这些信息找到对应的文件。此外,为了保证系统的安全性...

    fastdfs-nginx-module1.20

    4. **权限控制**:FastDFS-Nginx-Module支持基于HTTP头的权限验证,可以通过Nginx的访问控制策略限制对文件的访问。 5. **性能优化**:V1.20版本可能包括了一些性能优化措施,如缓存机制、减少网络通信开销等,提升...

    redis2-nginx-module-0.15

    Redis2-NGINX-Module 是由 OpenResty 团队开发的,OpenResty 是一个基于 NGINX 的高性能 Web 和反向代理服务器,它包含了大量的 LuaJIT 脚本支持,能够进行动态编程。通过这个模块,开发者可以在 NGINX 配置中直接...

    echo-nginx-module-0.58.tar.gz

    而为了更好地优化和调试Nginx的配置,开发者们开发了一系列的模块,其中echo-nginx-module是其中之一。本文将详细解析echo-nginx-module的功能、使用场景以及如何配合Nginx进行调试。 一、echo-nginx-module概述 ...

    nginx-sticky-module-1.25.zip

    nginx sticky是nginx的module,可以实现基于cookie的负载均衡。 下载后,在编译安装nginx时,用--add-module选项,指到sticky所在目录。类似命令如下: ./configure --prefix=/usr/local/nginx-1.6.0 --add-module=...

    Nginx Module Extension

    通过上述分析,《Nginx Module Extension》这本书不仅深入介绍了Nginx的核心特性,还提供了详细的自定义模块开发指南。对于希望深入了解并充分利用Nginx强大功能的专业人士来说,这是一本非常有价值的参考资料。无论...

    nginx-module-vts-0.1.18.tar.gz

    解压之后安装如下:mv nginx-module-vts-0.1.18 /usr/local/ yum -y install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel cd /usr/local/nginx/nginx-1.13.7 ./configure --add-module=/...

    fastdfs-nginx-module.zip

    在这个场景下,`fastdfs-nginx-module.zip`扮演着关键的角色,它是FastDFS与Nginx之间的重要桥梁。 FastDFS通常与Nginx结合使用,Nginx作为一个强大的反向代理和负载均衡服务器,负责接收HTTP请求,然后将这些请求...

    echo-nginx-module-0.61.tar.gz

    echo-nginx-module是Nginx的一个扩展模块,由Philipp Kewisch(@agentzh)开发,它提供了一系列用于处理HTTP响应体的指令,极大地丰富了Nginx的输出处理能力。echo-nginx-module的主要目标是支持HTTP服务器内部的...

    lua-nginx-module-0.10.9rc7

    ngx_devel_kit(简称ndk)是一个用于开发Nginx模块的工具集,它提供了很多用于编写C语言扩展的便利函数。在0.10.9rc7这个版本中,可能需要特定的ndk版本才能确保所有功能正常运行。如果版本不匹配,可能会遇到如时间...

Global site tag (gtag.js) - Google Analytics