微信公众号:郑尔多斯
关注可了解更多的Nginx知识。任何问题或建议,请公众号留言;
关注公众号,有趣有内涵的文章第一时间送达!

listen端口优化

本篇文章主要是分析配置文件解析完毕之后对listen的进一步优化。这一部分主要完成了端口的初始化以及打开操作。

代码分析

ngx_http_block()中有下面的一部分代码,如下:

1 /* optimize the lists of ports, addresses and server names */23if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) {4    return NGX_CONF_ERROR;5}复制代码

从上面的代码注释中可以看出来,ngx_http_optimize_servers()函数的作用就是对我们监听的端口,address以及server name进行优化处理的,下面我们结合自己的例子分析一下这个方法。
先把我们解析完http指令之后的内存结构图放出来:

解析http之后的内存图

ngx_http_optimize_servers

先看一下源码,如下:

 1static ngx_int_t 2ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,  ngx_array_t *ports) 3{ 4    ngx_uint_t             p, a; 5    ngx_http_conf_port_t  *port; 6    ngx_http_conf_addr_t  *addr; 7 8    if (ports == NULL) { 9        return NGX_OK;10    }1112    port = ports->elts;13//遍历所有的ports数组14    for (p = 0; p < ports->nelts; p++) {15// 对每个port下的所有addr进行排序16        ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,17            sizeof(ngx_http_conf_addr_t), ngx_http_cmp_conf_addrs);1819        /*20         * check whether all name-based servers have the same21         * configuration as a default server for given address:port22         */2324        addr = port[p].addrs.elts;25        for (a = 0; a < port[p].addrs.nelts; a++) {2627            if (addr[a].servers.nelts > 128#if (NGX_PCRE)29                || addr[a].default_server->captures30#endif31               )32            {33                if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {34                    return NGX_ERROR;35                }36            }37        }3839        if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {40            return NGX_ERROR;41        }42    }4344    return NGX_OK;45}复制代码

对addr进行排序

从上面的代码中可以看到,nginx会遍历所有的port,然后对每个遍历到的port调用ngx_sort()进行排序,使用的排序函数为ngx_http_cmp_conf_addrs(),该函数如下:

 1ngx_http_cmp_conf_addrs(const void *one, const void *two) 2{ 3    ngx_http_conf_addr_t  *first, *second; 4 5    first = (ngx_http_conf_addr_t *) one; 6    second = (ngx_http_conf_addr_t *) two; 7 8    if (first->opt.wildcard) { 9        /* a wildcard address must be the last resort, shift it to the end */10        return 1;11    }1213    if (second->opt.wildcard) {14        /* a wildcard address must be the last resort, shift it to the end */15        return -1;16    }1718    if (first->opt.bind && !second->opt.bind) {19        /* shift explicit bind()ed addresses to the start */20        return -1;21    }2223    if (!first->opt.bind && second->opt.bind) {24        /* shift explicit bind()ed addresses to the start */25        return 1;26    }2728    /* do not sort by default */2930    return 0;31}复制代码

从代码中可以看到排序规则:

  • 如果first addr是wildcard,那么这个addr排在后面second的后面,这一句就说明wildcard 属性要排在所有的地址的后面。
  • 如果first addr不是wildcard,但是second 是wildcard,那么first排在second的前面,也就是说wildcard类型的要排在 非wildcard后面
  • 如果 first和second 都不是wildcard,但是first有bind属性,而second没有bind属性,那么first排在second的前面,这个规则说明bind属性要排在非bind的前面。
  • 如果first和second都不是wildcard,但是first没有bind属性,而second有bind属性,那么frist排在second的后面,也是为了说明bind要排在前面。
  • 其他情况的排序规则不变
排序之后的样式

上图是排序之后的样式,不过由于我们只有一个addr,所以这里并没有这么麻烦。

ngx_http_init_listening

我们真正要关心的是这个函数,它对我么监听的端口进行了处理:

 1static ngx_int_t 2ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port) 3{ 4    ngx_uint_t                 i, last, bind_wildcard; 5    ngx_listening_t           *ls; 6    ngx_http_port_t           *hport; 7    ngx_http_conf_addr_t      *addr; 8 9    addr = port->addrs.elts;10// 在本例子中last = 111    last = port->addrs.nelts;1213    /*14     * If there is a binding to an "*:port" then we need to bind() to15     * the "*:port" only and ignore other implicit bindings.  The bindings16     * have been already sorted: explicit bindings are on the start, then17     * implicit bindings go, and wildcard binding is in the end.18     */1920    if (addr[last - 1].opt.wildcard) {21        addr[last - 1].opt.bind = 1;22        bind_wildcard = 1;2324    } else {25        bind_wildcard = 0;26    }2728    i = 0;2930    while (i < last) {3132        if (bind_wildcard && !addr[i].opt.bind) {33            i++;34            continue;35        }3637        ls = ngx_http_add_listening(cf, &addr[i]);38        if (ls == NULL) {39            return NGX_ERROR;40        }4142        hport = ngx_pcalloc(cf->pool, sizeof(ngx_http_port_t));43        if (hport == NULL) {44            return NGX_ERROR;45        }4647        ls->servers = hport;4849        hport->naddrs = i + 1;5051        switch (ls->sockaddr->sa_family) {5253#if (NGX_HAVE_INET6)54        case AF_INET6:55            if (ngx_http_add_addrs6(cf, hport, addr) != NGX_OK) {56                return NGX_ERROR;57            }58            break;59#endif60        default: /* AF_INET */61            if (ngx_http_add_addrs(cf, hport, addr) != NGX_OK) {62                return NGX_ERROR;63            }64            break;65        }6667        if (ngx_clone_listening(cf, ls) != NGX_OK) {68            return NGX_ERROR;69        }7071        addr++;72        last--;73    }7475    return NGX_OK;76}复制代码

预知后事如何,且听下文分解


喜欢本文的朋友们,欢迎长按下图关注订阅号郑尔多斯,更多精彩内容第一时间送达

郑尔多斯

nginx对listen端口的优化 -- 第一篇相关推荐

  1. black-box优化——第一篇:基础BBO算法

    本篇博客先介绍一些 naive 的方法来解决 BBO 问题,这样可以让大家了解到为什么DFO在实际中,如此受到欢迎. 两个缩写: derivative free optimization (DFO) ...

  2. SQL性能优化第一篇之分页数据与Count数据一次性获取

    相信大部分人都会遇到:在数据库的数据量很大时,分页需要几秒钟才会全部完成:包括分页list的获取和count的获取.那我们完全可以将这两步放到一次sql去执行获取,减少一半的查询时间.这里get到sq ...

  3. 性能优化系列第一篇——数据库性能优化

    本文章转载的Trinea大神的文章,文章原地址 http://www.trinea.cn/android/database-performance/ 性能优化之数据库优化 本文为性能优化的第一篇--数 ...

  4. 《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一第一篇 执行计划

    第一篇 执行计划 执行计划是指示Oracle如何获取和过滤数据.产生最终结果集,是影响SQL语句执行性能的关键因素.我们在深入了解执行计划之前,首先需要知道执行计划是在什么时候产生的,以及如何让SQL ...

  5. 天兔安装手册-第一篇文章

    文章的第一篇 一 LNMP安装 0 基础包安装 yum -y install openssl openssl-devel yum install libmcrypt-devel wget http:/ ...

  6. 聊聊后端程序员的知识体系-第一篇

    聊聊后端程序员的知识体系-第一篇 原文链接:https://www.fpthinker.com/backend_knowledge_architecture/knowledge.htmll 亲爱的读者 ...

  7. HTTP第一篇——搭建

    HTTP搭建第一篇 1.搭建web,部署能访问的网页 2.实现80和8080等多端口的访问 3.实现多端口访问的内容不同 一.搭建web,部署能访问的网页 ①装包 # yum  -y  install ...

  8. mac下安装JAVA开发工具(6)------tomcat、IDEA及nginx转发80端口到8080

    IDEA Tomcat 及Nginx的协作开发 在mac下开发java 少不了使用tomcat macos系统下的80端口是root权限才能使用 因此使用IDEA启动tomcat80端口时总会出现问题 ...

  9. 深入理解ajax系列第一篇——XHR对象

    前面的话 1999年,微软公司发布IE5,第一次引入新功能:允许javascript脚本向服务器发起HTTP请求.这个功能当时并没有引起注意,直到2004年Gmail发布和2005年Google Ma ...

最新文章

  1. ROW_NUMBER() OVER()函数用法;(分组,排序),partition by
  2. Qt5: SpringAnimation
  3. python编码规范手册-python编码规范
  4. mybatis深入理解(一)之 # 与 $ 区别以及 sql 预编译
  5. FM对采购业务的预算控制
  6. Tomcat+nginx+keepalived+memcached实现双VIP负载均衡及Session会话保持
  7. python的代码复用技术_Python__函数和代码复用
  8. 国科大高级人工智能8-归结原理和horn子句
  9. Scroll View 控件以Thumbnail的方式显示一个目录的全部图片,相似图片浏览器
  10. Python-进阶-装饰器小结
  11. 提升安全性----用户资金防篡改
  12. 人人开源-后台前后端快速开发
  13. Win10应用设计的那些事儿
  14. 有return的情况下try catch finally的执行顺序(最有说服力的总结) 后面的神评论
  15. Android 模拟器 Root 和 SuperSU 安装
  16. c语言中num =10,num/100%10 这是什么意思求详细的计算逻辑
  17. OpenWhisk部署指南
  18. left + (right - left) / 2;
  19. HashMap源码阅读笔记
  20. 综述|姿态估计方法大盘点

热门文章

  1. php 怎么查看文件类型信息,php获取文件类型和文件信息的方法
  2. 中望cad能编写lisp吗_宁水集团:中望CAD解决方案增强设计创新力,加速转型促发展...
  3. matlab ds18b20 单片机,基于51单片机ds18b20温度检测————设计报告.doc
  4. HTML示例06---水平线
  5. 由*.flo(光流)文件生成png图片
  6. 碎片试自学软件测试?我靠自己整理的这套方,案既充实了自己也得到了涨薪
  7. 程序人生:程序员做外包“前途“,“技术“,“经验“如何决策
  8. 测试开发新手:从0到1开展性能测试必备的性能测试要点!
  9. mysql linux32_linux 32 位mysql 安装中的问题 以及修改数据库密码
  10. mysql查询结果做表_MySQL将一个表的查询结果作为本表的查询条件更新数据