Nginx链接的定义:

作为 Web 服务器,每一个用户请求至少对应着一个 TCP 连接,为了及时处理这个连接,至少需要一个读事件和一个写事件,使得 epoll 可以有效地根据触发的事件调度相应模块读取请求或者发送响应。因此,Nginx 中定义了基本的数据结构 ngx connection t来表示连接,
这个连接表示是客户端主动发起的、Nginx 服务器被动接受的 TCP 连接,我们可以简单称其为被动连接。同时,在有些请求的处理过程中,Nginx 会试图主动向其他上游服务器建立连接,并以此连接与上游服务器通信,因此,这样的连接与 ngx_connection_t 又是不同的, Nginx 定义了ngx_peer_connection_t 结构体来表示主动连接,当然,ngx_peer_connection_t主动连接是以ngx connection t 结构体为基础实现的。下文将说明这两种连接中各字段的意义,同时需要注意的是,这两种连接都不可以随意创建,必须从连接池中获取。

1.被动连接:

我们常提到的未加修饰的"连接"都是指客户端发起的、服务器被动接受的连接,这样的连接都是使用 ngx_connection_t 结构体表示的,其定义如下。

struct ngx_connection_s {/*连接未使用时,data 成员用于充当连接池中空闲连接链表中的next指针。当连接被使用时,data的意义由使用它的Nginx模块而定,如在 HTTP 框架中,data指向ngx_http_request_t请求*/void               *data;//连接对应的读事件ngx_event_t        *read;//连接对应的写事件ngx_event_t        *write;//套接字句柄ngx_socket_t        fd;//直接接收网络字符流的方法ngx_recv_pt         recv;//直接发送网络字符流的方法ngx_send_pt         send;//以ngx_chain_t链表为参数来接收网络字符流的方法ngx_recv_chain_pt   recv_chain;//以ngx_chain_t链表为参数来发送网络字符流的方法ngx_send_chain_pt   send_chain;/*这个连接对应的ngx_listening_t 监听对象,此连接由listening 监听端口的事件建立*/ngx_listening_t    *listening;// 这个连接上已经发送出去的字节数off_t               sent;//可以记录日志的ngx_log_t对象ngx_log_t          *log;/*内存池。一般在accept一个新连接时,会创建一个内存池,而在这个连接结束时会销毁内存池。注意,这里所说的连接是指成功建立的TCP连接,所有的ngx_connection_t 结构体都是预分配的。这个内存池的大小将由上面的 listening监听对象中的 pool_size 成员决定*/ngx_pool_t         *pool;//连接客户端的sockaddr 结构体struct sockaddr    *sockaddr;//sockaddr结构体的长度socklen_t           socklen;//连接客户端字符串形式的IP地址ngx_str_t           addr_text;#if (NGX_SSL)ngx_ssl_connection_t  *ssl;
#endif/*本机的监听端口对应的gockaddr结构体,也就是listening监听对象中的sockaddr成员*/struct sockaddr    *local_sockaddr;/* 用于接收、缓存客户端发来的字符流,每个事件消费模块可自由决定从连接池中分配多大的空间给buffer这个接收缓存字段。例如,在HTTP模块中,它的大小决定于client header buffer size 配置项*/ngx_buf_t          *buffer;/*该字段用来将当前连接以双向链表元素的形式添加到ngx_cycle_t 核心结构体的reusable_connections_queue 双向链表中,表示可以重用的连接*/ngx_queue_t         queue;/*连接使用次数。ngx_connection_t结构体每次建立一条来自客户端的连接,或者用于主动向后端服务器发起连接时(ngx_peer_connection_t也使用它),number 都会加 1*/ngx_atomic_uint_t   number;//处理的请求次数ngx_uint_t          requests;/*缓存中的业务类型。任何事件消费模块都可以自定义需要的标志位。这个 buffered字段有8 位,最多可以同时表示8 个不同的业务。第三方模块在自定义buffered标志位时注意不要与可能使用的模块定义的标志位冲突。目前 openssl模块定义了一个标志位∶#define NGX SSL BUFFERED HTTP  0x01官方模块定义了以下标志位;#define NGX_HTTP_LOWLEVEL_BUFFERED 0xf0#define NGX_HTTP_WRITE_BUFFERED    0x10#define NGX_HTTP_GZIP_BUFFERED     0x20#define NGX_HTTP_SSI_BUFFERED      0x01#define NGX_HTTP_SUB BUFFERED      0x02#define NGX_HTTP_COPY BUFFERED     0x04#define NGX_HTTP_IMAGE BUFFERED    0x08同时,对于 HTTP 模块而言,buffered的低4位要慎用,在实际发送响应的 ngx_http_write_filter_module 过滤模块中,低4 位标志位为 1 则意味着 Nginx会一直认为有 HTTP 模块还需要处理这个请求,必须等待 HTTP 模块将低 4 位全置为0才会正常结束请求。检查低 4 位的宏如下;#define NGX_LOWLEVEL_BUFFERED 0x0f*/unsigned            buffered:8;/*本连接记录日志时的级别,它占用了3 位,取值范围是0~7,但实际上目前只定义了5个值,由ngx_ connection_log_error_e 枚举表示,如下∶typedef enum {NGX_ERROR_ALERT = 0,NGX_ERROR_ERR, NGX_ERROR_INFO,NGX_ERROR_IGNORE_ECONNRESET, NGX_ERROR_IGNORE_EINVAL}ngx_connection_log_error_e;*/unsigned            log_error:3;     /* ngx_connection_log_error_e *//*标志位,为 1 时表示独立的连接,如从客户端发起的连接;为0时表示依靠其他连接的行为而建立起来的非独立连接,如使用 upstream 机制向后端服务器建立起来的连接*/unsigned            single_connection:1;// 标志位,为1时表示不期待字符流结束,目前无意义unsigned            unexpected_eof:1;// 标志位,为1时表示连接已经超时unsigned            timedout:1;//标志位,为 1时表示连接处理过程中出现错误unsigned            error:1;/* 标志位,为 1时表示连接已经销级。这里的连接指是的 TCP连接,而不是nqx connection t 结构体。当destroved为1时,ngx_connection_t结构体仍然存在,但其对应的套接字、内存池等已经不可用*/unsigned            destroyed:1;/*标志位,为1时表示连接处于空闲状态,如keepalive 请求中两次请求之间的状态*/unsigned            idle:1;//标志位,为 1时表示连接可重用,它与上面的queue 字段是对应使用的unsigned            reusable:1;//标志位,为 1时表示连接关闭unsigned            close:1;//标志位,为1时表示正在将文件中的数据发往连接的另一端unsigned            sendfile:1;/* 标志位,如果为1,则表示只有在连接套接字对应的发送缓冲区必须满足最低设置的大小阈值时,事件驱动模块才会分发该事件。这与上文介绍过的ngx_handle_write_event 方法中的lowat 参数是对应的*/unsigned            sndlowat:1;/*标志位,表示如何使用TCP 的 nodelay特性。它的取值范围是下面这个枚举类型 ngx connectiontcp_nodelay_e: typedef enum{NGX_TCP_NODELAY_UNSET = 0, NGX_TCP_NODELAY_SET, NGX_TCP_NODELAY_DISABLED} ngx_connection_tcp_nodelay_e;*//*标志位,表示如何使用 TCP的nopush特性。它的取值范围是下面这个枚举类型 ngx_connection_tcp_nopugh_e:typedef enum {NGX TCP NOPUSH UNSET = 0, NGX_TCP_NOPUSH_SET, NGX_TCP_NOPUSH_DISABLED} ngx_connection_tcp_nopush_e;*/unsigned            tcp_nodelay:2;   /* ngx_connection_tcp_nodelay_e */unsigned            tcp_nopush:2;    /* ngx_connection_tcp_nopush_e */#if (NGX_HAVE_IOCP)unsigned            accept_context_updated:1;
#endif#if (NGX_HAVE_AIO_SENDFILE)//标志位,为 1时表示使用异步 工/O的方式将磁盘上文件发送给网络连接的另一端unsigned            aio_sendfile:1;//使用异步 I/O方式发送的文件,busy_sendfile缓冲区保存待发送文件的信息ngx_buf_t          *busy_sendfile;
#endif#if (NGX_THREADS)ngx_atomic_t        lock;
#endif
};
typedef ssize_t (*ngx_recv_pt)(ngx_connection_t *c,u_char *buf,size_t size);
typedef ssize_t (*ngx_recv_chain_pt)(ngx_connection_t *c,ngx_chain_t *in);
typedef ssize_t (*ngx_send_pt)(ngx_connection_t *c,u_char *buf,size_t size);
typedef ngx_chain_t *(*ngx_send_chain_pt)(ngx_connection_t *c,ngx chain t *in, off_t limit);

这 4个成员以方法指针的形式出现,说明每个连接都可以采用不同的接收方法,每个事件消费模块都可以灵活地决定其行为。不同的事件驱动机制需要使用的接收、发送方法多半是不一样的。

2.主动连接:

作为 Web 服务器,Nginx 也需要向其他服务器主动发起连接,当然,这样的连接与上面介绍的被动连接是不同的,它使用ngx_peer_connectiont结构体来表示主动连接。不过,一个待处理连接的许多特性在被动连接结构体 ngx_connection_t中都定义过了,因此,在 ngx_peer_connection_t结构体中引用了ngx_connection_t这个结构体,下面我们来看一下其定义。


struct ngx_peer_connection_s {/*一个主动连接实际上也需要 ngx_connection_t 结构体中的大部分成员,并且出于重用的考虑而定义了connection 成员*/ngx_connection_t                *connection;// 远端服务器的 socket 地址struct sockaddr                 *sockaddr;//sockaddr地址的长度socklen_t                        socklen;//远端服务器的名称ngx_str_t                       *name;/* 表示在连接一个远端服务器时,当前连接出现异常失败后可以重试的次数,也就是允许的最多失败次数*/ngx_uint_t                       tries;//获取连接的方法,如果使用长连接构成的连接池,那么必须要实现get 方法ngx_event_get_peer_pt            get;//与get 方法对应的释放连接的方法ngx_event_free_peer_pt           free;/*这个data指针仅用于和上面的get、free方法配合传递参数,它的具体含义与实现get 方法、free方法的模块相关,可参照 ngx_event_get_peer_pt和ngx_event_free_peer_pt 方法原型中的 data 参数*/void                            *data;#if (NGX_SSL)ngx_event_set_peer_session_pt    set_session;ngx_event_save_peer_session_pt   save_session;
#endif#if (NGX_THREADS)ngx_atomic_t                    *lock;
#endif//本机地址信息ngx_addr_t                      *local;//套接字的接收缓冲区大小int                              rcvbuf;// 记录日志的ngx_log_t对象ngx_log_t                       *log;// 标志位,为1时表示上面的connection连接已经缓存unsigned                         cached:1;/*与ngx_connection_t里的log_error意义是相同的,区别在于这里的log_error只有两位,只能表达 4 种错误,NGX_ERROR_IGNORE_EINVAL 错误无法表达*//* ngx_connection_log_error_e */unsigned                         log_error:2;
};

ngx_peer_connection_t也有一个ngx_connection t类型的成员,怎么理解这两个结构体之间的关系呢?所有的事件消费模块在每次使用 ngx_peer_connection_t对象时,一般都需要重新生成一个ngx_peer_connection_t结构体,然而,ngx_peer_connection_t对应的 ngx_connection t 连接一般还是从连接池中获取,因此,ngx_peer_connection_t只是对ngx_ connection t 结构体做了简单的包装而已。

深入理解Nginx——链接相关推荐

  1. 理解 Nginx HTTP 代理, 负载均衡, Buffering, Caching

    原文链接 开篇介绍 我们会在本文中深入探讨Nginx在HTTP通信方面的代理能力,所谓"代理"就是指Nginx在接收到request请求时将请求传递给后台多个http服务器进行进一 ...

  2. 《深入理解Nginx》阅读与实践(一):Nginx安装配置与HelloWorld

    最近在读陶辉的<深入理解Nginx:模块开发与架构解析>,一是想跟着大牛练练阅读和编写开源代码的能力,二是想学学Nginx优秀的架构设计,三是想找一个点深入下Linux下网络编程的细节.侯 ...

  3. 《深入理解Nginx》阅读与实践(四):简单的HTTP过滤模块

    一.Nginx的HTTP过滤模块特征 一个请求可以被任意个HTTP模块处理: 在普通HTTP模块处理请求完毕并调用ngx_http_send_header()发送HTTP头部或调用ngx_http_o ...

  4. 推荐我的新书《深入理解Nginx:模块开发与架构解析》

    http://www.china-pub.com/STATIC/zt_mb/zt_huodong_2013_3.asp?filename=2013_jsj_nginx_20130401 目录 < ...

  5. php与nginx链接,Nginx与PHP的交互

    FastCGI模块模块允许nginx同FastCGI协同工作,并且控制哪些参数将被安全传递. 一.CGI和FastCGI简介 1.什么是CGI CGI 是Web 服务器运行时外部程序的规范接口,按CG ...

  6. 《深入理解NGINX 模块开发与架构解析》之摘抄学习

    1.基于Nginx框架开发程序有5个优势: (1).Nginx将网络.磁盘及定时器等异步事件的驱动都做了非常好的封装,基于它开发将可以忽略这些事件处理的细节; (2).Nginx封装了许多平台无关的接 ...

  7. Nginx - 深入理解nginx的处理请求、进程关系和配置文件重载

    概述 Nginx的系统学习整理的第三篇博客,主要介绍nginx的应用场景和架构基础,以便更好的理解,再生产环境中进行性能调优. Nginx的三个主要应用场景 1.静态资源服务,通过本地文件系统提供服务 ...

  8. 深入理解linux文件系统( 理解inode与block,理解硬链接软链接,掌握恢复误删文件及其分析方法,掌握用户日志及其查询命令 )

    文章目录 深入理解linux文件系统 前言 inode与block详解 inode和bolck概述 1:数据(block)块: 2:元信息 : inode(索引节点) inodu的内容 Linux系统 ...

  9. 《深入理解Nginx:模块开发与架构解析》一3.3 如何将自己的HTTP模块编译进Nginx...

    3.3 如何将自己的HTTP模块编译进Nginx Nginx提供了一种简单的方式将第三方的模块编译到Nginx中.首先把源代码文件全部放到一个目录下,同时在该目录中编写一个文件用于通知Nginx如何编 ...

  10. nginx 配置文件详解 深入理解nginx配置文件

    #运行用户 user wenji; #启动进程,通常设置成和cpu的数量相等 worker_processes  8; #全局错误日志及PID文件 error_log  /var/log/nginx/ ...

最新文章

  1. c语言判断2 1000素数,2是不是素数(C语言判断一个数为素数)
  2. python3----智能检测编码的工具
  3. Excel vba引用工作表的三种写法
  4. 一种被忽视的构造和整数溢出重现
  5. python监控某个程序_9-30 python监控windows某个进程的变化(修正版)
  6. command对象和DataReader的学习
  7. 在ubuntu16.04安装hadoop集群时ssh不成功
  8. windows2003与文件共享有关的几个进程
  9. LeetCode6 Z字形变换
  10. 一个不明觉厉的貌似包含很多linux资料索引的网页
  11. 我的世界1.12.2java下载_我的世界1.12.2forge下载
  12. 坚果云+Markor+Typora实现多平台Markdown协同编辑
  13. 重磅!!毕业将近,论文免费查重工具任你选,非常值得收藏!
  14. jquery获取已选择和未选择的checkBox项以及清空所选项
  15. .net连接access数据库
  16. 利用计算机解决古代数学问题鸡兔同笼,古代鸡兔同笼数学题:利用现代数学思维来解决...
  17. Navicat 提示:Connection is being used
  18. 如何学习ansys electronics
  19. 【pymongo】连接认证 auth failed解决方法
  20. ►奇说总001期:《“中本聪”,你去哪儿了?》0928

热门文章

  1. 免费mysql_MySql 所有的版本都是免费的吗?
  2. java网上订餐系统开题报告_网上订餐系统的设计与实现
  3. C语言 库函数:qsort 详解
  4. c语言计算器小程序方案,C语言计算器小程序(源代码+实习报告).docx
  5. 为资产分类定义折旧范围_SAP使用权资产配置浅析
  6. CSDN积分赚取方法
  7. BPS数据包常见问题
  8. 嵌入式linux系统移植的四大步骤_嵌入式linux内核裁剪与移植步骤教程
  9. 《SQL入门经典》总结
  10. Intellij IDEA打开Java项目并启动