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

nginx module开发利器:subrequest

 
阅读更多

nginx是个高性能web server,很多时候我们会把它当成reverse proxy或者web server container使用,但有时我们也会开发它的第三方module,因为module才能完全使用nginx的全事件驱动、无阻塞调用机制,充分使用系统资源,达到SERVER最大处理吞吐量。


在开发nginx module时,我们最有可能遇到的一件事就是,在处理一个请求时,我们需要访问其他多个backend server网络资源,拉取到结果后分析整理成一个response,再发给用户。这个过程是无法使用nginx upstream机制的,因为upstream被设计为用来支持nginx reverse proxy功能,所以呢,upstream默认是把其他server的http response body全部返回给client。这与我们的要求不符,这个时候,我们可以考虑subrequest了,nginx http模块提供的这个功能能够帮我们搞定它。


先看看subrequest调用函数长什么样:

ngx_int_t
ngx_http_subrequest(ngx_http_request_t *r,
    ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
    ngx_http_post_subrequest_t *ps, ngx_uint_t flags)

挨个分析下参数吧。r是我们的module handler中,nginx调用时传给我们的请求,这时我们直接传给subrequest即可。uri和args是我们需要访问backend server的URL,而psr是subrequest函数执行完后返回给我们的新请求,即将要访问backend server的请求指针。ps指明了回调函数,就是说,如果这个请求执行完毕,接收到了backend server的响应后,就会回调这个函数。flags会指定这个子请求的一些特征。

看看ngx_http_post_subrequest的结构:

typedef struct {
    ngx_http_post_subrequest_pt       handler;
    void                             *data;
} ngx_http_post_subrequest_t;

这里的handler你可以指向一个函数,这个函数会在这个子请求结束以后被nginx调用,这时传给函数的request是子请求,不是原始的父请求哈。


而flag我们一般只会感兴趣下面这个NGX_HTTP_SUBREQUEST_IN_MEMORY,flag设为这个宏时,表示发起的子请求,访问的网络资源返回的响应将全部放在内存中,我们可以从upstream->buffer里取到响应内容。所以这里如果用了这个flag,一定要确保返回内容不可以很大,例如不能去下载一个大文件。


所以,当我们写nginx的module时,需要去拉取某个网络资源,就可以这么写:

    ngx_http_post_subrequest_t          *psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
		
    if (psr == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    psr->handler = ngx_http_my_post_subrequest;
    psr->data = ctx;
		ngx_flag_t flag = NGX_HTTP_SUBREQUEST_IN_MEMORY 
		ngx_str_t sub_location = ngx_string("/testlocation");
		ngx_str_t sub_args = ngx_string("para=1");;
    rc = ngx_http_subrequest(r, &sub_location, &url_args, &sr, psr, sr_flag);

这样,在这个subrequest执行完后,将会调用ngx_http_my_post_subrequest方法,再次注意,此时传给你的ngx_http_request_t上下文是子请求的,不是原始的父请求,所以,如果你需要在父请求的上下文中处理这个请求,可以在ngx_http_my_post_subrequest中找到父请求的handler,设置为一个处理函数即可。比如:

ngx_http_request_t          *pr = r->parent;
pr->write_event_handler = ngx_http_parent_handler;

这样,这个ngx_http_my_post_subrequest执行完毕后,nginx开始换醒父请求,这时ngx_http_parent_handler将会被调用。


最后我们要注意,一个请求中,我们只能调用一次subrequest,不能一次生成多个subrequest。我们可以在儿子请求中再创建孙子请求,一直下去都行,但是不能一次创建多个子请求。为什么呢?因为nginx本身的设计就是,每处理完一个事件后,将会检查有没有它对应的一个post事件(一对一),如果有则处理。上面的subrequest就是用这个流程的。如果一个请求中我们想同时生成多个子请求,就不能用subrequest了,我们必须自己创建nginx事件来处理了。

分享到:
评论

相关推荐

    编程知识+技术开发+Nginx技术深度解析:重要知识点、避坑经验与学习路径

    编程知识+技术开发+Nginx技术深度解析:重要知识点、避坑经验与学习路径;编程知识+技术开发+Nginx技术深度解析:重要知识点、避坑经验与学习路径;编程知识+技术开发+Nginx技术深度解析:重要知识点、避坑经验与...

    《Nginx模块开发指南:使用C++11和Boost程序库》罗剑锋 azw3

    Nginx 是由俄罗斯工程师Igor Sysoev 开发的一个高性能Web 服务器,运行效率远超传统的Apache、Tomcat,是世界第二大Web 服务器,被国内外诸多顶级互联网公司采用。 Nginx 的一个突出特点是其灵活优秀的模块化架构,...

    srcache-nginx-module, 基于透明subrequest的任意 Nginx 位置缓存布局.zip

    srcache-nginx-module, 基于透明subrequest的任意 Nginx 位置缓存布局 电子邮件名称ngx_srcache - 基于透明subrequest的任意 Nginx 位置缓存布局:这里 MODULE 没有与 Nginx 源一起分发。 我们将看到安装说明( 参见...

    Nginx 模块开发指南: 使用 C++11 和 Boost 程序库

    《Nginx 模块开发指南:使用 C++11 和 Boost 程序库》结构严谨、脉络清晰、论述精确、详略得当,值得广大软件开发工程师、系统运维工程师和编程爱好者拥有。

    nginx module开发指南(中文版)

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

    Nginx模块开发指南:使用C++11和Boost程序库.mobi

    Nginx[ 1] 是由 俄罗斯 工程师 Igor Sysoev 开发 的 一个 高性能 Web 服务器, 各方 面的 表现 均 远 超 传统 的 Apache, 已经 应用于 诸多 顶 级 互 联网 公司, 为 全世界 数以亿计 的 网 民 提供 着 出色 的 ...

    开源电子书:Nginx 开发手册文档.pdf

    2. 配置 Nginx:可以使用配置文件来配置 Nginx,包括设置服务器根目录、端口号、虚拟主机、负载均衡等。 3. PHP-FPM 安装配置:可以使用 PHP-FPM 作为 FastCGI server,提供 PHP支持。 Nginx 的一些常见问题和解决...

    Linux 下 Nginx的安装:(解压,进入目录里面执行,./configure –-> make -> sudo make install)

    ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module ``` 上述命令会启用SSL支持和状态监控模块。 5. **编译源码**: 使用`make`命令来编译源码: ```bash make...

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

    标题中的"fastdfs-nginx-module_v1.16.tar.gz"是一个开源项目,它是一个用于Nginx服务器的模块,旨在使Nginx能够与FastDFS文件存储系统无缝集成。FastDFS是一个轻量级的开源分布式文件系统,适用于互联网和企业内部...

    fastdfs-nginx-module-1.24

    1. 安装 FastDFS 和 Nginx:首先需要在服务器上安装 FastDFS 和 Nginx,确保它们能够正常运行。 2. 下载 FastDFS-nginx-module:获取最新的 1.24 版本源码包,并解压到指定目录。 3. 编译和安装模块:将模块编译进 ...

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

    4. 配置FastDFS和Nginx:配置FastDFS的连接参数,如tracker服务器地址,以及Nginx的服务器配置,如URL映射规则。 5. 启动和测试:启动Nginx服务,进行文件上传和下载的测试,确保一切正常。 在运维层面,FastDFS-...

    nginx-upload-module模块源码

    nginx-upload-module模块源码,用于nginx配置文件上传功能

    nginx-ingress-controller:0.30.0

    quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0

    lua-nginx-module-0.10.9rc7

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

    fastdfs-nginx-module-1.22.zip

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

    Nginx 问题 之 nginx: [emerg] unknown directive "echo" in /weblogic/nginx/conf/nginx.conf:43-附件资源

    Nginx 问题 之 nginx: [emerg] unknown directive "echo" in /weblogic/nginx/conf/nginx.conf:43-附件资源

    nginx-module-vts.tar.gz

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

    nginx-module-sts:Nginx流服务器流量状态模块

    而`nginx-module-sts`,全称为Nginx Stream Traffic Status Module,是专为Nginx流服务器设计的一个扩展模块,用于监控流服务器的实时流量状态,提供了丰富的统计信息,帮助管理员更好地理解和优化网络流量。...

    headers-more-nginx-module-0.34

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

    lua-nginx-module-0.10.13

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

Global site tag (gtag.js) - Google Analytics