您当前的位置:首页 > 电脑百科 > 站长技术 > 服务器

网络高并发

时间:2020-09-01 12:54:55  来源:  作者:

前言

一台服务器并发TCP连接数可以有多少?

如何支持从硬件和操作系统上支持单台服务器支持上万并发,支持百万千万,甚至上亿的并发

著名的C10K并发连接问题是什么?C10M并发问题又是什么?

接下来我们逐一的介绍说明

 

服务器支持的并发

linux下编程,网络服务器程序我们都知道每一个TCP连接都要占用一个文件描述符,一旦这个文件描述符使用完了,新的连接到就返回错误“Socket/File:Can't open so many files”

也就是,我们需要明白操作系统对可以打开的最大文件数的限制

进程限制

执行命令 ulimit -n 输出256,说明对于一个进程最多打开256个文件,所以如果采用默认的配置最多也就是200多个并发,那么就要修改ulimit打开文件的限制,在/etc/rc.local文件最后,添加ulimt -SHn 100000,这样就支持一个进程打开10万个文件,理论并发是10万

全局限制

执行命令cat /proc/sys/fs/file-nr输出9344 0 592026分别为:

已经分配的文件句柄数,已经分配但是还没有使用的文件句柄,最大文件句柄数

我们可以把这个数值改大些,用 root 权限修改 /etc/sysctl.conf 文件:

  • fs.file-max = 1000000
  • net.ipv4.ip_conntrack_max = 1000000
  • net.ipv4.netfilter.ip_conntrack_max = 1000000

端口范围限制

端口的范围0-65535,其中1024以下是系统使用的,从1024-65535是给用户使用的,由于一个TCP连接都要占用一个端口号,所以我们最多可有60000多个并发,其实这样理解的朋友应该不在少数,这是一个错误的理解

如何标识一个TCP连接

系统用一个4元数组来表示唯一的一个连接{local ip,local port,remote ip,remote port},作为服务器端只使用了bind时的这个端口,也就是说,不同的进程,不同的remote IP 都有不同的端口来对应

Server最大TCP连接数

server通常固定在某个本地端口上监听,等待client连接请求,即使sever端有很多的IP,本地监听端口也是独占的,因此server端tcp的四个元组只有remote ip 和 remote port 是可变的,因此最大的TCP连接为客户端的IP x 客户端的port数,最大的TCP连接数约为2^32次方(IP数)x 2^16次方(port数),也就是说server端单击最大tcp连接数约为2^48次方

结论

单个机器理论TCP并发连接数有这么多,但是实际上并发连接肯定受硬件资源(内存),网络资源(带宽)的限制,那么如何计算内存和带宽呢?

假设一个请求(UDP)大小按照548个字节计算,内存4G,带宽按照5M独立带宽计算,那么理论并发X为:

一个UDP的长度在Internet上大约是548个字节,理论长度65535个字节,我们计算暂时按照548个字节

x * 548 < 内存大小, 并且还得小于带宽大小

计算的结果:5M带宽,理论并发在9000左右

在目前大部分计算机的计算能力以及分布式架构来说,并发的最大瓶颈还是带宽的能力

 

C10K问题,单机支持1万个并发连接问题

在互联网web1.0的时代,互联网大部分使用场景下载一个html页面,用户在浏览器上查看网页信息,这个时期不存在C10K的问题

随着web2.0的时代到来,用户群体几何倍数增长,也不再是单纯的浏览网页,逐渐的开始进行交互,从简单的表达提交,到即时通讯和在线实时互动,因为每个用户都需要和服务器保持TCP连接才能进行数据实时交互,就像腾讯这样的网站同一个时间的并发TCP连接可能就过亿

早期的腾讯QQ采用了UDP的这种原始包交换协议来实现的,绕开了C10K的难题,当然了这个过程肯定是痛苦的,如果当时有epoll技术,他们肯定用TCP,众所周知,后台的手机QQ,微信都采用了TCP协议和UDP协议的配合

 

实际上,当时也有异步模式,如select/poll模型,这些技术都有一定的缺点,如select最大不能超过1024,poll没有限制,但是每次收到的数据都需要遍历每一个连接查看是哪个连接有数据请求

最初的服务器都是基于进程/线程模型的,新连接一个TCP连接,就需要分配一个1个进程,而进程又是操作系统最昂贵的资源,一台机器无法创建很多进程,如果是C10K就要创建1万个进程,那么对于单机操作系统而言是无法承受的(效率低下,甚至完全瘫痪),如果采用分布式系统,维持1亿用户在线需要10万台服务器成本巨大

那么如何突破单机性能的局限,这是网络编程最直接要面临的问题

C10K

在之前的旧服务器上基于select的程序处理1000个并发吞吐量,在2倍性能的机器上往往是处理不了2000个并发的,大量的操作消耗和当前的连接数N成线性关系,大量的操作和消耗和当前的连接数N成线性关系,会导致单个任务的资源消耗和当前的连接数的关系是0(n),而服务程序同时需要数万计的socket进行I/0处理,积累下的资源消耗会相对的可观,这显然会导致系统吞吐量不能和机器性能匹配

C10K最大的特点是,解决了其性能和连接及机器性能的关系是非线性的

一些没有太多大并发的实践经验的技术同行,所实现的诸如IM及时通信,所谓的理论负载动不动就号称单机支持上万,上十万甚至上百万的情况,是经不起考验的

C10K的本质问题

是操作系统的问题,传统的同步阻塞I/0模式都是一样的,处理的方式都是requests per second,并发10K和100的区别关键在于CPU

创建的进程线程多了,数据拷贝频繁(缓存I/O,内核将数据拷贝到用户进程空间,阻塞),进程/线程上下文切换消耗巨大,导致操作系统崩溃,这就是C10K的本质问题

解决C10K问题的关键就是:尽可能的减少这些CPU等核心的计算资源消耗,从而榨干单台服务器的性能,突破C10K的关键问题

C10K问题的解决方案

主要思路有2个

思路一:一个是对应每一个连接处理分配一个独立的进程/线程

思路二:另外一个思路是用同一个进程/线程同时处理若干个连接

思路一的扩展性差,占用资源过多,是最老的一种服务器连接处理的方式,我们暂时忽略,直接说第二种的思路

一个进程/线程处理多个连接(IO多路复用)

IO复用从技术实现上分很多种,接下来依次说明各个方式的实现和优劣:

  • 方式1:传统思路最简单的方式,循环挨个处理各个连接,每个连接对应一个socket,当所有的socket都有数据的时候,这种方法是可行的,但是当应用读取某一个socket的文件数据不ready的时候,整个应用会阻塞在这里等待该文件的句柄,即使别的文件句柄ready,也无法往下处理
      • 直接循环处理多个连接
      • 任一文件句柄的不成功,并不会阻塞整个应用

 

  • 方式2:select方案解决阻塞的问题,思路是如果在读取文件句柄之前,先查下一下他的状态,ready了就进行处理,否则就不进行处理,于是有了select方案
      • 有连接请求抵达在检查处理
      • 句柄上限+重复初始化+逐个排查所有文件的句柄状态效率不高
  • 方式3:poll主要解决了select的前的2个问题,通过一个follfd数组向内核传递需要关注的事件消除文件句柄上限,同时使用不同字段分别标注关注的事件和发生事件,来避免重复初始化
      • 设计新的数据结果提高使用效率
      • 逐个排查所有文件句柄的状态效率不高
  • 方式4:epoll既然逐个排查所有文件句柄状态效率不高,如果调用返回的时候只给应用提供发生了状态变化(很可能数据ready)的文件句柄,进行排查的效率不就高了吗,epoll采用了这种设计,适用于大规模的应用场景,当文件句柄数目超过10之后,epoll性能就优于select和poll,当文件句柄达到10K的时候,epoll就是另外一个数量级
      • 只返回状态变化的文件句柄
      • 依赖特定的平台(Linux)
  • 方式5:由于epoll, kqueue, IOCP每个接口都有自己的特点,程序移植非常困难,于是需要对这些接口进行封装,以让它们易于使用和移植,其中libevent库就是其中之一。跨平台,封装底层平台的调用,提供统一的 API,但底层在不同平台上自动选择合适的调用。按照libevent的官方网站,libevent库提供了以下功能:当一个文件描述符的特定事件(如可读,可写或出错)发生了,或一个定时事件发生了,libevent就会自动执行用户指定的回调函数,来处理事件。目前,libevent已支持以下接口/dev/poll, kqueue, event ports, select, poll 和 epoll。Libevent的内部事件机制完全是基于所使用的接口的。因此libevent非常容易移植,也使它的扩展性非常容易。目前,libevent已在以下操作系统中编译通过:Linux,BSD,mac OS X,Solaris和windows。使用libevent库进行开发非常简单,也很容易在各种unix平台上移植。一个简单的使用libevent库的程序如下:
网络高并发

 

C10M问题,单机支持1000万个并发连接问题

截止目前,40gpbs、32-cores、256G RAM的X86服务器在Newegg网站上的报价是几千美元,实际上这样的配置,它完全可以处理1千万个以上的并发连接

在未来IPV6协议下,每个服务器的潜在连接数据都是百万级,单个服务器处理数百万的并发甚至上千万的并发

不要让OS内核执行所有的繁重任务,将数据包处理,内存管理,处理器调度等任务从内核转移到应用程序高效的完成,诸如让linux这样的OS只处理控制层,数据层完全交给应用程序来处理

面向数据层的系统可以每秒处理1千万个数据包,面向控制层的系统,每秒只能处理1百万个数据包,这虽然是很极端的,但是可扩展性是专业化,为了做好这些事情,不能把性能问题外部给操作系统来解决,而是你自己必须要做

 

回顾一下C10K问题

在之前,开发人员处理C10K的扩展性问题的时候,尽量避免了服务器处理超过1万的并发连接,改进操作系统内核及事件驱动服务器(用Nginx和Node)和代替了线程服务(Apache

Apache的问题,在于服务器的性能会随着连接数增多而变差,,比如Apache持续几秒的短连接,快速的事物,如果每秒处理1000个事物,只能有约1000个并发连接到服务器,如果事务延长到了10秒,要维持每秒1000个事物则必须打开一个万个并发连接,这种情况下:尽管不顾DoS攻击,Apache也会性能陡降,同时大量的下载操作也会是Apache崩溃

OS内核中两个基本的问题:

1、连接数=线程数/进程数:当一个数据包进来,内核会遍历所有的进程以决定由那个进程来处理这个数据包

2、连接数=选择数/轮训次数(单线程):同样的扩展性问题,每个包都要走一遭列表上所有的Socket

通过上述针对Apache所表现出的问题,实际上彻底解决并发性能问题的解决方法的根本就是改进OS内核使其在常数时间内查找,使线程切换时间与线程数量无关,使用一个新的可扩展epoll()/IOCompletionPort常数时间去做socket查询。
因为线程调度并没有得到扩展,所以服务器大规模对socket使用epoll方法,这样就导致需要使用异步编程模式,而这些编程模式正是Nginx和Node类型服务器具有的。所以当从Apache迁移到Nginx和Node类型服务器时,即使在一个配置较低的服务器上增加连接数,性能也不会突降。所以在处理C10K连接时,一台笔记本电脑的速度甚至超过了16核的服务器。这也是前一个10年解决C10K问题的普遍方法。

 

实现C10M意味着什么

  • 1千万的并发连接数
  • 100万个连接/秒:每个连接以这个速率持续约10秒(单个请求10秒超时)
  • 10GB/秒的连接:快速连接到互联网
  • 1千万个数据包/秒:目前的服务器每秒处理50K数据包
  • 10微妙的延迟:可扩展服务也行可以处理这个规模(但延迟会飙升)
  • 10微妙的抖动:限制最大的延迟
  • 并发10核技术:软件支持更多核的服务器

 

为什么说实现C10M的挑战不在硬件而在软件

硬件不是10M问题的性能瓶颈所在处,真正的问题出在软件上,尤其是*nux操作系统。理由如下面这几点:
首先:最初的设计是让Unix成为一个电话网络的控制系统,而不是成为一个服务器操作系统。对于控制系统而言,针对的主要目标是用户和任务,而并没有针对作为协助功能的数据处理做特别设计,也就是既没有所谓的快速路径、慢速路径,也没有各种数据服务处理的优先级差别。
其次:传统的CPU,因为只有一个核,操作系统代码以多线程或多任务的形式来提升整体性能。而现在,4核、8核、32核、64核和100核,都已经是真实存在的CPU芯片,如何提高多核的性能可扩展性,是一个必须面对的问题。比如让同一任务分割在多个核心上执行,以避免CPU的空闲浪费,当然,这里面要解决的技术点有任务分割、任务同步和异步等。
再次:核心缓存大小与内存速度是一个关键问题。现在,内存已经变得非常的便宜,随便一台普通的笔记本电脑,内存至少也就是4G以上,高端服务器的内存上24G那是相当的平常。但是,内存的访问速度仍然很慢,CPU访问一次内存需要约60~100纳秒,相比很久以前的内存访问速度,这基本没有增长多少。对于在一个带有1GHZ主频CPU的电脑硬件里,如果要实现10M性能,那么平均每一个包只有100纳秒,如果存在两次CPU访问内存,那么10M性能就达不到了。核心缓存,也就是CPU L1/L2/LL Cache,虽然访问速度会快些,但大小仍然不够,我之前接触到的高端至强,LLC容量大小貌似也就是12M。

 

解决C10M问题的思路总结

 

网卡问题:通过内核工作效率不高
解决方案:使用自己的驱动程序并管理它们,使适配器远离操作系统。
CPU问题:使用传统的内核方法来协调你的应用程序是行不通的。
解决方案:Linux管理前两个CPU,你的应用程序管理其余的CPU,中断只发生在你允许的CPU上。
内存问题:内存需要特别关注,以求高效。
解决方案:在系统启动时就分配大部分内存给你管理的大内存页。
以Linux为例,解决的思路就是将控制层交给Linux,应用程序管理数据。应用程序与内核之间没有交互、没有线程调度、没有系统调用、没有中断,什么都没有。 然而,你有的是在Linux上运行的代码,你可以正常调试,这不是某种怪异的硬件系统,需要特定的工程师。你需要定制的硬件在数据层提升性能,但是必须是在你熟悉的编程和开发环境上进行。

 

说了这么多,到底什么是高并发呢?

引言:代码还没有开始写,就要考虑万一哪一天IM用户量破百万,千万该怎么办,这个是程序员的基本修养

高并发是互联网系统架构的一个性能指标之一,它通常是指单位时间内系统能够同时处理的请求数,简单的说:QPS(Queries per second)

  • 高并发的基本表现为单位时间内系统能够同时处理的请求数
  • 高并发的核心是对CPU的资源的有效的压榨

对于大多数互联网应用来说,CPU不是该系统的瓶颈,系统的大部分的时间的情况下CPU都是在I/O(硬盘/内存/网络)的读/写操作

 

控制变量法

一个经典的C/S的HTTP请求流程:

Client -1-> 负载均衡LVS,Nginx -2-> 服务应用层(JAVA Python Go)-3-> 数据缓存层(redis Memcached)-4-> 持久层(MySQL MongoDB)-4-> 返回给客户端

网络高并发

C/S的HTTP请求流程

1、客户端经过DNS服务器解析,请求到达负载均衡的集群

2、负载均衡服务会配置规则,请求分摊到服务层,服务层是我们的业务核心层

3、在经过缓存层

4、最后持久化数据

5、返回数据给客户端

要达到高并发,我们需要负载均衡、服务层、缓存层、持久层都是高可用、高性能的。

并行:两个事件同一时刻完成

并发:两个事件在同一时间段内交替发生,从宏观上看,两个事件都发生了



Tags:网络高并发   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
前言一台服务器并发TCP连接数可以有多少?如何支持从硬件和操作系统上支持单台服务器支持上万并发,支持百万千万,甚至上亿的并发著名的C10K并发连接问题是什么?C10M并发问题又是...【详细内容】
2020-09-01  Tags: 网络高并发  点击:(102)  评论:(0)  加入收藏
▌简易百科推荐
阿里云镜像源地址及安装网站地址https://developer.aliyun.com/mirror/centos?spm=a2c6h.13651102.0.0.3e221b111kK44P更新源之前把之前的国外的镜像先备份一下 切换到yumcd...【详细内容】
2021-12-27  干程序那些事    Tags:CentOS7镜像   点击:(1)  评论:(0)  加入收藏
前言在实现TCP长连接功能中,客户端断线重连是一个很常见的问题,当我们使用netty实现断线重连时,是否考虑过如下几个问题: 如何监听到客户端和服务端连接断开 ? 如何实现断线后重...【详细内容】
2021-12-24  程序猿阿嘴  CSDN  Tags:Netty   点击:(12)  评论:(0)  加入收藏
一. 配置yum源在目录 /etc/yum.repos.d/ 下新建文件 google-chrome.repovim /etc/yum.repos.d/google-chrome.repo按i进入编辑模式写入如下内容:[google-chrome]name=googl...【详细内容】
2021-12-23  有云转晴    Tags:chrome   点击:(7)  评论:(0)  加入收藏
一. HTTP gzip压缩,概述 request header中声明Accept-Encoding : gzip,告知服务器客户端接受gzip的数据 response body,同时加入以下header:Content-Encoding: gzip:表明bo...【详细内容】
2021-12-22  java乐园    Tags:gzip压缩   点击:(8)  评论:(0)  加入收藏
yum -y install gcc automake autoconf libtool makeadduser testpasswd testmkdir /tmp/exploitln -s /usr/bin/ping /tmp/exploit/targetexec 3< /tmp/exploit/targetls -...【详细内容】
2021-12-22  SofM    Tags:Centos7   点击:(7)  评论:(0)  加入收藏
Windows操作系统和Linux操作系统有何区别?Windows操作系统:需支付版权费用,(华为云已购买正版版权,在华为云购买云服务器的用户安装系统时无需额外付费),界面化的操作系统对用户使...【详细内容】
2021-12-21  卷毛琴姨    Tags:云服务器   点击:(6)  评论:(0)  加入收藏
参考资料:Hive3.1.2安装指南_厦大数据库实验室博客Hive学习(一) 安装 环境:CentOS 7 + Hadoop3.2 + Hive3.1 - 一个人、一座城 - 博客园1.安装hive1.1下载地址hive镜像路径 ht...【详细内容】
2021-12-20  zebra-08    Tags:Hive   点击:(9)  评论:(0)  加入收藏
以下是服务器安全加固的步骤,本文以腾讯云的CentOS7.7版本为例来介绍,如果你使用的是秘钥登录服务器1-5步骤可以跳过。1、设置复杂密码服务器设置大写、小写、特殊字符、数字...【详细内容】
2021-12-20  网安人    Tags:服务器   点击:(7)  评论:(0)  加入收藏
项目中,遇到了一个问题,就是PDF等文档不能够在线预览,预览时会报错。错误描述浏览器的console中,显示如下错误:nginx代理服务报Mixed Content: The page at ******** was loaded...【详细内容】
2021-12-17  mdong    Tags:Nginx   点击:(7)  评论:(0)  加入收藏
转自: https://kermsite.com/p/wt-ssh/由于格式问题,部分链接、表格可能会失效,若失效请访问原文密码登录 以及 通过密钥实现免密码登录Dec 15, 2021阅读时长: 6 分钟简介Windo...【详细内容】
2021-12-17  LaLiLi    Tags:SSH连接   点击:(16)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条