1. 网友评论
不同并发模式的选择,还要考察三个指标,分别是响应时间(RT),并发数(Concurrency),吞吐量(TPS)。
三者关系,吞吐量=并发数/平均响应时间。不同类型的系统,对这三个指标的要求不一样。
三高系统,比如秒杀、即时通信,不能使用。 三低系统,比如ToB系统,运营类、管理类系统,一般可以使用。 高吞吐系统,如果是内存计算为主的,一般可以使用,如果是网络IO为主的,一般不能使用。
2. 公号-技术夜未眠
2018-06-07
BIO:一个线程处理一个请求。缺点:并发量高时,线程数较多,浪费资源。Tomcat7或以下,在Linux系统中默认使用这种方式。可以适用于小到中规模的客户端并发数场景,无法胜任大规模并发业务。如果编程控制不善,可能造成系统资源耗尽。
NIO:利用多路复用IO技术,可以通过少量的线程处理大量的请求。Tomcat8在Linux系统中默认使用这种方式。Tomcat7必须修改Connector配置来启动。 NIO最适用于“高并发”的业务场景,所谓高并发一般是指1ms内至少同时有成百上千个连接请求准备就绪,其他情况下NIO技术发挥不出它明显的优势。
3. Regular 我怎么觉得,凡是高并发请求的系统都适合本节讲的高性能模式?!
作者回复:
高并发需要根据两个条件划分:连接数量,请求数量。
1. 海量连接(成千上万)海量请求:例如抢购,双十一等
2. 常量连接(几十上百)海量请求:例如中间件
3. 海量连接常量请求:例如门户网站
4. 常量连接常量请求:例如内部运营系统,管理系统
你再尝试分析一下看看😃
网友补充:
颛顼:
为什么门户网站是海量连接,常量请求?一个http请求不是对应一个连接的
张莹莹 > 颛顼:
作者的意思应该是门户网站访问人数多,但都是低频访问
不算帅 > 颛顼
HTTP 有keep-alive, 一定时间内对同一个域名的二次请求浏览器默认是连接复用的。 连接会保持,所以大体上终端的数量决定连接的数量,请求频率对连接数的影响有限
4. W_T 老师在文章和留言里已经透露答案了。 首先,PPC和TPC能够支持的最大连接数差不多,都是几百个,所以我觉得他们适用的场景也是差不多的。 接着再从连接数和请求数来划分,这两种方式明显不支持高连接数的场景,所以答案就是: 1. 常量连接海量请求。比如数据库,redis,kafka等等 2. 常量连接常量请求。比如企业内部网址
作者回复: 回答正确😃😃
个人追减的评论,有问题:
你好,有个问题想请教下,关于常量连接海量请求,比如数据库,这个怎么理解? 是指业务服务器连接数据库时,这个连接数是常量级?这个连接是可以复用的?不然数据库常量连接海量请求,怎么理解呢?
另外,如果有海量用户同时访问,业务服务器的连接应该也还是海量的,请求也是海量, 此时单台数据库服务器会报to many connections【mysql 8.0支持最大的连接数是10w】错误吧,解决办法是什么呢?
读写分离?分散访问【写访问主服务器,读访问从服务器】压力,一主多从,将海量连接分散到不同的db server,如果一主也没办法解决,这个问题,接下来就是分库分表,拆分到不同的server上,从而再次分散访问压力,总的可以支持的最大连接数也变大,请求数也变大了。
一直不太清楚,连接与请求,与进程/线程之间的关系,有知道的同学麻烦赐教下, 不过确实应该好好阅读下老师推荐的《unix网络编程》~
5. 正是那朵玫瑰 根据华仔回复留言的提示,分析下 1. 海量连接(成千上万)海量请求:例如抢购,双十一等 这样的系统,我觉得这讲所说的模式都不适应,面对海量的连接至少要使用IO复用模型或者异步IO模型,针对海量的请求,无论使用多进程处理还是多线程,单机都是无法支撑的,应该集群了吧。 2. 常量连接(几十上百)海量请求:例如中间件 常量连接,我觉得这讲的模式应该可以适用,如使用TPC的preyhtead模型,启动几十上百的线程去处理连接,应该问题不大吧,但是老师举的列子是中间件是这类系统,我就有点疑问了,是不是中间件系统都可以是阻塞IO模型来实现,比如activemq既支持BIO也支持NIO,但是NIO只是解决了能处理更多的连接,而真正每个请求的处理快慢还得看后面的业务的处理;而阿里的rocketmq也是使用netty这样的NIO框架实现的。但在面对常量连接的场景下,NIO并没有优势啊。 3. 海量连接常量请求:例如门户网站 这种系统我觉得非常适合使用netty这样的NIO框架来实现,IO复用模型可以处理海量的连接,而每个连接的请求数据量会很小,处理会很长快,如华仔说的门户网站,只要简单返回页面即可。 4. 常量连接常量请求:例如内部运营系统,管理系统 这种系统,本讲的模式就很适合了。
水平有限,望华仔指点下。 作者回复: 写的很好,你的疑问补充如下: 1. 常量连接模式下NIO除了复杂一点外,也没有缺点,因此也可以用。
2. 海量连接情况下,单机也要支持很多连接,不然集群成本太高
6. peison 请教一个比较小白的问题…为什么说门户网站是海量连接常量请求的情况?海量连接下为什么会常量请求,一直想不通
作者回复: 海量连接:连接的用户很多 常量请求:每个用户请求数量不多,大部分都是看完一篇文章再去点击另外的文章
7. 孙晓明 李老师,看完文章后查了一下bio和nio,还有一种aio,看的不是太明白,能麻烦您解答一下,并且它与nio的差别在哪里?
作者回复:
BIO:阻塞io,PPC和TPC属于这种 NIO:多路复用io,reactor就是基于这种技术 AIO:异步io,Proactor就是基于这种技术
补充:
BIO:Blocking IO
NIO:Non-blocking IO
AIO:Asynchronous IO
8. LakNeumann 大神, ……纯新手感觉这里读起来已经有点吃力了 ~ 好难啊
作者回复: 这是操作系统基础,可以看看《UNIX网络编程 卷一》
9. 无聊夫斯基 我无法想到ppc比tpc更适合的场景
作者回复: tpc异常时整个服务器就挂了,而ppc不会,所以ppc适合数据库,中间件这类
网友补充:
王二北
突然明白了ngx等为什么要用多进程,而不是多线程
°Magic
可以参考一下nginx的实现
10. 胖胖的程序猿 1. 海量连接(成千上万)海量请求:例如抢购,双十一等 2. 常量连接(几十上百)海量请求:例如中间件 3. 海量连接常量请求:例如门户网站 4. 常量连接常量请求:例如内部运营系统,管理系统 这个不理解,连接和请求有什么区别
作者回复: 一个连接就是TCP连接,一个连接每秒可以发一个请求,也可以发几千个请求
个人问题:
William Ning
这个连接是客户端的同一个进程/线程吗? 不同进程/线程能否复用连接?
11. 孙振超 本章中提到的几个概念,比如阻塞、非阻塞、同步、异步以及主要的两种方式ppc和tpc,以前都是记住了,今天通过这篇文章是理解了而不再是记住了。 ppc和tpc都是有一个进程来处理链接,收到一个请求就新创建一个进程或线程来处理,在处理完成之前调用方是处于阻塞状态,这种机制决定了单机容量不会太大。 但在文章中提到数据库一般是ppc模式,但数据库通常是连接数少请求量大的场景,为什么会采用这种模式呢?reactor模式为什么不适合数据库?还望老师解惑,多谢!
作者回复:
数据库连接数少请求量大,所以单线程或者单进程io轮询性能也高,因为一直都有数据处理,不会浪费时间阻塞等待,但数据库的引擎可以是多线程或者多进程,也就是说一条连接的请求交给引擎后,引擎可以是多线程来处理。
reactor适应于连接数很大但活动连接并没有那么多的场景,例如互联网web服务器,reactor功能上也可以用于数据库,只是关系数据库都是历史悠久,久经考验,没有必要把原来的模式改为reactor
12. 云学 希望再多写几篇讲解单机性能优化,比如线程模型,数据库,网络等,猜测下一篇讲IO复用了吧
作者回复:
具体的技术细节点好多,专栏聚焦架构。
一些常见的细节点如下: java:推荐看disruptor的设计论文,包括false sharing, 并发无锁,ring buffer等; 网络:tcp_nodelay,NIO; 内存:内存池,对象池,数据结构 存储:磁盘尾部追加,LSM;
13. Hanson 如果针对自内部系统,是否使用长链接性能损耗较低,毕竟频繁建链拆链性能损耗还是不小的,尤其是TLS的情况下
作者回复: 内部系统长连接多,例如各种中间件,数据库
14. 文竹 PPC适合对稳定性要求高,但并发量不大的场景,对于互联网的场景不适合。 TPC支持的并发量大,适合互联网产品场景。对于支持稳定性,需要创建冗余进程。
作者回复: TPC支持的并发量也不大呢
15. 大光头 高吞吐和高稳定是互斥的,如果要高吞吐就要采用prethread模式,如果要高稳定就需要高preprocess,如果要综合,线程进程同时
作者回复: 这就是apache的其中一个模式,线程进程结合
16. 星火燎原 像您说的这种多进程多线程模式好似更加稳定,但是tomcat为什么采用单进程多线程模型呢?
作者回复: tomcat是java语言开发的,java用线程是最好的
17. DFighting 看大家的评论,对aio、bio和nio讨论的比较多,我也来凑个数: 请求到达服务器到最终处理完毕可以分为3个过程,接受请求+系统处理+结果返回,其中需要切换线程写作的是请求接受后,在系统处理这段时间,连接线程如何做: bio:阻塞调用等待系统处理完毕 nio:不阻塞调用,不断查询结果,其实从结果上来看依然是阻塞等待的一种,只不过是主动点 io复用:一个连接同时处理多个io请求,本质上还是阻塞,不过由多个线程同时阻塞等待转为一个线程阻塞,等待多个io调用结果 aio:连接请求和处理请求完全异步,连接交给系统处理以后,我就可以去处理下一个连接,等待系统处理结果完毕以后,发送消息或者信号异步发送结果返回 其实从本质以上来看,阻塞和非阻塞这两种性能差异感觉不大,多路复用虽然也是阻塞但是它复用了阻塞线程,提高了性能。异步io才是真正实现了连接线程和系统处理线程的并发执行。 以上是我自己的了解,如有不正确的地方,欢迎指正和探讨
作者回复:
异步io性能相比io复用没有明显优势,但操作系统设计比较复杂,目前来看:Linux上主流的是epoll io复用,windows上是IOCP的异步io
18. 咬尾巴的蛇 很感谢分享,我想问下 就是我开一个tomcat,支持tcp请求,然后什么都不做处理,同时有几百个请求是后面连接就进不来了吗,我是新手才开始架构这块,希望能帮忙解释下,非常感谢
作者回复: tomcat应该不是ppc的模式,如果你找一个ppc的服务器,连接满了后新的连接进不来,但旧的连接发送请求是没问题的
19. 网友-互联网老辛 单台数据库服务器可以支撑多少并发?单台nginx 可以支撑多少呢
作者回复: nginx反向代理可以达到3万以上,具体需要根据业务和场景测试
个人补充问题: 请问,这个并发是指并发连接还是并发请求呢。 另外,关于连接超时,这个通常是由谁来做控制呢? 网友-熊猫酒仙 单方close和双方close应该是全双工与半双工的区别,连接仍然还存在的。 ppc/tpc比较适合系统中担当路由器或容器角色的部分,像nginx,甚至像mongodb集群也有router。 感觉一些部署容器的线程池,应该属于tpc范畴!
作者回复:
close是减少文件描述符引用计数,当socket的文件描述符引用计数为0时,操作系统底层会执行连接关闭操作,全双工和半双工是shutdown操作。 路由器恰恰不适合ppc/tpc,nginx也不是这种模式
20. 琴扬枫 老师好,请教个问题,文中提到的几百连接是在什么样的软硬件环境参数下面呢?谢谢
作者回复: 常见的服务器配置就可以,16核16g以上
21. 落叶飞逝的恋 几百连接的这种性能只适合内部管理系统之类。
作者回复: 中间件也可以,例如数据库,缓存系统等
22. undefined 请教下,PPC和NIO在同一台服务器上是否可以混合使用?redis用单线程处理IO请求时使用多路复用技术,日志持久化时某些操作会fork子进程来实现异步。关于redis单机高性能的设计跟今天的课程接合起来,是否可以简述一下?
作者回复: PPC和NIO不会混用,PPC是指Process Per Connection,不是说用了多进程就是PPC,而是说用进程来处理连接才是PPC。 所以redis用fork来创建持久化进程不是PPC。
23. 钱 课前思考及问题 1:啥是PPC?它怎么提高性能的? 2:啥是TPC?它怎么提高性能的? 3:还存在XPC吗? 课后思考及问题 1:今天讲的知识,感觉是自己的知识盲点,不是很了解。 2:文中核心观点 2-1:高性能架构设计主要集中在两方面: 一是,尽量提升单服务器的性能,将单服务器的性能发挥到极致。 二是,如果单服务器无法支撑性能,设计服务器集群方案。 2-2:架构设计决定了系统性能的上限,实现细节决定了系统性能的下限。 2-3:服务器高性能的关键之一就是服务器采取的并发模型,并发模型有如下两个关键设计点: 服务器如何管理连接,和I/O模型相关,I/O 模型:阻塞、非阻塞、同步、异步。 服务器如何处理请求,和进程模型相关,进程模型:单进程、多进程、多线程。 详情需参考《UNIX网络编程》《NUIX环境高级编程》《LINUX系统编程》 3:PPC 是 Process Per Connection 的缩写,其含义是指每次有新的连接就新建一个进程去专门处理这个连接的请求,这是传统的 UNIX 网络服务器所采用的模型。 这里没太明白老师讲的是网络通信的通用I/O模型,还是指UNIX特有的,感觉没讲全,也没讲出它怎么实现单服务器的高性能的? 4:TPC 是 Thread Per Connection 的缩写,其含义是指每次有新的连接就新建一个线程去专门处理这个连接的请求。与进程相比,线程更轻量级,创建线程的消耗比进程要少得多;同时多线程是共享进程内存空间的,线程通信相比进程通信更简单。 5:这块知识差的太多了,感觉听完老师的讲解,发现自己对于进程、线程、子进程、子线程、怎么阻塞的、怎么唤醒的、怎么分配内存空间的、怎么被CPU执行的、网络链接怎么建立的、进程怎么切换的、线程怎么切换的、一个请求怎么发送怎么处理的怎么返回的、长链接怎么保持的这些东西的具体细节都不太清楚。惭愧啊!知耻而后勇,我一定把这些补上来!
作者回复: 加油
24. 衣申人 有个疑问: 看ppc和tpc模式,最后都是服务器write之后就close,意思是这两种模式都不支持长连接?
作者回复: 都支持长连接,循环read-处理-write,图中write后可以继续read
25. Hook 老师,我使用 Netty 开发了一个 Java 网络应用程序,是一个长连接的场景。我使用 CentOS、14G 内存、2 个CPU,经过测试发现最高能支持 3 万个并发长连接。 在这 3 万个长连接场景下,CPU利用率大概在 65%左右,而内存剩余不到 2 个G。 这个结果,与网上很多文章介绍的,轻轻松松就能支持百万长连接例子相差很大啊。 结合老师的经验,我这个结果能打几分呢?能给一些优化的方向吗?
作者回复: 轻松百万是假的吧?这个结果已经是正常结果了
个人观点:
想问下,从上面的结果来看,cpu的利用率并不是很高,也就是cpu并不是限制因素,至于内存,似乎成了限制因素,但是似乎并不是最主要的限制因素,最主要的限制因素,是网络带宽吗?
26. 天外来客 主要考察连接数,因单机的fd 是有限的,可根据并发连接数考虑是否部署集群!
作者回复: fd不是关键,关键是进程或者线程数量太多,所占资源和上下文切换很耗费性能
27. 肖一林 对于客户端不多的情况下,可以长连接。对于客户端海量的情况下,只能短连接,还要控制瞬时连接数?反正都要适应ppc和tpc,对吧
作者回复: Reactor,Proactor都可以处理海量长连接
28. 辉 Prethread为啥不用线程池
作者回复: 具体实现可以做成线程池,但线程池涉及到不同连接复用线程时的资源共享问题,处理会复杂一些;如果一个线程只给一个连接用,连接关闭就结束线程,新连接用新线程,实现起来很简单
29. 网友-siwei 同一页面发起多次ajax请求是一个连接还是多个连接?
作者回复: ajax发的是HTTP请求,所以你要看你具体的HTTP协议版本是1.0还是1.1还是HTTP/2
个人补充:
持久连接在 HTTP/1.1 中是默认开启的,所以你不需要专门为了持久连接去 HTTP 请求头设置信息,如果你不想要采用持久连接,可以在 HTTP 请求头中加上Connection: close。目前浏览器中对于同一个域名,默认允许同时建立 6 个 TCP 持久连接。
极客时间,使用的http协议基本都是1.1 和 2.0, 打开开发者工具,查看network就可以知道,另外,也可以看到很多请求走的是统一连接,从Connection ID就可以知道。
|