当前位置: > Linux服务器 > nginx >

Nginx启动配置加载性能分析:作为http服务器

时间:2015-09-05 02:32来源:linux.it.net.cn 作者:IT
本文测试了在配置文件规模较大时, Nginx作为http服务器的启动速度,并分析耗时原因。

  结论:

  1. Nginx初始化中影响性能点在于listen IP:PORT, 其中port的汇聚会造成初始化速度变得很慢

  2. 对于Server_name的初始化相当快, 对初始化性能无影响

  一、测试内容

  脚本创建3类配置文件, 规则如下:

  1. 共创建2万条Server{}配置

  2. server_name基本定长, PerformanceTestxxx

  3. 第1类是listen的IP完全一致,port全不同, 配置文件实例:

 
  1. http{
  2. server{
  3. listen 192.168.0.1:8080;
  4. server_name PerformanceTest8080;
  5. }
  6. server{
  7. listen 192.168.0.1:8081;
  8. server_name PerformanceTest8081;
  9. ….
  10. }
  11. }

  3. 第2类是listen的Port完全一致,IP全不同, 配置文件实例:

 
  1. http{
  2. server{
  3. listen 192.168.0.1:80;
  4. server_name PerformanceTest1;
  5. }
  6. server{
  7. listen 192.168.0.2:80;
  8. server_name PerformanceTest2;
  9. ….
  10. }
  11. }

  4. 第3类是listen的IP:PORT完全一致, server_name全不同, 配置文件实例:

 
  1. http{
  2. server{
  3. listen 192.168.0.1:80;
  4. server_name PerformanceTest001;
  5. }
  6. server{
  7. listen 192.168.0.1:80;
  8. server_name PerformanceTest002;
  9. ….
  10. }
  11. }

  二、 测试数据

  对于3类配置, 再加入3组变量:

  1. 不配置server_name

  2. server_name全配置一样

  3. server_name全配置不一样

  看server_name对于初始化速度的影响

  9种组合的性能如下:

  

  nginx 启动时间:time ./nginx -c /root/nginx.conf.sameport.noloc

  nginx reload时间:time ./nginx -c /root/nginx.conf.sameport.noloc –s reload

  从测试数据可以看出, 对nginx启动速度影响的因素为server{}中listen的port, server_name指令基本无影响。

  三、 原因分析

  3.1 http{}初始化流程简单介绍:

  

  解析配置文件是递归地调用ngx_conf_parse函数完成的, http{}配置块的解析流程:

  1. 解析到http指令, 执行ngx_http_block函数, 创建http module的配置上下文后, 继续ngx_conf_parse解析http{}内部的内容;

  2. 解析到server指令, 执行ngx_http_core_server函数, 创建该server{}的配置上下文后, 继续ngx_conf_parse解析server{}内部的内容;

  3. 解析到listen指令, 添加到cscf以及cmcf配置中, 如下图:

  1. cmcf->servers数组保存了所有监听的server数据

  

  2. cmcf->ports数组保存了所有port汇聚的ip的数据. listen同一个ip:port, server_name不同的srv_conf会挂在ngx_http_conf_addr_t的servers数组下。

  

  一个配置好的样子可能是这样:

  

  3.2 耗时位置定位

  代码中加变量记录函数耗时总时间, 得到启动时耗时在2个步骤:

  1) 解析配置文件, 对应ngx_conf_parse函数

  2) 初始化socket, 对应ngx_open_listening_sockets函数

  

  3.3 ngx_conf_parse耗时分析

  主要是ngx_http_block函数的耗时, 分为以下2个部分:

  

  很明显, ngx_http_add_addresses函数的性能消耗在对相同port已存在ip的查找上面, 这里用的是线性的遍历查找,

  且需要进行字符串比较ngx_memcmp被执行了2w*2w共4亿次:

 
  1. for (i = 0; i < port->addrs.nelts; i++) {
  2. // 遍历查找, 如果配置文件中,相同port的IP过多,字符串比较带来较大性能问题, 2w个listen,这一块耗时需要8s左右
  3. if (ngx_memcmp(p, addr[i].opt.u.sockaddr_data + off, len) != 0) {
  4. continue;
  5. }
  6. /* the address is already in the address list */
  7. // 找到对应的ip, 添加cscf到IP
  8. if (ngx_http_add_server(cf, cscf, &addr[i]) != NGX_OK) {
  9. return NGX_ERROR;
  10. }

  3.4 ngx_open_listening_sockets耗时分析

  函数中初始化所有listening的socket

 
  1. /* for each listening socket */
  2. ls = cycle->listening.elts;
  3. for (i = 0; i < cycle->listening.nelts; i++) {
  4. if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
  5. if (listen(s, ls[i].backlog) == -1) {
  6. }

  

  对于同1个IP,新建不同port的socket相比新建多个不同IP的socket更省时间。

(责任编辑:IT)
------分隔线----------------------------
栏目列表
推荐内容