真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

nginx啟動(dòng)初始化代碼執(zhí)行流程是什么

這篇文章主要介紹“nginx啟動(dòng)初始化代碼執(zhí)行流程是什么”,在日常操作中,相信很多人在nginx啟動(dòng)初始化代碼執(zhí)行流程是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對(duì)大家解答”nginx啟動(dòng)初始化代碼執(zhí)行流程是什么”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

創(chuàng)新互聯(lián)公司專注于大安網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供大安營銷型網(wǎng)站建設(shè),大安網(wǎng)站制作、大安網(wǎng)頁設(shè)計(jì)、大安網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務(wù),打造大安網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供大安網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

代碼執(zhí)行流程

ngx_event_process_init:遍歷connections,初始化listenfd的回調(diào)函數(shù),添加事件監(jiān)聽

static ngx_int_t

ngx_event_process_init(ngx_cycle_t *cycle)

{

...

cycle->connections =

ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);

cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,

cycle->log);

...

ls = cycle->listening.elts;

for (i = 0; i < cycle->listening.nelts; i++) {

c = ngx_get_connection(ls[i].fd, cycle->log);

c->listening = &ls[i];

rev = c->read;

}

...

rev->handler = ngx_event_accept;

ngx_add_event(rev, NGX_READ_EVENT, 0)

...

}

ngx_event_accept:調(diào)用ngx_listening_t的回調(diào)函數(shù)

void

ngx_event_accept(ngx_event_t *ev)

{

...

lc = ev->data;

ls = lc->listening;

...

s = accept(lc->fd, (struct sockaddr *) sa, &socklen);

c = ngx_get_connection(s, ev->log);

ngx_add_conn(c)

ls->handler(c);

...

}

找到ls->handler(c)的位置

static char *

ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

...

if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) {

return NGX_CONF_ERROR;

}

...

}

static ngx_int_t

ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,

ngx_array_t *ports)

{

...

if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {

return NGX_ERROR;

}

...

}

static ngx_int_t

ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port)

{

...

ls = ngx_http_add_listening(cf, &addr[i]);

if (ls == NULL) {

return NGX_ERROR;

}

...

}

static ngx_listening_t *

ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)

{

...

ls->handler = ngx_http_init_connection;

...

}

第三方模塊(輸出):

server {

listen 0.0.0.0:70;

location / {

root /usr/local/nginx/html/bak/;

limit_req zone=req10k burst=5 nodelay;

shuchu "helloworld";

}  

}

一個(gè)模塊的三大核心

static ngx_command_t ngx_http_shuchu_commands[] = {

{  

ngx_string("shuchu"),

NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,

ngx_http_shuchu,

NGX_HTTP_LOC_CONF_OFFSET,

offsetof(ngx_http_shuchu_loc_conf_t, content),

NULL,

}, 

ngx_null_command,

};

static ngx_http_module_t  ngx_http_shuchu_ctx = {

NULL,

ngx_http_shuchu_init,

NULL,

NULL,

NULL,

NULL,

ngx_http_shuchu_create_loc_conf,

ngx_http_shuchu_merge_loc_conf

};

ngx_module_t ngx_http_shuchu_module = {

NGX_MODULE_V1,

&ngx_http_shuchu_ctx,        /* module context */

ngx_http_shuchu_commands,    /* module directives */

NGX_HTTP_MODULE,                     /* module type */

NULL,                                /* init master */

NULL,                                /* init module */

NULL,                                /* init process */

NULL,                                /* init thread */

NULL,                                /* exit thread */

NULL,                                /* exit process */

NULL,                                /* exit master */

NGX_MODULE_V1_PADDING

};

ngx_conf_parse:解析配置

char *

ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)

{

...

type = parse_file;

fd = ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);

rc = ngx_conf_read_token(cf);

省略對(duì)rc和type組合的判定

rc = ngx_conf_handler(cf, rc);

...

}

ngx_conf_handler:對(duì)指令進(jìn)行處理

static ngx_int_t

ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)

{

...

for (i = 0; ngx_modules[i]; i++) {

cmd = ngx_modules[i]->commands;

for ( /* void */ ; cmd->name.len; cmd++) {

if (cmd->type & NGX_DIRECT_CONF) {

conf = ((void **) cf->ctx)[ngx_modules[i]->index];

} else if (cmd->type & NGX_MAIN_CONF) {

conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);

} else if (cf->ctx) {

confp = *(void **) ((char *) cf->ctx + cmd->conf);

if (confp) {

conf = confp[ngx_modules[i]->ctx_index];

}

}

rv = cmd->set(cf, cmd, conf);

}

}

...

}

ngx_http_block

static char *

ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

...

ctx->main_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

for (m = 0; ngx_modules[m]; m++) {

if (ngx_modules[m]->type != NGX_HTTP_MODULE) {

continue;

}

module = ngx_modules[m]->ctx;

mi = ngx_modules[m]->ctx_index;

if (module->create_main_conf) {

ctx->main_conf[mi] = module->create_main_conf(cf);

if (ctx->main_conf[mi] == NULL) {

return NGX_CONF_ERROR;

}

}

if (module->create_srv_conf) {

ctx->srv_conf[mi] = module->create_srv_conf(cf);

if (ctx->srv_conf[mi] == NULL) {

return NGX_CONF_ERROR;

}

}

if (module->create_loc_conf) {

ctx->loc_conf[mi] = module->create_loc_conf(cf);

if (ctx->loc_conf[mi] == NULL) {

return NGX_CONF_ERROR;

}

}

}

pcf = *cf;

cf->ctx = ctx;

...

/* parse inside the http{} block */

cf->module_type = NGX_HTTP_MODULE;

cf->cmd_type = NGX_HTTP_MAIN_CONF;

rv = ngx_conf_parse(cf, NULL);

...

}

ngx_http_core_server

static char *

ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)

{

...

ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));

if (ctx == NULL) {

return NGX_CONF_ERROR;

}

http_ctx = cf->ctx;

ctx->main_conf = http_ctx->main_conf;

ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

...

cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];

cscf->ctx = ctx;

cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];

cscfp = ngx_array_push(&cmcf->servers);

if (cscfp == NULL) {

return NGX_CONF_ERROR;

}

*cscfp = cscf;

/* parse inside server{} */

pcf = *cf;

cf->ctx = ctx;

cf->cmd_type = NGX_HTTP_SRV_CONF;

rv = ngx_conf_parse(cf, NULL);

...

}

ngx_http_core_listen

static char *

ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

...

cscf->listen = 1;

value = cf->args->elts;

ngx_memzero(&u, sizeof(ngx_url_t));

u.url = value[1];

ngx_parse_url(cf->pool, &u);

if (ngx_http_add_listen(cf, cscf, &lsopt) == NGX_OK) {

return NGX_CONF_OK;

}

...

}

ngx_http_add_listen

ngx_int_t

ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,

ngx_http_listen_opt_t *lsopt)

{

...

cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

if (cmcf->ports == NULL) {

cmcf->ports = ngx_array_create(cf->temp_pool, 2,

sizeof(ngx_http_conf_port_t));

if (cmcf->ports == NULL) {

return NGX_ERROR;

}

}

sin = &lsopt->u.sockaddr_in;

p = sin->sin_port;

port = ngx_array_push(cmcf->ports);

port->family = sa->sa_family;

port->port = p;

port->addrs.elts = NULL;

ngx_http_add_address(cf, cscf, port, lsopt);

...

}

ngx_http_add_address

static ngx_int_t

ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,

ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt)

{

...

addr = ngx_array_push(&port->addrs);

addr->opt = *lsopt;

addr->default_server = cscf;

...}

ngx_http_add_server

static ngx_int_t

ngx_http_add_server(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,

ngx_http_conf_addr_t *addr)

{

...

server = ngx_array_push(&addr->servers);

*server = cscf;

...

}

到這里為止,整個(gè)配置的基本架構(gòu)已經(jīng)搞起來了,port(ngx_http_conf_port_t)下掛著多個(gè)監(jiān)聽的地址(ngx_http_conf_addr_t),每個(gè)地址后的opt目前都是配置里面讀出來,存著監(jiān)聽器的信息,監(jiān)聽地址(ngx_http_conf_addr_t)后面還掛著這個(gè)監(jiān)聽地址所存在的server塊(ngx_http_core_srv_conf_t),接下來就要最后在optmize一下,把opt里的東西搞一下,然后做hash:

ngx_http_optimize_servers

static ngx_int_t

ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,

ngx_array_t *ports)

{

...

port = ports->elts;

for (p = 0; p < ports->nelts; p++) {

addr = port[p].addrs.elts;

for (a = 0; a < port[p].addrs.nelts; a++) {

if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {

return NGX_ERROR;

}

}

if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {

return NGX_ERROR;

}

}

...

}

ngx_http_server_names:整理addr中的servers,將sn和對(duì)應(yīng)的srv_conf對(duì)應(yīng)起來

static ngx_int_t

ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,

ngx_array_t *ports)

{

...

ha.pool = cf->pool;

cscfp = addr->servers.elts;

for (s = 0; s < addr->servers.nelts; s++) {

name = cscfp[s]->server_names.elts;

for (n = 0; n < cscfp[s]->server_names.nelts; n++) {

rc = ngx_hash_add_key(&ha, &name[n].name, name[n].server,

NGX_HASH_WILDCARD_KEY);  

}

...

hash.hash = &addr->hash;

ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts);

}

...

}

ngx_http_add_listening

static ngx_listening_t *

ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)

{

...

ls = ngx_create_listening(cf, &addr->opt.u.sockaddr, addr->opt.socklen);

ls->handler = ngx_http_init_connection;

...

}

instance

每次get_connection都會(huì)將instance取反,s是accept獲取的socket,是一個(gè)int,賦值給c->fd

ngx_connection_t *

ngx_get_connection(ngx_socket_t s, ngx_log_t *log)

{

...

c = ngx_cycle->free_connections;

ngx_cycle->free_connections = c->data;

ngx_cycle->free_connection_n--;

rev = c->read;

wev = c->write;

ngx_memzero(c, sizeof(ngx_connection_t));

c->read = rev;

c->write = wev;

c->fd = s;

rev->instance = !instance;

wev->instance = !instance;

rev->data = c;

wev->data = c;

return c;

...

}

而free的時(shí)候只移動(dòng)鏈表,清空文件,將當(dāng)前鏈表變成可用

void

ngx_free_connection(ngx_connection_t *c)

{

...

c->data = ngx_cycle->free_connections;

ngx_cycle->free_connections = c;

ngx_cycle->free_connection_n++;

if (ngx_cycle->files) {

ngx_cycle->files[c->fd] = NULL;

...

}

而無論是add_event還是add_connection,都是直接將epoll指向的直接與instance,在process_events的時(shí)候,拿出來事件指向的

static ngx_int_t

ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)

{

...

ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);

...

}

static ngx_int_t

ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)

{

...

c = event_list[i].data.ptr;

instance = (uintptr_t) c & 1;

if (c->fd == -1 || rev->instance != instance) {

...

}

到此,關(guān)于“nginx啟動(dòng)初始化代碼執(zhí)行流程是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!


網(wǎng)頁標(biāo)題:nginx啟動(dòng)初始化代碼執(zhí)行流程是什么
網(wǎng)站地址:http://weahome.cn/article/jcogcp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部