Chinaunix首页 | 论坛 | 博客
  • 博客访问: 129351
  • 博文数量: 24
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 280
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-14 15:19
文章分类

全部博文(24)

文章存档

2014年(6)

2008年(3)

2007年(15)

我的朋友

分类: 架构设计与优化

2014-11-06 16:32:53

Nginx 主要数据结构解析


本篇主要分析nginx代码中用到的主要的数据结构。
Nginx对自用数据结构的定义非常规范,统一,考虑也很周全,非常好的适配了linux, windows两个主流的OS,同时也很好的规避了32/64位机器的风险。另一方面,nginx的数据结构定义风格非常新颖,统一,
看得出作者的C语言是大师级的水平,通过分析nginx的数据结构的定义,我们一定可以学习到很多东西。

基础数据结构


Nginx 大量使用了自定义的基础数据结构,其主要目的是对C语言中基础的数据结构类型进行二次封装,以达到统一风格,规避风险以及方便使用的问题,例如 :

 78 typedef intptr_t        ngx_int_t;
 79 typedef uintptr_t       ngx_uint_t;
 80 typedef intptr_t        ngx_flag_t;
nginx对于这列数据结构的定义主要是为了方便在32/64位机器之间的编译移植, 具体定义可参考 : /usr/include/stdint.h

 16 typedef struct {
 17     size_t      len;
 18     u_char     *data;                         
 19 } ngx_str_t;

nginx队char类型的重新封装主要是为了更方便的使用。

核心数据结构 : 通用型

ngx_log_t : typedef struct ngx_log_s         ngx_log_t;

其定义如下 :

 48 struct ngx_log_s {
 49     ngx_uint_t           log_level;            // log 等级
 50     ngx_open_file_t     *file;    // log打开的文件
 51
 52     ngx_atomic_uint_t    connection;
 53
 54     ngx_log_handler_pt   handler;    // log处理函数
 55     void                *data;    // 数据
 56
 57     /*
 58      * we declare "action" as "char *" because the actions are usually
 59      * the static strings and in the "u_char *" case we have to override
 60      * their types all the time
 61      */
 62
 63     char                *action;    // 泛型指针
 64
 65     ngx_log_t           *next;
 66 };
 67

ngx_pool_t : typedef struct ngx_pool_s        ngx_pool_t;

Nginx的pool数据结构,是nginx的核心数据结构之一,其目的是提供一个容器,以方便对内存,文件句柄等资源进行预分配,管理,回收等操作,其主要作用是队内存的管理。

 43 struct ngx_pool_large_s {
 44     ngx_pool_large_t     *next;
 45     void                 *alloc;
 46 };

 34 struct ngx_pool_cleanup_s {
 35     ngx_pool_cleanup_pt   handler;
 36     void                 *data;
 37     ngx_pool_cleanup_t   *next;
 38 };

 49 typedef struct {
 50     u_char               *last;  
 51     u_char               *end;   
 52     ngx_pool_t           *next;  
 53     ngx_uint_t            failed;
 54 } ngx_pool_data_t;

 57 struct ngx_pool_s {
 58     ngx_pool_data_t       d;     
 59     size_t                max;   
 60     ngx_pool_t           *current;
 61     ngx_chain_t          *chain;
 62     ngx_pool_large_t     *large;
 63     ngx_pool_cleanup_t   *cleanup;
 64     ngx_log_t            *log;
 65 };  

这个数据结构是一个管理数据结构,其中最终要的是‘d'成员。我们总是尾poll分配一定的内存空间大小(其必须大于pool本身的size),其中 d.last指向poll结构体本身占用空间之外的第一个字节,d.end只想整个分配空间的最后一个字节。Nginx定义了函数 : nginx_create_poll(size, log)来分配一个pool, 需要注意的是成员max,其意思是此pool中除去pool本身大小外剩余的内存空间大小。

Nginx定义了函数 : nginx_pnalloc(pool, size) 来从pool中分配内存。其核心思想是,检查pool中的剩余内存大小是否大于或等于size,如果是则从当前的pool直接分配,否则找到此pool链 表的下一个pool继续上一步骤。 需要注意的是pool是一个链表,依靠pool->d.next来进行组织。如果在当前pool的链中找不到合适的块,nginx会新分配一个 pool并将其链接到次pool的链表中来。需要注意的是,此pool的后继item(除链表头以外)只需要
ngx_pool_data_t 这个成员,其它部分都作为空闲内存空间使用。

large的分配是相似的,利用了pool中的large成员来管理,这里就不再详细描述了。

ngx_array_t :

 16 typedef struct {   
 17     void        *elts;
 18     ngx_uint_t   nelts;
 19     size_t       size;  
 20     ngx_uint_t   nalloc;
 21     ngx_pool_t  *pool;
 22 } ngx_array_t;

ngx_array_t 是另外一个nginx组织数据的核心数据结构。其主要用途是用来管理一个数组,包括数组内存空间分配以及管理操作功能。

ngx_array_init(array, pool, n, size), ngx_array_t必须从与其关联的pool中为数组分配内存, 数组大小为n * size,其中size是array所管理的数组中单个元素的大小n是元素的最大数目。poll是与array关联的pool的指针。实际所分配的内存空 间由elts指针管理。需要注意的是,array也有再分配功能,即当前array已满后,再次申请时需要对其内存大小进行调整,可能会有拷贝。

其管理函数主要有ngx_array_init, ngx_array_destroy, ngx_array_push, ngx_array_push_n等,这里就不再详细描述了。

ngx_array_t 主要用来管理 ngx_listening_t数据结构

ngx_list_t : 


18 struct ngx_list_part_s {
 19     void             *elts;
 20     ngx_uint_t        nelts;
 21     ngx_list_part_t  *next;   
 22 };

 25 typedef struct {              
 26     ngx_list_part_t  *last;   
 27     ngx_list_part_t   part;   
 28     size_t            size;   
 29     ngx_uint_t        nalloc;
 30     ngx_pool_t       *pool;   
 31 } ngx_list_t;

ngx_list_t 是nginx中另外一个常用的核心数据结构。其用法与定义与ngx_array_t相差无几,这里就不再详细描述了。
ngx_list_t主要用来管理ngx_open_file_t,ngx_shm_zone_t 等数据结构。

ngx_queue_t : typedef struct ngx_queue_s  ngx_queue_t

 18 struct ngx_queue_s {
 19     ngx_queue_t  *prev;       
 20     ngx_queue_t  *next;
 21 };  

ngx_queue_t 是一个简单的数据结构,但是用处比较广泛,主要用来管理reusable_connections_queue。


ngx_buf_t: typedef struct ngx_buf_s  ngx_buf_t

 20 struct ngx_buf_s {
 21     u_char          *pos;
 22     u_char          *last;
 23     off_t            file_pos;
 24     off_t            file_last;
 25
 26     u_char          *start;         /* start of buffer */
 27     u_char          *end;           /* end of buffer */
 28     ngx_buf_tag_t    tag;
 29     ngx_file_t      *file;
 30     ngx_buf_t       *shadow;
 31
 32
 33     /* the buf's content could be changed */
 34     unsigned         temporary:1;
 35
 36     /*   
 37      * the buf's content is in a memory cache or in a read only memory
 38      * and must not be changed
 39      */
 40     unsigned         memory:1;
 41
 42     /* the buf's content is mmap()ed and must not be changed */
 43     unsigned         mmap:1;
 44
 45     unsigned         recycled:1;
 46     unsigned         in_file:1;
 47     unsigned         flush:1;
 48     unsigned         sync:1;
 49     unsigned         last_buf:1;
 50     unsigned         last_in_chain:1;
 51
 52     unsigned         last_shadow:1;
 53     unsigned         temp_file:1;
 54
 55     /* STUB */ int   num;
 56 };

ngx_buf_t 是nginx 用来管理缓冲区的数据结构,基本上所有涉及到对缓冲区的操作,比如读,写,控制等,都需要用到这个结构。


核心数据结构 : 业务型

ngx_cycle_t : typedef struct ngx_cycle_s       ngx_cycle_t

此数据结构是nginx的主控数据结构,可以说是nginx全局运行的控制核心。

 37 struct ngx_cycle_s {
 38     void                  ****conf_ctx;
 39     ngx_pool_t               *pool;   // 相关联的pool
 40
 41     ngx_log_t                *log;      // 所使用的log
 42     ngx_log_t                 new_log;
 43
 44     ngx_uint_t                log_use_stderr;  /* unsigned  log_use_stderr:1; */
 45
 46     ngx_connection_t        **files;
 47     ngx_connection_t         *free_connections;
 48     ngx_uint_t                free_connection_n;
 49
 50     ngx_queue_t               reusable_connections_queue;
 51
 52     ngx_array_t               listening;
 53     ngx_array_t               paths;
 54     ngx_list_t                open_files;
 55     ngx_list_t                shared_memory;
 56
 57     ngx_uint_t                connection_n;
 58     ngx_uint_t                files_n;
 59
 60     ngx_connection_t         *connections;
 61     ngx_event_t              *read_events;
 62     ngx_event_t              *write_events;
 63
 64     ngx_cycle_t              *old_cycle;
 65
 66     ngx_str_t                 conf_file;
 67     ngx_str_t                 conf_param;
 68     ngx_str_t                 conf_prefix;
 69     ngx_str_t                 prefix;
 70     ngx_str_t                 lock_file;
 71     ngx_str_t                 hostname;
 72 };


ngx_module_t : typedef struct ngx_module_s      ngx_module_t

此数据结构是nginx的核心数据结构之一,定义了nginx的模块信息。
102 struct ngx_module_s {
103     ngx_uint_t            ctx_index;
104     ngx_uint_t            index;
105
106     ngx_uint_t            spare0;
107     ngx_uint_t            spare1;
108     ngx_uint_t            spare2;
109     ngx_uint_t            spare3;
110
111     ngx_uint_t            version;
112
113     void                 *ctx;
114     ngx_command_t        *commands;
115     ngx_uint_t            type;
116
117     ngx_int_t           (*init_master)(ngx_log_t *log);
118
119     ngx_int_t           (*init_module)(ngx_cycle_t *cycle);
120
121     ngx_int_t           (*init_process)(ngx_cycle_t *cycle);
122     ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);
123     void                (*exit_thread)(ngx_cycle_t *cycle);
124     void                (*exit_process)(ngx_cycle_t *cycle);
125
126     void                (*exit_master)(ngx_cycle_t *cycle);
127
128     uintptr_t             spare_hook0;
129     uintptr_t             spare_hook1;
130     uintptr_t             spare_hook2;
131     uintptr_t             spare_hook3;
132     uintptr_t             spare_hook4;
133     uintptr_t             spare_hook5;
134     uintptr_t             spare_hook6;
135     uintptr_t             spare_hook7;
136 };


ngx_conf_t : typedef struct ngx_conf_s        ngx_conf_t

157 struct ngx_conf_s {
158     char                 *name;
159     ngx_array_t          *args;
160
161     ngx_cycle_t          *cycle;
162     ngx_pool_t           *pool;
163     ngx_pool_t           *temp_pool;
164     ngx_conf_file_t      *conf_file;
165     ngx_log_t            *log;
166
167     void                 *ctx;
168     ngx_uint_t            module_type;
169     ngx_uint_t            cmd_type;
170
171     ngx_conf_handler_pt   handler;
172     char                 *handler_conf;
173 };

ngx_conf_t是nginx核心配置文件管理数据结构。



ngx_event_t : typedef struct ngx_event_s       ngx_event_t

38 struct ngx_event_s {
 39     void            *data;
 40
 41     unsigned         write:1;
 42
 43     unsigned         accept:1;
 44
 45     /* used to detect the stale events in kqueue, rtsig, and epoll */
 46     unsigned         instance:1;
 47
 48     /*
 49      * the event was passed or would be passed to a kernel;
 50      * in aio mode - operation was posted.
 51      */
 52     unsigned         active:1;
 53
 54     unsigned         disabled:1;
 55
 56     /* the ready event; in aio mode 0 means that no operation can be posted */
 57     unsigned         ready:1;
 58
 59     unsigned         oneshot:1;
 60
 61     /* aio operation is complete */
 62     unsigned         complete:1;
 63
 64     unsigned         eof:1;
 65     unsigned         error:1;
 66
 67     unsigned         timedout:1;
 68     unsigned         timer_set:1;
 69
 70     unsigned         delayed:1;
 71
 72     unsigned         deferred_accept:1;
 73
 74     /* the pending eof reported by kqueue, epoll or in aio chain operation */
 75     unsigned         pending_eof:1;
 76
 77 #if !(NGX_THREADS)
 78     unsigned         posted_ready:1;
 79 #endif
 80
 81 #if (NGX_WIN32)
 82     /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */
 83     unsigned         accept_context_updated:1;
 84 #endif
 85
 86 #if (NGX_HAVE_KQUEUE)
 87     unsigned         kq_vnode:1;
 88
 89     /* the pending errno reported by kqueue */
 90     int              kq_errno;
 91 #endif
 92
 93     /*
 94      * kqueue only:
 95      *   accept:     number of sockets that wait to be accepted
 96      *   read:       bytes to read when event is ready
 97      *               or lowat when event is set with NGX_LOWAT_EVENT flag
 98      *   write:      available space in buffer when event is ready
 99      *               or lowat when event is set with NGX_LOWAT_EVENT flag
100      *
101      * iocp: TODO
102      *
103      * otherwise:
104      *   accept:     1 if accept many, 0 otherwise
105      */
106
107 #if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
108     int              available;
109 #else
110     unsigned         available:1;
111 #endif
112
113     ngx_event_handler_pt  handler;
114
115
116 #if (NGX_HAVE_AIO)
117
118 #if (NGX_HAVE_IOCP)
119     ngx_event_ovlp_t ovlp;
120 #else
121     struct aiocb     aiocb;
122 #endif
123
124 #endif
125
126     ngx_uint_t       index;
127
128     ngx_log_t       *log;
129
130     ngx_rbtree_node_t   timer;
131
132     unsigned         closed:1;
133
134     /* to test on worker exit */
135     unsigned         channel:1;
136     unsigned         resolver:1;
137
138 #if (NGX_THREADS)
139
140     unsigned         locked:1;
141
142     unsigned         posted_ready:1;
143     unsigned         posted_timedout:1;
144     unsigned         posted_eof:1;
145
146 #if (NGX_HAVE_KQUEUE)
147     /* the pending errno reported by kqueue */
148     int              posted_errno;
149 #endif
150
151 #if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
152     int              posted_available;
153 #else
154     unsigned         posted_available:1;
155 #endif
156
157     ngx_atomic_t    *lock;
158     ngx_atomic_t    *own_lock;
159
160 #endif
161
162     /* the links of the posted queue */
163     ngx_event_t     *next;
164     ngx_event_t    **prev;
165
167 #if 0
168
169     /* the threads support */
170
171     /*
172      * the event thread context, we store it here
173      * if $(CC) does not understand __thread declaration
174      * and pthread_getspecific() is too costly
175      */
176
177     void            *thr_ctx;
178
179 #if (NGX_EVENT_T_PADDING)
180
181     /* event should not cross cache line in SMP */
182
183     uint32_t         padding[NGX_EVENT_T_PADDING];
184 #endif
185 #endif
186 };




ngx_connection_t : typedef struct ngx_connection_s  ngx_connection_t

118 struct ngx_connection_s {
119     void               *data;
120     ngx_event_t        *read;
121     ngx_event_t        *write;
122
123     ngx_socket_t        fd;
124
125     ngx_recv_pt         recv;
126     ngx_send_pt         send;
127     ngx_recv_chain_pt   recv_chain;
128     ngx_send_chain_pt   send_chain;
129
130     ngx_listening_t    *listening;
131
132     off_t               sent;
133
134     ngx_log_t          *log;
135
136     ngx_pool_t         *pool;
137
138     struct sockaddr    *sockaddr;
139     socklen_t           socklen;
140     ngx_str_t           addr_text;
141
142     ngx_str_t           proxy_protocol_addr;
143
144 #if (NGX_SSL)
145     ngx_ssl_connection_t  *ssl;
146 #endif
147
148     struct sockaddr    *local_sockaddr;
149     socklen_t           local_socklen;
150
151     ngx_buf_t          *buffer;
152
153     ngx_queue_t         queue;
154     
155     ngx_atomic_uint_t   number;
156
157     ngx_uint_t          requests;
158
159     unsigned            buffered:8;
160
161     unsigned            log_error:3;     /* ngx_connection_log_error_e */
162
163     unsigned            unexpected_eof:1;
164     unsigned            timedout:1;
165     unsigned            error:1;
166     unsigned            destroyed:1;
167
168     unsigned            idle:1;
169     unsigned            reusable:1;
170     unsigned            close:1;
171
172     unsigned            sendfile:1;
173     unsigned            sndlowat:1;
174     unsigned            tcp_nodelay:2;   /* ngx_connection_tcp_nodelay_e */
175     unsigned            tcp_nopush:2;    /* ngx_connection_tcp_nopush_e */
176
177     unsigned            need_last_buf:1;
178
179 #if (NGX_HAVE_IOCP)
180     unsigned            accept_context_updated:1;
181 #endif
182
183 #if (NGX_HAVE_AIO_SENDFILE)
184     unsigned            aio_sendfile:1;
185     unsigned            busy_count:2;
186     ngx_buf_t          *busy_sendfile;
187 #endif
188
189 #if (NGX_THREADS)
190     ngx_atomic_t        lock;
191 #endif
192 };


非核心数据结构

ngx_core_conf_t : nginx运行的全局配置,定义在配置文件中

 75 typedef struct {         
 76      ngx_flag_t               daemon;
 77      ngx_flag_t               master;
 78
 79      ngx_msec_t               timer_resolution;
 80
 81      ngx_int_t                worker_processes;
 82      ngx_int_t                debug_points;
 83
 84      ngx_int_t                rlimit_nofile;
 85      ngx_int_t                rlimit_sigpending;
 86      off_t                    rlimit_core;
 87
 88      int                      priority;
 89
 90      ngx_uint_t               cpu_affinity_n;
 91      uint64_t                *cpu_affinity;
 92
 93      char                    *username;
 94      ngx_uid_t                user;
 95      ngx_gid_t                group;
 96
 97      ngx_str_t                working_directory;
 98      ngx_str_t                lock_file;
 99
100      ngx_str_t                pid;
101      ngx_str_t                oldpid;
102
103      ngx_array_t              env;
104      char                   **environment;
105
106 #if (NGX_THREADS)
107      ngx_int_t                worker_threads;
108      size_t                   thread_stack_size;
109 #endif   
110
111 } ngx_core_conf_t;


Nginx用到的重要的全局变量(数据结构)

ngx_sys_errlist               :        用来储存全局的错误信息描述,主要是为了提高效率与便于管理
ngx_max_sockets          :        暂时位用
ngx_log                            :        全局的log变量
init_cycle                          :        全局的cycle变量,注意此变量只在初始化时候使用!
ngx_cycle                        :         全局cycle变量,是运行时的cycle
ngx_max_module           :        全局module个数变量
ngx_modules【】          :         nginx的模块定义列表,在nginx/objs/ngx_modules.c中定义,此全局数组定义了nginx默认的所有模块。

                                              




























阅读(741) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~