基础设施

更新于2018.08.08

日志

ngx_log_t支持stderr, 文件, syslog, 内存输出方式. 多个日志实例可组成链, 这样消息将写到链上的每一个日志实例中.

代码: src/core/ngx_log.h

内存管理

堆内存

堆内存有以下4个API:

ngx_alloc(size, log) //malloc的封装, 但会把错误信息和调试信息输出到log
ngx_calloc(size, log)
ngx_memalign(alignment, size, log)
ngx_free(p)

代码: src/core/ngx_palloc.h

内存池

nginx中大部分内存是从内存池(ngx_pool_t)获取的, 这样可以提升分配性能, 降低内存管理难度.

A pool internally allocates objects in continuous blocks of memory. Once a block is full, a new one is allocated and added to the pool memory block list. When the requested allocation is too large to fit into a block, the request is forwarded to the system allocator and the returned pointer is stored in the pool for further deallocation.

主要接口:

ngx_create_pool(size, log)
ngx_destroy_pool(pool)
ngx_palloc(pool, size)
ngx_pcalloc(pool, size)
ngx_pnalloc(pool, size)
ngx_pfree(pool, p)

// TODO

代码: src/core/ngx_palloc.h

共享内存

nginx共享内存用于在进程间共享数据, 基本数据结构是ngx_shm_zone_t.

// TODO

代码: src/core/ngx_cycle.h, src/core/ngx_slab.h

buffer

buffer用于给输入/输出操作提供缓冲区. buffer即可以引用内存中的数据, 也可以引用文件中的数据, 同时引用这两者也是可能的. buffer中的内存是单独分配的, 与buffer无关.

对于输入/输出操作, buffer构成链式结构(chain)

代码: src/core/ngx_buf.h

cycle

cycle对象存储与特定配置对应的nginx运行时上下文. 当配置更新时, 会创建新的cycle.

// TODO

代码: src/core/ngx_cycle.h

字符串操作

字符串

nginx使用带长度的字符串:

typedef struct {
    size_t      len;
    u_char     *data;
} ngx_str_t;

其中data可能以0结束, 也可能不是, 在大多数情况下不是, 但在特殊场景下, 比如解析配置文件时, 是以0结束的.

nginx针对ngx_str_t提供了自己的字符串函数, 比如ngx_strcmp(), ngx_memcpy(), ngx_memzero()等.

代码: src/core/ngx_string.h

格式化

nginx提供以下字符串格式化函数:

ngx_sprintf(buf, fmt, ...)
ngx_snprintf(buf, max, fmt, ...)
ngx_slprintf(buf, last, fmt, ...)
ngx_vslprintf(buf, last, fmt, args)
ngx_vsnprintf(buf, max, fmt, args)

另外提供了格式化字符串, 其中一部分是:

%O — off_t
%T — time_t
%z — ssize_t
%i — ngx_int_t
%p — void *
%V — ngx_str_t *
%s — u_char * (null-terminated)
%*s — size_t + u_char *

数值转换

nginx提供了一些接口, 可以把字符串转换为数值:

ngx_atoi(line, n) — ngx_int_t
ngx_atosz(line, n) — ssize_t
ngx_atoof(line, n) — off_t
ngx_atotm(line, n) — time_t
ngx_atofp(line, n, point)
ngx_hextoi(line, n)

正则表达式

nginx里的正则接口是对PCRE的封装.

代码: src/core/ngx_regex.h

容器

数组

此数组是可以动态增长的, 但空间不足以容纳新元素时, 将会扩展为原来的2倍大小.

// TODO

代码: src/core/ngx_array.h

链表

ngx_list_t是一个数组序列, 为插入大量元素进行了优化. 链表主要用于HTTP输入和输出首部. 此链表不支持节点删除, 但可以标记为missing, 这样迭代等操作就会忽略此节点.

// TODO

代码: src/core/ngx_list.h

队列

ngx_queue_t实现为侵入式的双向链表(其他侵入式数据结构比如Linux中的经典链表实现, 需要在调用者的数据结构里显式加上数据成员, 而不像C++标准库中的容器那样).

// TODO

代码: src/core/ngx_queue.h

红黑树

代码: src/core/ngx_rbtree.h

Heap4四叉树

// TODO

哈希

支持 通配符匹配 .

// TODO

代码: src/core/ngx_hash.h

时间

To obtain the current time, it is usually sufficient to access one of the available global variables, representing the cached time value in the desired format.

代码: src/core/ngx_times.h

网络

连接

ngx_connection_t是对socket描述符的封装.

nginx connection可以透明地封装SSL层, 在此情况下, ssl成员保存一个ngx_ssl_connection_t 的指针, 且recv/send/recv_chain/send_chain的handler被设为启用了SSL的函数.

配置文件中的worker_connections限制了每个worker的连接数, 而且所有connections是预先分配好的, 放在连接池中. 可以通过ngx_reusable_connection(c, reusable)来设置连接是否可以重用.

代码: src/core/ngx_connection.h

事件

  • 事件
  • I/O事件
  • 计时器事件
  • Posted events
  • 事件循环

进程

XXX

线程

XXX

模块

XXX

错误处理