这麽热闹!我来转帖一篇CSDN的文章,大家可以看一下。不要局限于DELPHI和WIN,关键是
思想!最后,CSDN的回复是由下往上的,看错了顺序你会不知所云的。
这是正在写的一本书的大纲,先发出来,大家提点意见
高性能服务器软件开发
关于这本书的简单介绍:
注意,在这里我们讨论的高性能服务器软件设计并不是通常意义上的高性能Web程序设计,比如说在J2EE、.NET框架下如何使用线程池提高性能,如何优化ASP,PHP程序,或者如何调整Apache,IIS等Web服务器以获得更好的性能等等。
这里讨论的是真正高性能的从硬件到操作系统底层,然后到IO模型、应用模型的服务器设计,当然,作为一家之言,里面同样充满了误解、偏见和无知,但是在指责我之前,请仔细思考你指责的理由,进行仔细的测试之后把你的完整意见告诉我,我会很感谢这种建设性的指责而不是其他。
我们面临的问题
目前已经存在,而且将会越来越多的大量网络应用,它们包括:
即时聊天服务器
FTP服务器
基于互联网的媒体应用
大型购物网站
大型门户网站
在线网络游戏
而在实际使用的时候,我们经常碰到下面的情况:
连接数过多,网站无法访问。
无法下载文件,或者下载速度非常缓慢
同时连接的数量受到很大限制。
站点非常脆弱,经常受到这样那样的攻击而瘫痪。
对于这些情况,通常的解决方案是:
增加硬件的性能
使用服务器集群和负载均衡技术
更大的带宽
这些真的需要吗?
我们有没有仔细的思考我们的硬件本身的限制,操作系统的限制,我们的应用程序的限制,真正的瓶颈在哪里?
让我们首先来看一看基本的c/s网络应用。
基本的客户/服务器网络应用系统:
第一类 非基于连接的系统
电子邮件,百万级的,使用的频率有限,同时访问的用户有限,连接的数量受到限制
即时聊天、视频或者其他在线媒体
这些系统有自己的功能限制。
基于连接的静态系统
ftp下载
http访问
基于连接的动态系统
包括动态页面的Web 站点,动态的内容和用户无关
包括用户的概念以及用户相关数据的系统,经常有一个后台数据库。
包括业务逻辑的系统,例如电子购物站点,信息港,以及最近流行的在线游戏。
根本的问题是什么
如何以尽可能少的CPU 时间,内存占用,支持更多的网络连接,发送/接收更多的数据。
从下往上系统的根本构造包括:
1. 硬件设施:包括CPU 的计算能力,硬盘、总线的带宽,网络设施的吞吐能力。
2. 操作系统:操作系统对并发连接的支持和开销,操作系统的IO开销
3. 网络应用模型:基本的网络IO模型,事件通知的机制
4. 应用模型:结合实际应用的应用系统设计
5. 编码和实现:好的编码和差的实现之间的差别是非常巨大的,在这里我提出一些可能有偏见或者偏激的看法。
1,2硬件设施和操作系统的开销比较。
我们将1,2结合起来进行比较:
选择下面一些基本的硬件平台:
典型的笔记本电脑,P4M平台,100M网卡,512M内存
典型的台式机,P4平台,100M网卡,512内存
典型的服务器,xeon平台,千兆网卡,1G内存
典型的AMD64位服务器,千兆网卡,1G内存
软件系统包括:
Windows系统:
Windows2000 Profession
Windows2000 Advance Server
自由的Unix类系统:
Linux 2.4内核
Linux 2.6内核
FreeBSD5.1内核
主要的性能评估包括:
影响服务器性能的操作系统的基本调用评估
l 分配/释放内存的开销
l 创建/中止线程/进程的开销
l 互斥锁的开销(上下文切换的开销)
l 内存映像文件的创建/读写开销
操作系统网络性能的基本评估
l 套接字的创建/释放开销
l 套接字的绑定开销
l 建立网络连接的开销
l 发送数据/接收数据的吞吐量
l 一次标准HTTP请求/响应的延时和开销。
初步的结果表明,硬件方面,Xeon系统显然超过了通常的笔记本和台式机,而AMD 的64位系统在较低的主频下有非常好的性能表现(我们仍然使用32位软件进行测试)。而操作系统方面,所有的类Unix系统都全面超过Windows平台,而Linux2.6内核是各个平台中表现最好的。
网络IO模型的设计和评估:
基本概念,操作系统采用何种方式通知应用软件应该去某一个套接字上获取数据或者发送数据。
最简单的办法,采用轮询的机制循环检查套接字的状态,在很多时候,这种方式的效率反而最高。
轮询方式具体的应用范围:
其次,使用每个连接一个线程的方式,这种方式可行性决定于
操作系统可以使用线程的数量
操作系统线程创建和线程间切换的开销。(初步的测试表明,linux2.6内核每秒可以创建5000以上的线程)
两种基本的消息触发方式:
条件触发和边沿触发
常见的select就是条件触发。
Window平台:
包括常见的Select模型
event select模型
IO完成端口模型,实际上就是一种边沿触发的机制。
Linux平台
基本的select模型,最大的问题在于寻找哪一个socket上面发生的事件(socket的本质是文件句柄,所以数量巨大)
边沿触发:
2.4内核推荐的实时信号模型
2.6内核推荐的epoll模型
FreeBSD
基本的select模型
边沿触发的kqueue模型
性能评估:
基本的测试表明,在同时并发连接数量,每个连接的延时和吞吐量上,Linux 2.6内核都是胜利者,其性能显著超过了2.4内核以及FreeBSD。所有的类Unix系统都将Windows系统远远抛在后面。在各种IO模型的比较下, linux2.6内核的epoll同样成为胜利者,而IO完成端口仍然是最后一名,显然,对易用性和图形性能的要求使得Windows并不适合作为一个服务器端的操作系统。
应用系统的模型:
基本的Web服务器:
1静态页面的提供:
内存映像文件
直接文件发送,减少了文件的数据从核心拷贝到应用层然后再拷贝到核心的开销
在Windows和Linux环境下都有相应的系统调用。
核心服务器,直接在核心完成基本的HTTP服务:
khttpd
2动态内容的提供:
基本的硬编码方式提供动态页面
使用简单的应用程序密切相关的脚本语言,
使用通用的脚本语言:
高性能的LUA
高性能但是过于庞大的Java
其它脚本语言PHP,ASP等等。
3 数据库系统
本地存储还是通过网络访问数据库服务器?
Oracle、Sybase、SQL Server和其他的数据库服务器
mySQL、mSQL、Postgres等open source数据库服务器
本地:
Berkely DB
如果不需要复杂的事务处理和恢复功能,可以使用简单高性能的,基本B *Tree存储机制。
4 J2EE和.NET框架,复杂性的好处和代价。
其他应用服务器:
数据库应用
在线游戏
流媒体播放,RTP和其他并不广为人知的协议
下一代应用?P2P和BT
新的思路,带来的好处,当然也会由此带来新的问题:
可能对整个互联网带宽和流量的影响
可能带来的法律问题
下面该看看应用系统了,好的设计同样是非常重要的:
真正高性能的程序设计
more small, more fast
more simple, more fast
更小的代码更快
更简单的代码更快
现代计算机的体系,速度往往取决于CPU cache 的命中情况。
因此,更小、更简单的代码往往会获得更好的性能。
l 删除冗余代码,和一般理解相反,放在那里不动的代码即使没有使用也会影响系统的性能。
l 不要低估或者高估编译器的优化,除了代码本身所能提供的信息以外,编译器永远不知道你到底要做什么。
l 不要梦想复用,在代码级重复使用你代码的可能性接近于0
l 层层的封装是效率的杀手
l 动态运行时解析,类型….带来的问题远远大于所承诺的好处。
l 专用、专用再专用,把你的代码限制在一个非常具体的场景中,通用的代码往往意味着低效、潜在的误用和其他错误。
l 不要做期待之外的事情,所有的bonus都是要付出代价的!
l 优化最常见的情况,而不是最糟糕的情况。
l 内存分配和释放是非常昂贵的操作(从时间上,稳定性上都是)
l 不要想象,使用工具观察你的代码,vTune或者gProf等等,只有这样才能发现真正的瓶颈所在。
对该文的评论 人气:9545
hsia (2003-12-14 16:16:56)
我同意楼主的看法。 6、7年前,就曾有人说,机器性能在不断提高,不要在乎那一点效率。事实上,到今天,格局仍然依旧。如果不借助pro C,数据库的应用仍然慢如牛车。举一个例子,某省的连通公司,每月计算用户资费,需要3天多的时间,几百万的用户数,涉及到的数据充其量也不会超过10亿条,亏他们能做得出来。数据库仍然是很慢的,于是,所谓3T架构流行起来,似乎加上线程池、加上集群,就能解决问题。殊不知,结构的复杂只能是效率的进一步下降。简单想一下,原来是两个人对话,现在中间加上一个人(翻译),对话的效率是提高了还是降低了?不要美国人说C/S好,大家都C/S;美国人说B/S/D,那么OK大家都来B/S/D。做软件的人,有几个?什么时候?用你自己的头脑思考呢?
chenhaono1 (2003-12-13 14:15:52)
倘若按照SnowFalcon的 "如果应用是需要需要毫秒级的定时,修改系统调用(在kernel/timer.c中),使其定时单位变为毫秒。也就是相当于让一个进程变成一个分片式的任务调度系统,这样的好处是你可以控制某个任务需要调度多少时间。" 那么程序的运行时间不照样由操作系统控制, 尽管可以设置程序的调度优先级,可以mlock()内存. 但是进程的信号是在内核快返回时检查进程的信号位来实现的, 这样一来就免不了要有上下文的切换. 众所周知进程上下文的切换是昂贵的, 而线程的切换相对开销小. 那仅仅为了在自己的控制下采用上述做法是不合适的.
minzheng (2003-12-12 13:22:24)
我觉得楼主的测试应该有问题,我用MSDN的例子在我的机器上测试,1500个连接,cpu还是很低的。通讯性能我没有跟Linux比较过,当我个人认为相差应该不大吧。当然如果楼主能够提供个你测试例子的代码,我们大家看看,如何?我对这个帖子的题目很有兴趣,大家可以一起讨论。
davemin (2003-12-12 10:48:18)
要不大家去改写一下linux内核代码吧。 这样会更理解一些的。
davemin (2003-12-12 10:46:33)
msn 服务器的架构看看就行了。****. 事实为依据, IOCQ 服务器是什么架构的?
SteroWang (2003-12-11 17:46:38)
诸位有没有采用ACE并使用Proactor模式的例子呢?我粗看了它的源代码,Win32平台的Proactor实现用了IO Compoliation Port,很想知道在程序怎么调用,诸位有的话可不可以把地址贴出来或发给我。先行谢过了!
davidprg (2003-12-11 15:35:20)
我做的server在普通p4 ,256mb ram下的测试结果tcp的并发达到8000仍然运行良好,压力测试未做;另外我正在开发的一个game server并发过万运行也比较良好,也是p4机器,win2000下,不过我相信linux下可以获得更高性能。
whidy (2003-12-11 14:25:36)
国内有windows下开发的服务器吗?支持大容量的
wyzegg (2003-12-10 14:10:11)
是这样的吗,服务器的稳定性呢
biny (2003-12-10 10:33:32)
呵呵,很欣赏 SnowFalcon 的话,很多话说的太对了 说到心坎里去了,哈哈
cxu123 (2003-12-10 6:28:47)
Linux中性能最好的FTP服务器 Pureftpd 和 vsftpd 都只为每个FTP连接生成一个线程 =========================================================================== 我写错了,这里应该是每个FTP连接生成一个新进程
cxu123 (2003-12-10 6:21:27)
建议作者看看http://www.kegel.com/dkftpbench/的文章,主要讨论FTP Benchmark。 http://www.kegel.com/c10k.html。The C10K problem,主要讨论各种UNIX 和Windows SOCKET编程模式的不同,e-poll,kqueue 和Window IO Complete Port都有提及,不过好像差别没那么大。 LINUX 线程切换速度很快,所以e-poll用处没有那么大。Linux中性能最好的FTP服务器 Pureftpd 和 vsftpd 都只为每个FTP连接生成一个线程.e-poll,kqueue 虽然看着不错,但是有一个不同UNIX平台兼容性的问题,很少有服务器只在一个UNIX平台或版本上工作的,考虑到这个原因大部分开源的服务器程序还是不用e-poll,kqueue。不同版本兼容性是UNIX 不同Socket模型的最大问题。 实际工作中Window IO Complete Port和Linux差别没有那么大W单看indow IO Complete Port很多情况性能更好,但是Windows 操作系统的其他原因最后抵消掉IO Complete Port 的优势。例如Windows Spleep()只能精度只能到毫秒,线程切换和调度也只能到毫秒,这一点很影响效率,而UNIX下可以到纳秒。因为这个原因Windows线程切换开销好像比LINUX进程切换开销大,在Windows里一个连接一个线程肯定是不行的。
cxu123 (2003-12-10 6:20:15)
建议作者看看http://www.kegel.com/dkftpbench/的文章,主要讨论FTP Benchmark。 http://www.kegel.com/c10k.html。The C10K problem,主要讨论各种UNIX 和Windows SOCKET编程模式的不同,e-poll,kqueue 和Window IO Complete Port都有提及,不过好像差别没那么大。 LINUX 线程切换速度很快,所以e-poll用处没有那么大。Linux中性能最好的FTP服务器 Pureftpd 和 vsftpd 都只为每个FTP连接生成一个线程.e-poll,kqueue 虽然看着不错,但是有一个不同UNIX平台兼容性的问题,很少有服务器只在一个UNIX平台或版本上工作的,考虑到这个原因大部分开源的服务器程序还是不用e-poll,kqueue。不同版本兼容性是UNIX 不同Socket模型的最大问题。 实际工作中Window IO Complete Port和Linux差别没有那么大W单看indow IO Complete Port很多情况性能更好,但是Windows 操作系统的其他原因最后抵消掉IO Complete Port 的优势。例如Windows Spleep()只能精度只能到毫秒,线程切换和调度也只能到毫秒,这一点很影响效率,而UNIX下可以到纳秒。因为这个原因Windows线程切换开销好像比LINUX进程切换开销大,在Windows里一个连接一个线程肯定是不行的。
xiaha3 (2003-12-9 23:02:24)
有一个想法;那就是如果应用程序尽量不使用操作系统提供的功能,同样的硬件平台,不同的操作系统上的效率可能一样;同样可以实现高性能
lesstif (2003-12-9 11:38:06)
我欣赏有研究精神的同志!!!好,其实,我个人也在进行研究,虽然跟你的方向不一样,祝成功。 顺便说一句,如果你写成书出版,我一定买!!!
emilchan6k (2003-12-9 7:54:12)
SnowFalcon是强人~
CSDN010 (2003-12-8 15:01:47)
微软系统一直是效率低下,不能登大雅之堂的形象。随着近年来越来越多的国外报道,才知道微软也是电信、军队、银行、政府等的重要软件提供商。下例是Windows2000系统为美国著名计费软件厂商提供超过2500万用户系统容量计费系统的报道,在电信领域微软取得成绩之迅速,不得不令人为之侧目。 全球领先的计费和用户管理软件供应商美国 Portal 软件公司与微软公司日前宣布携手合作,确保世界各地电信运营商把服务、设备迅速地提供给顾客,并进行高效准确的管理和计费。双方将把 Portal 获奖的计费和用户管理软件平台和微软的.NET 技术整合起来,为通信业提供 .NET 连接解决方案,使服务提供商能够迅速提供新的语音、数据和内容服务,同时为传统和 B2B 集成提供卓越的支持,协助缩短时间,降低成本。 服务供应商致力于向客户提供全新服务,例如多媒体短信,IP电话以及提供更强大的互联网互动能力的设备。但是,它们往往都隐藏在组成其运营及业务支持系统的网络元素的后面。由于共同认识到 Web 服务将如何影响业内应用,微软和 Portal 开始联手提供 BillingAgility 解决方案。该解决方案可以使服务提供商对新的服务进行计费,同时可避免升级或开发新代码以增强原有功能时带来的重复成本。 使用 Web 服务,BillingAgility 是一种可扩展的高性能解决方案,专为满足服务供应商对计费和用户管理的要求而设计,同时亦支持未来的新服务。这种解决方案将 Portal 的 Infranet 软件和微软的 Windows Server 2003、SQL Server 2000 和 BizTalk Server 结合起来,向客户提供无与伦比的灵活性和出众的性能以及更低的总体拥有成本。 · 无与伦比的灵活性。BillingAgility 具有无与伦比的灵活性,客户可使用第三方应用软件轻松地更改复杂的计费系统和界面。BillingAgility 采用 Web 服务标准,比如 XML 和 SOAP, 使之可以与其它传统应用和系统更快速,更简单地集成,并且可以方便服务供应商迅速建立内容合作伙伴网络。例如,CRM 或一般分帐户系统与 BillingAgility 的无缝数据连接只要求先前应用程序50%的资源。 · 一流的性能。BillingAgility 是一个建立在微软 Windows Server 2003(64位)操作系统之上的计费和客户管理解决方案,采用 SQL Server 2000 企业版(64位)。服务提供商使用 64 位架构和 BillingAgility 将可以支持超过 2500 万用户并加快计费进程。这将大幅减少支持运行和管理任务关键型应用程序所需硬件的数量,满足世界一级运营商的处理要求。 · 降低总体拥有成本。Portal 基于产品的解决方案模式和微软基于技术的计算平台相结合,进一步为客户降低总体拥有成本。BillingAgility 通过缩短实施时间并降低维护成本为电信运营商带来极大的竞争优势。 Portal 软件公司简介 Portal 软件公司的客户包括中国电信、中国吉通、中国移动、沃达丰、中国铁通、路透社、美国在线时代华纳、香港电讯盈科、日本电报电话公司(NTT)、台湾远东传信、Telstra、Sprint 和法国电信等。 Portal 软件公司总部位于美国加利福尼亚州的 Cupertino,目前在亚太地区的北京、香港、东京、悉尼、新加坡、汉城、台北和墨尔本等地设有办事处。
ddddh (2003-12-8 9:54:55)
性能评估: 基本的测试表明,在同时并发连接数量,每个连接的延时和吞吐量上,Linux 2.6内核都是胜利者,其性能显著超过了2.4内核以及FreeBSD。所有的类Unix系统都将Windows系统远远抛在后面。在各种IO模型的比较下, linux2.6内核的epoll同样成为胜利者,而IO完成端口仍然是最后一名,显然,对易用性和图形性能的要求使得Windows并不适合作为一个服务器端的操作系统。 ===================== 这是怎么回事?没有看到测试方案,没有看到测试数据,但是看到了测试结论! -------------------------- 俗称是“托”?
xkak2 (2003-12-8 9:37:11)
性能评估: 基本的测试表明,在同时并发连接数量,每个连接的延时和吞吐量上,Linux 2.6内核都是胜利者,其性能显著超过了2.4内核以及FreeBSD。所有的类Unix系统都将Windows系统远远抛在后面。在各种IO模型的比较下, linux2.6内核的epoll同样成为胜利者,而IO完成端口仍然是最后一名,显然,对易用性和图形性能的要求使得Windows并不适合作为一个服务器端的操作系统。 ===================== 这是怎么回事?没有看到测试方案,没有看到测试数据,但是看到了测试结论!
lbaby (2003-12-7 6:01:04)
看的好舒服...
hustzhuch (2003-12-6 17:37:40)
好文,好强!
hao_yufei (2003-12-6 16:53:03)
插一句题外话: more small, more fast more simple, more fast 是否应该写成: smaller, faster simpler faster
sunhuiNO1 (2003-12-5 20:09:11)
zhuchuanjing: 我用IOCP测试的时候虽然才1000个客户端但是压力相当大,只要服务器处理完这个线程的请求,客户端马上发新的请求过来,CPU占用率极高 2只强P4 2。4G,2G内存的机器的CPU占用率到了80%以上,测试了3个效率仍然没有出现任何问题。看来你所谓的不稳定估计是你对IOCP的理解不够深刻,怪不得去搞Linux开发啊
MHB (2003-12-5 19:48:30)
more small, more fast more simple, more fast 》这是什么话?不开发速度更快, (初步的测试表明,linux2.6内核每秒可以创建5000以上的线程) 》那 windows每秒可以创建多少个呢? 不要告诉我只能创建5000以下。 性能评估: 基本的测试表明,在同时并发连接数量,每个连接的延时和吞吐量上,Linux 2.6内核都是胜利者,其性能显著超过了2.4内核以及FreeBSD。所有的类Unix系统都将Windows系统远远抛在后面。在各种IO模型的比较下, linux2.6内核的epoll同样成为胜利者,而IO完成端口仍然是最后一名,显然,对易用性和图形性能的要求使得Windows并不适合作为一个服务器端的操作系统。 》作者,你对windows知多少?对linux又知多少?你的这些数据从那里来的?你的开发经验?你开发的资质有多深(比我强是肯定的)?
ft,就是叫linux祖师爷来都不敢说这句话。
MHB (2003-12-5 19:33:49)
作者,你是一个很好玩的人。
ddddh (2003-12-5 17:17:46)
这方面没什么经验不敢乱说话 不过这个贴的回复比较精彩 希望发表评论的人,用数据来说话 不要用猜的,那样没意思。
hx (2003-12-5 17:03:42)
很可能是这么来说, LINUX下数据库,更优秀! WINDOWS下数据库,影响到了系统资源。
hx (2003-12-5 16:44:27)
CACHE是很重要。。代码大小,也很重要。。。但开发进度,更重要!关于LINUX和WINDOWS,你在WINDOWS的字符界面下,进行过比较吗????我也同意进行和2003的比较。我看到的IOCP,性能,还是很不错的。。我也相信,LINUX的性能。。。但决到不是轮询!!!线程之间切换,也是很费资源的!!!你没有数据出来的话,请不要误导大家。!!!因为,很容易一些,没有做过,没有经历过的新人,会被你带入误区,那样的话,你这样,比一般的刑事犯罪还罪犯!做事情之前,要先负责!!!!!先去看看三个代表,不过,对你所提出的 more small, more fast more simple, more fast 和前面一些观点,很认同。
zhuchuanjing (2003-12-5 14:20:05)
你的测试里面,每两秒钟发送一次数据,远远没有到达带宽的上限,我测试的例子有两点不同: 1实际数据发送和接收基本上占用了所有的带宽,100M的网络超过10M字节/秒 2广域网的应用环境,存在大量的不稳定连接,TCP的滑动窗口重发的次数非常大。我想在这种情况下的性能和你局域网的测试应该有很大不同
TNSW (2003-12-5 9:32:49)
我最近刚刚完成了一个用windows完成端口实现的服务器。下面是我的测试数据:机子: p4 2.4G 512M SCSI30G 内存带宽533 数据库和服务器软件运行在同一台计算机机上,每个客户端连接每隔2秒发送一次数据,服务器软件要把数据保存到数据库并得出这个客户端已经有多少条记录。在四台计算机上同时连接了2000个客户端,服务器的CUP占用率为50%,实际上大部分CPU是被SQL SQLERVER数据库占用了,测试进行了一周,没有任何问题。我们一开始也遇到很多问题,最后才发现原来是自己对完成端口理解得不够。
softeye (2003-12-4 20:14:56)
实时应用的高性能和一般服务应用的高性能不能做比较,几乎就是不同的设计方向和设计语境。
shujian (2003-12-4 14:54:26)
SnowFalcon兄关注: 与SnowFalcon兄探讨问题 To SnowFalcon: 摘录的原话:你相信Java程序会有内存泄漏么?你相信一个程序的一个星期内高效工作,但是 下个礼拜一就因为内存碎片而慢的象乌龟爬么?你相信一个java程序会应为几千 个thread而导致每个连接需要用10秒钟来完成connect么?你相信因为使用了一个 visitor/obersver模式而把整个服务器的速度拖垮么?很多在平时看上去非常良好的设计,一旦更换到highperformance就是bullshit。而 且最为危险的是,最后的性能问题出在整个设计结构上。 shujian: 其实Java程序也会产生内存泄漏的问题,但JAVA所公开的文档上其实蒙蔽了我 们。我不知道SnowFalcon用什么办法在编写代码的时候自觉得做到把不用的对象进行释放。能给我们一点经验吗?? 我也有写过java的多thread程序,但同时在线的client<10,所以对于性能的测试只是一句空话。很难相信你说的:“你相信一个java程序会应为几千 个thread而导致每个连接需要用10秒钟来完成connect么?” 但我知道这是真的,我更想知道的是,您是怎么解决这个令人头痛的问题。能告诉我吗?? 摘录的原话:因此我认为highperformance的网络程序的一个信条就是永远不要相信操作系统和 语言的特性。最大的隐患就是我们最放心的地方。 shujian: 您说的没错,其实错在我们对操作系统和语言的特性认识的不够深刻 。也只有在屡犯错误的过程中,我们才越来越深刻得认识。才能避免同样错误的发生。你说呢?
metabug (2003-12-4 13:59:56)
对于上面线程与连接数目,还有所谓的并发问题我建议还是多看看tux对这些连接的处理,我采用类似的方法,性能提高了 50% 另外,如果必须使用tcp 连接,最好使用 tcp splicing来解决保存连接中的问题。
metabug (2003-12-4 13:54:37)
对于上面线程与连接数目,还有所谓的并发问题我建议还是多看看tux对这些连接的处理,我采用类似的方法,性能提高了 50% 另外,如果必须使用tcp 连接,最好使用 tcp splicing来解决保存连接中的问题。
wuyg (2003-12-4 9:03:38)
to SnowFalcon: 老兄也太武断了吧:“无论是OO和pattern用于编写程序除了好看以外都没有太大的作用。” 这么多优秀的人才搞出的东西就这么被否决了? 太慢了,好,加机器,搞集群,不是很困难吧?但没有复杂的功能如何满足日益复杂的用户的要求呢?诚然在很多地方为了性能还要妥协,但你也看到了硬件的高速发展,越来越多的地方不需要特别关注性能。我以前在640k的计算机上也用C写过很长时间的代码,也为了节约一些内存和提高一点性能费尽心机,但是时代在不断在变化,上次我看到网上有人说数据库最好的优化方法就是加内存和CPU,虽然搞笑但值得深思。 有句很有名的话“科技以人为本”,我理解的意思是“让机器累死,让人舒服死”,当然这里的人不仅指一般用户,也指程序开发人员和系统维护人员。
SnowFalcon (2003-12-3 23:33:39)
AXE-10和voip是两码事情,axe-10是电路交换自己有硬件来解决时分和空分的。那么你上层用什么都无所谓了,只要性能损耗的不是离谱。pattern的效率问题我是这么看得。任何不好的设计,你当然可以说那是没有用或者没有理解好pattern和OO。任何的好的设计都可以说是领悟了pattern和OO的精髓。无论是OO和pattern用于编写程序除了好看以外都没有太大的作用。扩展性复用性,只不过是一种gambling。能够复用或者能够扩展只不过是随机撞上的而已。Pattern或者OO,与一个软件复用与否没有必然的逻辑联系。既不是一个充分的条件,也不是一个必要的条件.
flyinair2000 (2003-12-3 18:33:31)
To SnowFalcon: 软件的设计和实现一律都是c,void指针的强制转型,old plain strcuture。不要说玩什么pattern之类的东西,就连OO,虚拟都是不允许的。template/stl还可能有用,但是你必须要修改所有的内存分配方式,以内存池代替malloc/free或者new/delete ------------ 据我所知,爱立信AXE-10交换机就是采用的oo设计。(当然,你也可以说它设计的很烂。不过,它的设计师可是个大牛)而中国研制的交换机的比如中兴,多是采用c.其实我认为不是效率问题,而是水平问题。结构设计是最切合人的思维习惯的,解决问题要向前看,不要以为用了pattern就会带来效率问题。(不要告诉我会用C的就是高手,B.J学了一年C就创造了C++)
ychener (2003-12-3 17:46:59)
这篇文章肯定有问题,我想问问楼主是否用过完成端口, 500个并发以上,就分页内存耗尽?? 狗屁! 如果不是作者胡说就是你的系统有问题。
SteroWang (2003-12-3 16:56:31)
非常支持作者能做这么大的一个题材的探索,并且针对这么多的操作系统。在这里给与作者高度的支持。庸勿质疑,在任何时候,无论硬件多么强悍,架构合理的高性能应用开发始终值得探索。在硬件配置相同的情况下,对于大量并发Socket的管理,我认为IO模型的影响最大,编码和实现次之,再是操作系统。编码和实现不大可能有量化的可比性,可假设一个人写的代码差别不大。非常希望作者能用清晰简洁的例子(最好是同一个人所写),保持同样的硬件配置,采取单项比较法,也即保持操作系统相同比较IO模型,保持IO模型相同比较操作系统(操作系统不同IO模型可能不会完全一一对应),在比较的过程中保持客户端不变(操作系统,硬件配置,目标程序都不变),用准确的事实数据阐述自己的观点,这对我们也是最好的参考。还有,Windows2003是否也能包含在比较范围内?刚看到一篇关于Unix类操作系统下的文章,觉的不错,推荐给大家http://www.kegel.com/c10k.html
WalkWorld (2003-12-3 14:38:50)
SnowFalcon: nod,linux 2.6即将可以支持32个处理器了
sunhuiNO1 (2003-12-3 14:38:46)
高性能的网络程序我认为最重要的是带宽,如果带宽不够,你服务器写的效率再高也没用。 10M带宽下的服务器程序写的再好也比不过100M带宽下的普通服务器,就算你开了1000个线程,都用select模式,也就是64000个用户,你算算流量100m/8=12.5M/S,还要考虑网卡工作效率问题,最多到10m/s就极限了,如果是下文件就是10000个用户每个用户才1K/S根本就没有实用性。只要并发支持1000~3000个用户基本上就到了极限了。
SnowFalcon (2003-12-3 14:28:27)
同时处理是不可能的,一块cpu上的thread也不是并发的。只不过看上去并发而已。除非你加cpu.
WalkWorld (2003-12-3 14:16:29)
4000个client可以看作4000个并发的socket。 linux下一个进程能够创建1024个线程,一个线程能够等待64个事件,加入select的速度足够快,是不是可以这样说一个进程能够同时处理1024×64个client?
SnowFalcon (2003-12-3 14:12:26)
4000个没错!就是这么多。其实不能说是一个进程,只不过用时钟中断来作任务调度而已。每个线程归化成一个带有loop的任务,对于某一个运行中的任务,欲使其loop被定时调用的方法是,给这个任务定时发送一个信号,使该任务得到调度,在loop执行结束时,这个任务再将自己阻塞住,等待下一次信号。 Linux提供了一个定时发送信号的系统调用alarm(unsigned int seconds),该系统调用能够根据参数seconds,在seconds秒后发送一个SIGALRM信号给当前进程。如果应用是需要需要毫秒级的定时,修改系统调用(在kernel/timer.c中),使其定时单位变为毫秒。也就是相当于让一个进程变成一个分片式的任务调度系统,这样的好处是你可以控制某个任务需要调度多少时间。超过这个时间任务就pending,如果使用线程那么调度多少时间什么时候调度都是不可控制
bolidecaster (2003-12-3 13:48:11)
用一个进程?里面有多少线程呢?4000个?
kidding.
SnowFalcon (2003-12-3 13:26:21)
4000个客户端,当然不应该用4000个thread.我只要更改一些linux代码,用一个进程就能全部照顾他们。
SnowFalcon (2003-12-3 13:16:20)
VOIP这个名字底下猫腻可是很多的,gateway和softswitch是两个概念,就是gateway里面也有不同,有些只是一个h.323或者sip的解析器,而真正的交换依然是电路交换。市面上很多产品都是这样。一个gateway只完成从PSTN与IP之间的协议转换。而真正意义上的voip是要用软件代替的电路交换。 关于语境的问题:我刚才说过了,能够依赖loadbalance这类的东西来解决性能问题的网络程序很难说是highperformance。 另外,关于trade-off的问题。trade-off是一个大词,它可以表述任何事情但是也等于什么都也没有说。你可以说在开发效率与性能之间的取舍。那么我认为如果说到开发效率,那么因为性能问题而推倒整个设计是不是影响开发效率。即使不是推翻整个设计,为高并发量的程序进行性能优化需要的时间也是相当可观的。高并发的程序的debug,性能调整需要非常高的技巧和耐心。一个bottleneck可能仅仅是几百万行代码中的一语句,有的甚至不是程序的问题而是操作系统本身的问题。就我个人的经验来说,如果不是一开始强调性能那么为这种程序进行性能优化需要的时间可能与开发时间相当。按照一般软件工程的经验,风险越是压后你就要付出更多的代价。在一般的程序设计中性能并不是一个风险,但是highperformance的网络程序中他就是最大的风险。如果你给程序员灌输这样的思想:"开发的时候不要太考虑效率问题,等最后优化的时候再说或者我们可以加cpu,加memorY"。那么这样你就种下了几千个,几万个地雷。可能某些人写出的程序每个函数都有性能问题。而到最后性能优化要挖除这些地雷的时候,你面对的是基本上在重写整个程序。也许kuth那句话:"early optimization is the root of all evils"对于一般的程序来说是对的,但是highperformance的网络程序就应该遵循len latanzi那句话:"belated pessimization is the leaf of no good".
sunhuiNO1 (2003-12-3 12:43:29)
我用完成端口的服务器做压力测试的时候并发1000人,测试一下午,压力相当大,只要服务器处理完了请求客户就接着发请求,服务器上只开了4个IOCP工作线程(其他的密码验证线程什么的不算)一直工作稳定,而且这个服务器程序是开了7天以后测试的,所有的测试都完成的很好,没有发帖子作者说的问题,我估计应该是贴主的IOCP测试代码有问题。
bolidecaster (2003-12-3 12:35:04)
SnowFalcon: trade-off是指对各种因素的权衡考量,不太明白你的意思。
bolidecaster (2003-12-3 12:32:17)
SnowFalcon: 我所说的语境是指与4000这个数目相关的环境、数据。你不能简单地说ACE/TAO在linux RT上同时只能支持4000个client。这没有一点意义。 CUseeMe公司使用ACE和TAO开发了基于软件的H.323 MCU。当然,这和你说的softswitch可能不是一个级别的,但这也恰恰说明了,离开系统需求、离开具体的语境谈论问题是没有意义的。 CUseeMe Networks, Inc use ACE and TAO in their CUseeMe Conference Server, a software-based H.323 MCU, enabling standards-based group conferencing with a variety of endpoints. The server uses a Reactor to handle all T.120 protocol communication, and a Proactor to handle the huge numbers of RTP/RTCP audio and video datagrams. Also, an ACE_Task is used as a thread pool for mixing audio packets. TAO is being used to configure and monitor the server.
SnowFalcon (2003-12-3 12:32:03)
另外一个问题是,tradeoff。tradeoff的一个关键假设是硬件性能提升的速度可以赶上糟糕代码所带来的消耗。但是这个假设成立么?在highperformance的语境下基本是不成立的。因为高并发的应用,就意味着代码调用的次数是指数级的增长。面对这种增长,硬件几乎无能为力。trade off很多时候会给程序员一种假象,即操作系统能管理任何事情。但是当出了问题以后,那已经是nightmare了。以前我曾经写过很长时间的java网络通信的应用。这些应用最麻烦的bug就是性能问题,而这些问题基本根源就是程序员书写的糟糕代码。你相信Java程序会有内存泄漏么?你相信一个程序的一个星期内高效工作,但是下个礼拜一就因为内存碎片而慢的象乌龟爬么?你相信一个java程序会应为几千个thread而导致每个连接需要用10秒钟来完成connect么?你相信因为使用了一个visitor/obersver模式而把整个服务器的速度拖垮么?很多在平时看上去非常良好的设计,一旦更换到highperformance就是bullshit。而且最为危险的是,最后的性能问题出在整个设计结构上。因此我认为highperformance的网络程序的一个信条就是永远不要相信操作系统和语言的特性。最大的隐患就是我们最放心的地方。
SnowFalcon (2003-12-3 12:08:51)
是的,的确是需要特定的语境。但是这个语境已经很清楚了,那就是highperformance。如果一个应用没有critical的性能需求,那么显然是不是在讨论highperformance。网络通信的种类很多,什么是high performance?一般来说高并发量,高流量的需求并不能代表是high performance。因为比如http,ftp这样的服务,应该是说中等的并发量,上下文无关,但是会有流量上的严格要求。那这些服务,用ace/tao之类的类库甚至使用java(例如tomcat/jboss)无疑是合适的。因为即使你的一台机器负荷很高,那么也能用loadbalance的方法将请求切换到其他空闲的服务器上。但是如果应用是有严格的上下文相关的,比如我正在从事的工作softswitch,每个tcp包都是一个连续的语音流的一部分,那么就无法在连接工作的时候切换服务器。那么就不得不提高每个服务器的性能和稳定性。要提高性能,那么一个关键的问题就是不要等待操作系统来调度资源,包括线程,内存,锁等等.这个观点在高性能的网络程序中都是通用的,只是程度不同而已。例如EJB的连接池,就是一种接管系统资源的方法。你可以说java自动回收内存,finalize来关闭连接。但是这种连接高消耗,也不得不让Java这种傻瓜语言低头。其实去看看jboss/tomcat的原代码,很多地方都充斥这些为了性能而舍弃设计的方法。
WalkWorld (2003-12-3 11:38:01)
linux里面的一个进程里能够创建的线程数量实际上就局限了它的连接能力,这样说你同意吗?linux你肯定要采用select ,而采用select的话有一个线程只能等待64个事件,这也限制了它的并发处理能力!未分页内存池耗尽可以通过限制未完成操作的数量来避免,你说的windows 2000 server下并发连接数量到500的时候,cpu 占用率就很高,而且时间长了会有未分页缓冲区耗尽的问题,不知道是从何而来? 你看看windows网络编程(2 edion)里面的数据吧! I/O模型 尝试连接数/成功连接数 使用内存(KB) 未分页内存池 CPU用量 线程 数据吞吐率(每秒发送/接收的字节) IO完成端口 7000/7000 36160 31128 40%~50% 2 6282473/3893507 12000/12000 59256 38862 40%~50% 2 5027914/5027905 50000/49,997 242272 148192 55%~65% 2 4326946/4326496 服务器P4 1.7G xeon, 内存768MB。客户机建立在3台计算机上:PII 233M,内存128MB;PII 350M,内存128M; Itanium 733M, 内存1G。测试网络100MB隔离集线器。操作系统win XP。它的服务器端和客户端的程序这本上都有,虽然我没有测试过,但是我相信这本书而不会相信你!你可以把你的数据贴出来。另外,我先声明,我不是对你漫骂,我只是希望你能对你的书认真负责!
zhuchuanjing (2003-12-3 10:57:21)
很高兴看到这么多人发表评论,还好谩骂的不是很多,比我预料的好多了,在这里我做几点申明:首先,我说的是linux的线程创建开销,和进程的线程上限没有关系其次,我实际做过大量IOCP和real time signal, epoll的工程,IOCP在处理极大数量并发连接的时候效率比rts和epoll差很多,接下来我会提供实际的例子和评测数据,在2000 server下IOCP的并发连接数量达到500以上的时候,CPU占用率就很高了,而且时间长了会有未分页缓冲区耗尽的问题(连续运行24小时,在网络环境不稳定的情况下)。我不知道这位朋友的IOCP效率最高的说法从何而来,如果是听来的就不要误导大家,如果是自己测试的结果我会很高兴的和你探讨。
bolidecaster (2003-12-3 10:54:20)
如果“完成端口用很少的几个线程处理几K并发连接依然保持很稳定的CPU占用……”,4000个客户大概也就并非等价于4000个并发线程,当然也就不用从第1个线程切换到第4000个线程了。这里有一篇关于ACE_Proactor(封装了NT的完成端口和POSIX的AIO API)的论文:http://www.cs.wustl.edu/~schmidt/PDF/PDCS-98.pdf SnowFalcon所说的评测数据,要看其系统设计针对的环境,没有特定的语境,这样的数据是没有意义的。另外,从理论上说,用C写的程序几乎总是可以比C++更快,但就像编写游戏软件一样:用汇编写游戏肯定最快,但现在没有人全部用汇编写大型游戏,因为你很难、或是不可能完成游戏,也没有必要这么做——用C写大部分代码、用汇编写性能关键的代码就能够满足要求了。这是一个trade-off的问题。如果用ACE这样的OO框架开发的应用能够满足要求,而且开发周期要短得多,就算性能稍差,我们仍旧可以选择ACE。更何况,一般开发者用C写成的网络应用未必能胜过基于ACE这样的应用。 SnowFalcon:辩论是很正常的事情,你不用觉得受到了挑衅。 Cowboy22:我也已经等了很久了。不知道什么时候能出版。
wuyg (2003-12-3 10:23:20)
to SnowFalcon: 如果没有上下文,老兄这么说我是完全正确,但你也要看看正文说的是商业应用上的网络应用, 不是硬件级的编程,因此从上下文来看,老兄这么说我可不对哦。 你应该也承认,每个观点都有自己的使用范围。几年前我也是非常武断地讲究运行效率,可是几年 的应用软件市场的打拼,让我明白了一些道理。
WalkWorld (2003-12-3 10:20:40)
TO:zhuchuanjing作者按照你现在的思路,如果你不做实际的测试,你的“网络IO模型的设计和评估:”这一章节将很难写! linux下面一个进程根本不能开5000个线程,最多也就1024个。而且开这么多的线程肯定会陷入Thread hell,线程间的切换开销将十分巨大,效率可想而知。更不要说采用轮询机制来检查套节字的状态了。可以采用select,但是也有局限,因为每个线程只能等待64个事件,这对于处理大规模的并发socket来说也是难以接收的。如果你真的想写书的话,希望你能对读者负责,你作出实际的测试,用数据来表明你的观点!谢谢!期待有一本好书出现!
WalkWorld (2003-12-3 10:06:49)
re windows下的IOCP(IO completion port) 是所有的I/O方案中效率最高的,只是在windows下面没有在linux下面稳定而已。我现在正在研究I/O完成端口编程,有兴趣的大家一起讨论吧,qq:43490118
sunhuiNO1 (2003-12-3 8:42:16)
真不知道你用过完成端口做过开发没有?完成端口用很少的几个线程处理几K并发连接依然保持很稳定的 CPU占用,同时由于线程很少,所以线程竞争很小,而且相互之间的切换由内核来控制,比循环SELECT效率要高多了。SnowFalcon的讲的很对。实话说,我很想看看你的测试代码和测试的数据。在我的影象中,完成端口模型在各种测试中都击败了linux下的各种I/O模型。
Cowboy22 (2003-12-3 8:32:34)
好好, 很有可能是一本好书, 出来的时候通知我一声. bolidecaster是马sir吧? 你和lostmouse的C++NP什么时候出来? 等了很久了.
SnowFalcon (2003-12-3 0:01:17)
ACE/TAO,So what!看看他的评测数据,linux RT上4000个client已经是峰值。如果4000个client就算high performance的话,那就未免儿戏了。就按照他的bench mark的机器,起码上要每分钟处理10万个call才能算是high performance。其实4000个线程,性能已经相当低了。Thread之间的context切换都是毫秒级的从Thread1切换到Thread4000就需要几秒钟的时间。如果Thread 4000被某个客户使用它要到几秒钟之后才能处理数据。当然在一般的http,ftp的应用这个几秒钟是无关紧要的.但是如果是一台softswitch,客户使用的是IP电话,那么你需要客户听到的语音就会出现严重的掉帧。
bolidecaster (2003-12-2 23:20:07)
FYI: http://www.cs.wustl.edu/~schmidt/ACE.html The ADAPTIVE Communication Environment (ACE) is a freely available, open-source object-oriented (OO) framework that implements many core patterns for concurrent communication software. ACE provides a rich set of reusable C++ wrapper facades and framework components that perform common communication software tasks across a range of OS platforms. The communication software tasks provided by ACE include event demultiplexing and event handler dispatching, signal handling, service initialization, interprocess communication, shared memory management, message routing, dynamic (re)configuration of distributed services, concurrent execution and synchronization. ACE is targeted for developers of high-performance and real-time communication services and applications. It simplifies the development of OO network applications and services that utilize interprocess communication, event demultiplexing, explicit dynamic linking, and concurrency. In addition, ACE automates system configuration and reconfiguration by dynamically linking services into applications at run-time and executing these services in one or more processes or threads. ACE continues to improve and its future is bright. ACE is supported commercially via the Riverace corporation using an open-source business model. In addition, many members of the ACE development team are currently working on building The ACE ORB (TAO). http://www.cs.wustl.edu/~schmidt/ACE-users.html ACE and TAO are being used in thousands of commercial products at many companies, as well as at various universities and research labs around the world, in many types of communication systems, particularly telecom, medical, aerospace, and financial services. Our research group has personally worked with companies using ACE and TAO on UNIX, Win32, and embedded platforms on the following projects: * TAO and ACE are used for a number of manned and unmanned real-time avionics mission computing embedded systems at Boeing/McDonnell Douglas in St. Louis, MO. Several successful test flights of Boeing aircraft were recently flown using ACE and TAO. * TAO and ACE are used for the Run-Time Infrastructure (RTI) for the Defense Modeling and Simulation Organization's (DMSO) High-Level Architecture (HLA) distributed interactive simulation environment at SAIC. * ACE and TAO are used for syngo, which is next-generation medical software framework for Siemens Medical Engineering, Erlangen, Germany. * TAO and ACE are being used for network management and a call processing gateway for a "voice over IP" system in the Siemens ICN division in Munich, Germany. * ACE and TAO are being used for a number wireless and wireline telecommunication and data networking embedded systems at Lucent Technologies and Motorola. ... ...
bolidecaster (2003-12-2 23:04:21)
zhuchuanjing:对6502了如指掌?
BlueTrees (2003-12-2 20:53:17)
没有明白文章在说什么,作者到底是什么观点?
SnowFalcon (2003-12-2 17:28:01)
以我所观察的情况而言,一般5万元人民币的服务器硬件可以承担的应用是至少50万人民币的软件价值。 所以我认为作者并没有充分考虑总体成本。 ___________________________________________ 你知道通常的softswtich每分钟会处理多少个call么?7个billion 你知道一个u的服务器只要要支撑多少并发数才能满足一个局的IP电话的接入?1.5 个million 不懂就不要乱说.高性能的网络服务器甚至是杜绝线程的使用,而采用时钟中断进行状态机轮询。如果一个服务器开1万个thread,可能已经到了极限。面对7个billion的呼叫简直就是杯水车薪。软件的设计和实现一律都是c,void指针的强制转型,old plain strcuture。不要说玩什么pattern之类的东西,就连OO,虚拟都是不允许的。template/stl还可能有用,但是你必须要修改所有的内存分配方式,以内存池代替malloc/free或者new/delete。
wuyg (2003-12-2 15:55:04)
我常听人说,现代计算机系统开发的侧重点已经从运行效率转到开发效率,是因为硬件的高速降价和软件成本的据高不下造成的。以我所观察的情况而言,一般5万元人民币的服务器硬件可以承担的应用是至少50万人民币的软件价值。 所以我认为作者并没有充分考虑总体成本。
captainwh (2003-12-2 15:44:53)
怀疑其权威性,是个Linux fans吧
securitytrip (2003-12-2 15:24:17)
感谢你提供这样一个思路,希望我们能在测试方法和数据分析等方面作进一步探讨。
Alex_20 (2003-12-2 14:59:44)
高效率的缓存机制也非常重要啊,希望作者不要忘了这一点。
solarsoft (2003-11-30 13:36:41)
epoll