http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=190176&id=4234854

一 前言
 
当管理大量连接时,特别是只有少量活跃连接,NGINX有比较好的CPU和RAM利用率,如今是多终端保持在线的时代,更能让NGINX发挥这个优点。本文做一个简单测试,NGINX在一个普通PC虚拟机上维护100k的HTTP长连接,然后查看NGINX和系统的资源利用率。
 
二 测试环境
 
1.服务端
 
硬件:双核2.3GHz,2GB内存
软件:CentOS 6.5, kernel 2.6.32,  gcc 4.4.7, nginx 1.4.7
IP:10.211.55.8
 
内核参数调整:

$ /sbin/sysctl -w net.netfilter.nf_conntrack_max=102400 # 提升系统整体连接数
$ /sbin/sysctl net.netfilter.nf_conntrack_max #验证是否生效
 
NGINX从源码编译时带--with-http_stub_status_module,只列出与默认设置不同的部分:

worker_rlimit_nofile 102400;

events {
    worker_connections  102400;
}
http {
       # 设一个比较大得超时,客户端能以平缓的方式发送HEAD请求来维持KeepAlive
       keepalive_timeout  3600;
 
        #监控连接数,本机访问
        location /nginx_status {
            stub_status on;
            access_log   off;
            allow 127.0.0.1;
            deny all;
        }
}
 
 
2. 客户端1
 
硬件:双核2.3GHz,2GB内存
软件:CentOS 6.5, kernel 2.6.32, gcc 4.4.7, Python 3.3.5
IP:10.211.55.9
 
内核参数调整:
$ /sbin/sysctl -w net.ipv4.ip_local_port_range="1024 61024” #实际只使用50000个端口
$ /sbin/sysctl net.ipv4.ip_local_port_range #验证是否生效
$ vi /etc/security/limits.conf #提升当前用户的最大打开文件数nofile(hard >= soft > 50000)
$ ulimit -n #验证是否生效,可能需重启shell
 
Python 3.3.5从源码编译,如下配置:
$ pyvenv ~/pyvenv #创建虚拟环境,便于测试
$ . ~/pyvenv/bin/activate #激活虚拟环境
(pyvenv) $ python get-pip.py #从pip官网下载get-pip.py
(pyvenv) $ pip install asyncio #安装异步IO模块
 
因为Apache ab只能批量请求,不能维持连接,所以自己写了一个HTTP长连接测试工具asyncli.py,详细实现见http://blog.chinaunix.net/uid-190176-id-4223282.html
基本用法:
(pyvenv) $ python asyncli.py --help

usage: asyncli.py [-h] [-c CONNECTIONS] [-k KEEPALIVE] url
 
asyncli
 
positional arguments:
  url                   page address
 
optional arguments:
  -h, --help            show this help message and exit
  -c CONNECTIONS, --connections CONNECTIONS
                        number of connections simultaneously
  -k KEEPALIVE, --keepalive KEEPALIVE
                        HTTP keepalive timeout
 
工作机制:
每隔10毫秒连续创建10个连接(每秒约1000个连接),直到总连接数达到CONNECTIONS,每个连接都会睡眠[1, KEEPALIVE / 2]的一个随机数(单位为秒),然后向服务端url发送一个HEAD请求来维持HTTP KeepAlive,然后重复上一个睡眠步骤。。。
 
3. 客户端2
 
与客户端1完全一致,除了IP为10.211.55.10
 
三 运行与输出
 
1. 服务端系统空闲
# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 1723336  11624  76124    0    0    62     1   26   28  0  0 100  0  0
 
2. 服务端启动NGINX,无外部WEB请求
# nginx
# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 1681552  11868  76840    0    0    50     1   24   25  0  0 100  0  0 
 
3. 客户端1和2先后启动,每个客户端发起50000个长连接,并维持直到服务端关闭或超时
(pyvenv) $ python asyncli.py -c 50000 -k 3600 http://10.211.55.8/ &
 
4. 约2小时后。。。查看服务端
# curl http://127.0.0.1/nginx_status

Active connections: 100001
server accepts handled requests
 165539 165539 1095055
Reading: 0 Writing: 1 Waiting: 100000
 
# ps -p 1899 -o pid,%cpu,%mem,rss,comm
  PID %CPU %MEM   RSS COMMAND
 1899  2.0  4.9 94600 nginx
 
# vmstat 3
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 654248  62920 158924    0    0     6     6  361  108  0  1 98  0  0    
 0  0      0 654232  62920 158952    0    0     0    85  804  218  0  1 98  0  0    
 0  0      0 654108  62928 158976    0    0     0     9  813  214  0  1 98  0  0    
 0  0      0 654108  62928 159004    0    0     0     0  803  220  0  1 99  0  0    
^C
 
# free
             total       used       free     shared    buffers     cached
Mem:       1918576    1264576     654000          0      62952     159112
-/+ buffers/cache:    1042512     876064
Swap:      4128760          0    4128760
 
四 总结
 
1. NGINX平均每个连接的内存占用很小,通过ps的rss看出,每个连接物理内存占用约1k。多数内存都被内核TCP缓存占用。
2. NGINX维持大量连接(少量活跃连接,本文中平均每秒活跃连接为总连接数的千分之一)占用很少CPU,上文仅为2%。
3. 最好的优化就是不优化。整个测试除了提升文件数和连接数的这些硬限制外,没有任何参数调优,但仔细计算下就发现平均每个连接内存占用不到10k,远小于默认的缓存大小(net.ipv4.tcp_rmem = 4096     87380     4194304)和 (net.ipv4.tcp_wmem = 4096     16384     4194304)
4. NGINX维持此类连接的主要瓶颈就是可用内存大小,我的2GB内存虚拟机其实可以支持15万长连接,只不过我物理机器没有内存再继续clone虚拟机客户端了:-(
5. 虽然会遇到更多内核参数的限制,但大内存服务器支持100万连接是完全没问题的。

NGINX轻松管理10万长连接 --- 基于2GB内存的CentOS 6.5 x86-64的更多相关文章

  1. NGINX轻松管理10万长连接

    先说说服务为什么使用HTTPs长连接技术?有如下几个原因:对响应时间要求较高:服务走的是公网,客户端与服务端的TCP建立的三次握手和断开的四次握手都需要40ms左右(真实数据包计算出来的),共需要80 ...

  2. 使用SuperSocket打造逾10万长连接的Socket服务

    SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架.你无须了解如何使用 Socket, 如何维护 Socket 连接和 Socket 如何工作 ...

  3. Nginx总结(九)Nginx服务器高性能优化的配置--轻松实现10万并发访问量

    前面讲了如何配置Nginx虚拟主机,如何配置服务日志等很多基础的内容,大家可以去这里看看nginx系列文章:https://www.cnblogs.com/zhangweizhong/category ...

  4. [NewLife.Net]单机400万长连接压力测试

    目标 对网络库NewLife.Net进行单机百万级长连接测试,并持续收发数据,检测网络库稳定性. [2020年8月1日晚上22点] 先上源码:https://github.com/NewLifeX/N ...

  5. nginx反向代理时保持长连接

    ·[场景描述] HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟. 如果我们使用了nginx去作为 ...

  6. Nginx Upstream Keepalive 分析 保持长连接

    Nginx Upstream长连接由upstream模式下的keepalive指令控制,并指定可用于长连接的连接数,配置样例如下: upstream http_backend {     server ...

  7. (转)nginx优化 实现10万并发访问量

    转自http://www.cnblogs.com/pricks/p/3837149.html 一般来说nginx配置文件中对优化比较有作用的为以下几项:worker_processes 8;1 ngi ...

  8. nginx优化 实现10万并发访问量

    一般来说nginx配置文件中对优化比较有作用的为以下几项:worker_processes 8;1 nginx进程数,建议按照cpu数目来指定,一般为它的倍数.worker_cpu_affinity ...

  9. 2016年度,这40项IT技能年薪轻松超过10万美元

    众所周知,科技行业聚集了大批高薪职位,但这同样也是一个快速变化的市场.今天的热门技能明天就有可能惨遭淘汰. 求职网站Dice.com最近发布了<2016薪酬调查>, 列举了年薪最高的各种科 ...

随机推荐

  1. Oracle Rac crs无法启动

    OS:ORACLE LINUX 5.7 DB:11.2.0.3 RAC:YES 故障:1.两节点RAC,节点分别为linuxdb1.linuxdb2,其中节点linuxdb2服务器出现故障,无法启动2 ...

  2. oracle DML错误日志(笔记)

    DML错误日志是oracle10gR2引入的一个类似于SQL*Loader的错误日志功能.它的基本原理是把任何可能导致语句失败的记录转移,放到一张错误日志表中. 具体使用如下: 1.使用DBMS_ER ...

  3. 随机数范围扩展(如rand7()到rand10())(转)

    题目:已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10.分析:要保证rand10()在整数1-10的均匀分布,可以构造一个1-10*n的均 ...

  4. ASP.NET浏览器定义文件及IE兼容模式

    由于ASP.NET4.0中的一个小bug,导致了ASP.NET WebForms控制的CallBack无效,部分控件无法使用. 解决方法是在项目中添加自定义的浏览器定义文件,参考这里:http://w ...

  5. c++基础(二):成员he派生类

    struct Date{ int day, month, year; }; struct Book{ string name; Date date; void init(string n, int y ...

  6. IOS中的UINavigationController(导航控制器)

    UINavigationController UINavigationControlle:导航控制器,是iOS中最常用的多视图控制器之一,它用来管理多个试图控制器 导航控制器可以认为是管理控制器的控制 ...

  7. DataGridView 中CheckBox 获取状态

    /// <summary> /// /// </summary> /// <param name="sender"></param> ...

  8. 如何使用和了解ALTERA的IP核

    可以通过直接对IP核进行仿真验证,通过波形来分析IP核的功能和工作方式,以及各个寄存器之间的工作关系. 也可以通过查看用户指导手册来学习IP核,如下图.

  9. 如何破解UltraEdit

    在断网的前提下,软件->帮助->注册->激活->脱机激活—>用户和密码随便输入->还有两个空着,就是该用注册机激活了. 打开注册机->输入ULtredit的自 ...

  10. 28.USB的传输类型

    USB上必须将数据组织成 事务 才能够进行传输.事务常有两个或三个包.令牌包用于启动一个事务,由主机发送:数据包传送数据,方向由令牌包确定:握手包常是数据接收方发送的,用于表示接收数据的状态.USB协 ...