Nginx源码分析(1)

Nginx源码分析(1)

Nginx是一个高性能的静态HTTP服务器和反向代理服务器,Nginx本身不支持现在流行的 JSP、ASP、PHP等动态页面,但是它可以通过反向代理将请求发送到后端的服务器,例如 Tomcat、Apache等来完成动态页面的请求处理。

服务器的架构大同小异,而性能的差异主要来自对数据的处理方式上,也即进程模型和事件模型上。一个客户端请求的数据如何进行接收、存储、解析、返回是服务器做的最主要的工作。


##源码文件结构 源码位于src目录下,分为七个部分。


最基础的数据结构

C++之所以不被用来写网站是因为,网站的核心是处理字符串。而C++的字符串处理实在比较弱,还要不断惦记GC和内存泄漏。

而Nginx首先封装了一下字符串的数据结构和API。定义位于nginx/src/core/nginx_string.h中。

Nginx中一个字符串被表示为指针data指示首地址+len指示长度的方式,这种方式唯一定位一个字符串。和标准的glibc API\0的方式标识字符串结束不同,它有很多好处。

  • 通过长度表示字符串长度,减少计算字符串长度的步骤
  • 可以重复引用一段字符串内存,减少不必要的内存分配

这样的表示是不是似曾相识?在Redis的sds中有类似的处理。

再看看它的API,API以宏的方式定义。

第一个宏定义一个nginx的字符串,用法是

这里直接是宏展开,对结构体进行赋值。先生成了一个临时变量"stop",然后把临时变量的长度和地址赋值给结构体。ngx_stringngx_null_string{,}格式的,而结构体只能在初始化时进行整体赋值,因而API只能用于赋值时初始化。还需要注意str必须是常量字符串,因为sizeof是以\0为结束标志的。

打印结果


内存管理池ngx_pool_t

ngx_pool_t是一个资源管理池。它提供一种机制帮助管理一系列的资源(如内存、文件等),接管这些资源的所有权,负责资源的使用和释放。类似于C++中的shared_ptr智能指针。

ngx_pool_t定义在文件nginx/src/core/ngx_palloc.h中,相关的内存分配函数(如ngx_alloc)定义在nginx/src/os/unix/ngx_alloc.h中。

ngx_pool_data_t指示资源池数据块的位置信息。

size_t是数据块的最大值

整个内存管理如图所示:

再看一下相关的API函数。

  • ngx_alloc使用malloc进行内存分配,同时把错误信息写到log文件。
  • ngx_create_pool使用posix_memalign()申请大小为NGX_POOL_ALIGNMENT字节对其的内存。

p->d.last位移ngx_pool_t大小指向数据区段未使用部分的开始。

p->d.last指向数据区段未使用部分的结束。

可见分配的size大小的内存一部分要分给ngx_pool_t结构。

p->max表示分配的最大内存为NGX_MAX_ALLOC_FROM_POOL

最大限制为一个分页大小,在x86上其返回值应为4096Bytes = 4KB。

0

发表评论

邮箱地址不会被公开。