当前位置:首页 > 服务器 > 正文

50万长连接服务器怎么调优(百度怎么连接服务器)

本篇文章给大家谈谈50万长连接服务器怎么调优,以及百度怎么连接服务器对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

【TCP】单台服务器并发 TCP 连接数到底可以有多少 ?

长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持。

长连接,是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接。

聊天室或即时消息推送系统等,因为很多消息需要到产生时才推送给客户端,所以当没有消息产生时,就需要hold住客户端的连接,这样,当有大量的客户端时,要hold住大量的长连接。

在性能测试过程中,经常会接触到连接数相关的问题,有一个问题曾经困扰我好长时间,那就是一台服务器最多能支持多少链接数呢?

有的朋友可能会说是65535,因为操作系统有65535个端口,那么这个答案准确吗?

首先先了解下如何标识一个链接(记住下面的概念,文章后面要用到),操作系统是通过一个四元组来标识一个TCP链接:

{本地ip,本地port,远程ip,远程port}

这四个要素唯一确定一个TCP链接,任意一个要素不相同,就认为是一个不同的链接。

在Linux系统中,一切皆文件,每一个TCP链接都要占用一个文件句柄,系统允许创建的链接数取决于句柄数的上限。超过这个值再创建链接就会报这样的错误:“Can't open so many files"。

通过命令ulimit -n可以查看当前系统允许打开文件数量的上限,在Linux中这个值默认是1024,也就是说默认情况下,只能创建1024个链接。同时这个值也是可以修改的,通过修改/etc/security/limits.conf文件,可以把这个值改大,一般服务器都会改的很大,比如我们的服务器上一般设置为1000000。

那这么说是不是就意味着只要我改的很大,链接数可以无限大了?

其实也并不是这样,创建链接的时候,一般分为两个端, 即链接的发起端和链接接收端。

比如我们现在使用Jmeter进行压测,被测系统部署在Tomcat服务器10.0.0.3上,使用的是8080端口。

如果我们用5个并发来进行压测的话,创建的链接如下图所示:

对于Jmeter来说,它是链接发起端,Jmeter创建了5个链接去连接服务端的8080端口,每个新建链接会占用了一个端口号,如图中的10001-10005。在操作系统中,端口号的范围是0-65535,其中0-1024是预留端口号,不可使用,其他的端口都是可以使用的。也就是说, 在链接发起端,受端口号的限制理论上最多可以创建64000左右链接。

那么有没有办法超过这个限制呢,答案是肯定的!

通过TCP标识的四元组可以看到,对于链接发起端,影响链接数的是本地ip和port,端口号受限于65535,已经没办法增加了。那我们可以增加本地ip来达到这个目的。一般情况下,服务器的一个网卡上只绑定了一个ip,对外通信都使用这个ip进行。其实网卡是支持一个绑定多个IP的,当然必须确保ip是有效的且未使用的。

# ifconfig eth0:1 10.0.0.5

以上命令可以在eth0网卡上增加一个ip 10.0.0.5,服务器网卡每增加一个ip,就可以允许在这个ip上再创建65535左右的链接数。

曾经做过一个邮件网关的链接数测试,目的是为了测试网关服务器可以接收并且保持多少TCP长连接。正常情况下,受限于单台机器65535端口号的影响,客户端想创建25万TCP长连接,至少需要4台机器。通过对客户端网卡绑定多IP的方法,成功在一台机器上创建了25万个链接。

当然,这种手段只是一种非常规的操作,只是为了进行某种特殊场景的测试。正常情况下不推荐网卡绑定多个IP。

对于Tomcat服务器来讲,它是链接接收端,它是不是也受限于65535呢?

并不是,从上面图中可以看到,Jmeter发起的所有链接都创建在Tomcat服务器的8080端口,也就是说对于链接接收端,所有的链接占用的是同一个端口。

根据TCP标识四元组可以分析出, 一个链接接收端,最大的TCP链接数=所有有效ip排列组合的数量*端口数量64000 ,这个计算结果应该是一个天文数字。 因此链接接收端支持的链接数理论上可以认为是无限大的。

上面介绍的一些数据都是理论上单台机器可以支持的TCP链接数, 实际情况下,每创建一个链接需要消耗一定的内存,大概是4-10kb,所以链接数也受限于机器的总内存。

链接发起端,活力全开才64000左右链接,内存最多才占用640M,一般客户端都能 满足,内存限制主要还是考虑服务器端。

虽然现在的集群,分布式技术可以为我们将并发负载分担在多台服务器上,那我们只需要扩展出数十台电脑就可以解决问题,但是我们更希望能更大的挖掘单台服务器的资源,先努力垂直扩展,再进行水平扩展,这样可以有效的节省服务器相关的开支(硬件资源、机房、运维人力、电力其实也是一笔不小的开支)。

首先需要考虑文件句柄的限制。在Linux下编写网络服务器程序的朋友肯定都知道每一个tcp连接都要占一个文件描述符,一旦这个文件描述符使用完了,新的连接到来返回给我们的错误是“Socket/File:Can't open so many files”。这时你需要明白操作系统对可以打开的最大文件数的限制。

我们可以通过ulimit -n命令、/etc/security/limits.conf 文件 以及 /etc/sysctl.conf 文件等来修改文件句柄数。

其次要考虑的是端口范围的限制,操作系统上端口号1024以下是系统保留的,从1024-65535是用户使用的。

由于每个TCP连接都要占一个端口号,所以我们最多可以有60000多个并发连接。我想有这种错误思路朋友不在少数吧?

面试官也比较喜欢在这里引导挖坑,类似的问题还有:一个UDP连接可以复用已经被TCP连接占用的端口嘛?

如何标识一个TCP连接?

系统使用一个4四元组来唯一标识一个TCP连接:

本地端口号 local port、本地IP地址 local ip、远端端口号 remote port、远端IP地址 remote ip。

server通常固定在某个本地端口上监听,等待client的连接请求。不考虑地址重用(unix的SO_REUSEADDR选项)的情况下,即使server端有多个ip,本地监听端口也是独占的,因此server端tcp连接4元组中只有remote ip(也就是client ip)和remote port(客户端port)是可变的,因此最大tcp连接为客户端ip数×客户端port数,对IPV4,不考虑ip地址分类等因素,最大tcp连接数约为2的32次方(ip数)×2的16次方(port数),也就是server端单机最大tcp连接数约为2的48次方。

上面给出的结论都是理论上的单机TCP并发连接数,实际上单机并发连接数肯定要受硬件资源(内存)、网络资源(带宽)的限制。

单台服务器最大支持多少连接数

单机服务器支持千万级并发长连接的压力测试

HTTP长连接200万尝试及调优

一次百万长连接压测 Nginx 内存溢出问题

大并发下TCP内存消耗优化小记(86万并发业务正常服务)

TCP长连接与短连接的区别

Linux系统设置–ulimit

HTTP的长连接和短连接

网络连接中的长连接和短链接是什么意思?

性能优化篇-使用长连接提升服务性能

nginx能支持多少长连接

一 前言

当管理大量连接时,特别是只有少量活跃连接,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

基本用法:

(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

4. 约2小时后。。。查看服务端

# curl

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万连接是完全没问题的。

java Netty NIO 如何突破 65536 个端口的限制?如何做到10万~50万的长连接?

通常情况下是不可以突破的,端口有限制.单独对外提供请求的服务不用考虑端口数量问题,监听某一个端口即可.但是向提供代理服务器,就不得不考虑端口数量受限问题了.当前的1M并发连接测试,也需要在客户端突破6万可用端口的限制.端口为16进制,那么2的16次方值为65536,在linux系统里面,1024以下端口都是超级管理员用户(如root)才可以使用,普通用户只能使用大于1024的端口值.

服务器是只监听一个端口,所有的客户端连接,都是连接到服务器的同一个端口上的。也就是说服务器只是用了一个端口。就比如Http服务器。默认只用了80端口。

nio 在linux上使用的是epoll ,epoll支持在一个进程中打开的FD是操作系统最大文件句柄数,而不是你所说的16位short表示的文件句柄。 而 select模型 单进程打开的FD是受限的 select模型默认FD是1024 。操作系统最大文件句柄数跟内存有关,1GB内存的机器上,大概是10万个句柄左右。

java Netty NIO 如何突破 65536 个端口的限制?如何做到 10万~50万 长连接?

NIO突破不了65535的端口数限制,linux端口范围0--65535,一般用户1025 ~ 65535

server端最大tcp连接数,理论上是2的48次方。

一个端口最大连接数cat /proc/sys/fs/file-max查看

客户端连接上端口之后的处理,才是netty的内容。netty代码监听着某个端口。

长连接不是问题,可能你要考虑的是并发问题

50万长连接服务器怎么调优的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于百度怎么连接服务器、50万长连接服务器怎么调优的信息别忘了在本站进行查找喔。

取消
扫码支持 支付码