|
|
这里所说的web,特指large scale web,大规模,高负载,高并发是它最显著的特点.
asp.net作为一个基于.net framework和windows的web框架,总体来说还是不错的.为什么说它要基于windows的,在linux下不也是可以用asp.net了吗?但那个asp.net是做不了large scale的web application的(这个我们可以一起探讨为什么)
asp.net在走过1.0,1.1到2.0的时代上,已经显露出了大量的弊端,随着各种快速并且在一定程度下仍能保证不错性能的几个流行的快速开发框架下,asp.net也做出了响应的改进,下一个版本的asp.net有非常大的可能直接是4.0版本,其核心的两大框架是asp.net mvc和dynamic data.比如说我们参照一下RoR框架,scaffolding是不是很酷,创建好数据库的table,一个scaffold,实体层和数据访问层就well done了,大多数情况下速度也不错.而django可以直接写一个实体的entity,然后就直接可以用了,更是方便,我们都忘记数据库是什么了.
技术的进步带来的一个不可避免的结果就是让更多的程序员缺乏对真相的认识和底层技术的匮乏.
园子里的朋友绝大多数的都是从事基于.net开发职业的.那么当你面对一个即将要展现在internet上的large scale的website的时候,我们如何考虑性能?NLB,Cluster,缓存,减少数据库带来的性能损耗,分布式...
这样的考虑出发点并没有错,看一下微软提供个我们的:方便的outputcache,愈发强大的sql server 2008,wcf框架, 更有前几天刚推出来的分布式缓存...
反过来我们看几点:
- 这些缓存真的需要这么麻烦创建或者说一定要你亲自动手去做吗?
- 把成千上万的小数据的内容放在硬盘上一定比放在sql server里快吗?
- 分布式一定要做的那么标准那么符合微软的要求吗?
我一直觉得早期使用过较多asp技术的朋友比起从asp.net作为起点开始web开发的朋友要幸福许多,能看到更多web的真相,也就是能更多的需要去了解http这个东西. 5年前有一个项目让我比较幸运的使用vb6封装了asp来开发一个产品,也是从那时候,逐渐开始知道了rfc的重要性.
我不知道有多少看了这篇blog的朋友能回味起学生时代听老师把html和web讲述成各种各样的版本.现在的学习方式应该改变了,是需要质疑和刨根问底的,相信学校里的老师或培训机构的课程,不如自己看看rfc并且动手实验一下.
要做大规模的web application我们需要了解一些什么呢?
a) HTTP
这个太重要了,很多地方都讲过它.这里不讲述什么,我们看一个例子:
我们telnet到园子,输入:
HEAD / HTTP/1.1
Host: www.cnblogs.com
(回车)
一会就能看到response了.如果您对这三行命令一头雾水或还不太明白,那应该看看http相关的rfc了,如果您没有注意到这个request并没有“connection已经丢失”的提示,那应该看看rfc2616.
b) Web Server
不知道从上图大家是否看到了园子很酷的地方:使用了IIS7.0
IIS7.0如此的酷,是iis历史上一个最大的变革.从这个版本开始,才更像是一个web server了,同时也弥补了一些asp.net框架上的不足.
从两个不同的角度来举例子:
- 有没有朋友在iis6上使用asp.net mvc时发现你的url不能很酷,如果不借助third party你不能不接受url里是http://localhost/abc.mvc/def/ghi的情况.aspnet_isapi.dll不是那么优先的,至少它前面还有一个http.sys,但是对于使用asp.net的幸福的一代,这两个东西在大多数情况下都没必要直道他存在.iis一直是跟着文件走的,称作mapping,在到达asp.net之前,server已经根据url做了该做的工作,这也就是你无法把这个url重写的原因,要想rewrite这个url,唯一的做法就是去写一个isapi,托管代码在此时就没有任何作用了,换言之,要了解一些win32和iis6的工作模型才能完成这个工作了(幸运的是这个task不是很难).而web使用的最多的是什么类型的?肯定是static file,那么好,iis7.0就把static file拉出来重新审视他的地位,所以在iis7上你可以把这个.mvc的尾巴去掉了.相比iis7,google app engine的server更多的是关注non-static的内容了,所有static的东西一定要说明了才可以使用.
- Gmail能不能用iis来做server,答案是当然不可以.http说我们可以有head,get,post,delete等命令,iis,apache等主流server都不支持delete,换一个角度,也就是说我们开发的环境导致了我们对web认识的片面性:
client给server一个request,server是不是必须要立刻返回?
一个request发送出去后还没有response,我们可不可以继续发送request呢?能发送多少个?
为internet提供服务的web server有各种个样,在一棵树上吊死或许不是明智之举,这里不是说微软的平台不好,而是说这个平台的价格和她的能力应该去让她去做更重要的事,这就好比你当老板的时候招一个3,4K的程序员来做架构,ta不一定有这能力;招一个12k的程序员来做一些繁琐和基础的工作,ta不一定能做好一样.Linux下有很多很酷的东西,比如nginx,lighttpd这样的lightweight web server,在处理静态文件的时候效率是非常不错的,由此节省的成本也骤然降低了N个档次.有时候我们会认为把静态内容放到内存里比做成静态文件更快,如果能不把IIS当作你唯一知道的webserver的话,那应该了解到webserver其实是一个处理静态文件的好手.像CDN这样的应用的例子是一个极限情况,应用它所需要付出的成本也是很可观的.有一些聪明的网站使用nginx来做过滤器,自己处理静态内容,动态内容转交到其他服务器来处理.而web server的实现也不是那么复杂,建立一个最基本功能的webserver只需要十几k的c的代码,有兴趣的朋友可以看看qshttpd-0.3.0这个版本的源代码.
c) Browser
最近几年来让人特别关注客户端开发的是xhtml, ajax, advance css, Yahoo的21 rules和IE8.尤其是yahoo的YUI小组两次公布的rules上,越来越多的人注意到了客户端程序结构的重要性,IE8的到来更让许多人知道了浏览器的connection的小秘密.其实不然,http标准里对这些内容的阐述就像是1年级的数学一样,只是用了一个SHOULD略加修饰.
在举一个case:如果您遇到需要删除一个Repeater里的所有checkbox为checked的items,除了在服务器端遍历这堆checkbox外,为何不用javascript去遍历然后将特征值以某种形式post到服务器,服务器删除完后给一个ok的回应,脚本再将客户端的页面的相关的内容从dom中去除或隐藏掉?仔细比较一下,性能和复用上都是一个提高.
上周五在家修养了一天,想了很多关于这篇blog该怎么写.文笔太粗,内容显得比较凌乱.技术应该是没有界线的,就像微软也从不排斥其他技术一样.写这篇blog希望更多的可以让园友们看到基于.net的web开发上的一些死角和一些固定思路.更希望有更多的朋友可以一起来丰富这个主题!
P.S.
与上文的图相比,看红框内的内容.
如果对lighttpd感兴趣可以参看一下:
lighttpd+web.py的一个简单测试结果:每秒可处理350个请求
在lighttpd上配置web.py运行
ubuntu server上删除log后lighttpd无法运行的处理
install lighttpd and php5-cgi on ubuntu
如果对google app engine感兴趣可以看一下:
ubuntu下google app engine的dev_appserver.py启动报缺失PIL module的warning的解决办法
GAE的datastore在index上的bug
如果对博客园下一代Web网络技术团队感兴趣可以comment上您的博客园ID加入该team.
此外,对于.NET新手training活动Team我开通博客园Training小组,希望有些您不是太急一时google不到结果的问题可以post到小组里.小组相比QQ群是异步的,在不耽误大家工作的同时相信会有更好的答案.
Feedback
不得不承认微软平台上的开发人员认识面普遍狭隘,真不知道是微软的错还是程序员的错。
lz所说的qshttp-0.3.0,我google了一下,貌似没什么反应.麻烦能不能说清楚具体的项目名称,官方网站,谢谢
“lighttpd+web.py的一个简单测试结果:每秒可处理350个请求”。
从这个数字上来看,IIS也完全可以。
web 2.0应用瓶颈9成在数据库上,只要写的正确配置的正确,任何技术任何平台的性能都差不多,还说asp.net + iis不行的人要么还停留在iis5年代要么就是跟风。
还想说的就是,没有说用了asp.net和iis就不能和linux粘上边了。比如用nginx做前端反向代理,负载均衡,后面搭建Squid群集作图片缓存,最后用windows做静态文件存储也是常用的办法。当然静态文件服务器换成其他平台的也没有关系——甚至是数据库。因为前端的nginx和squid在将后面的存储实现隐藏了起来。
因此支持楼主在这方面进行普及,需要老赵的地方也不要忘了我。:)
@Jeffrey Zhao
关于这个350请求的测试环境还得看完全文,我没有列举出服务器当时的性能,没有像windows下perfmon这样直观和优越的工具,但看到的这个350并不是requests/sec计数器,在这里其实应该是一个再与request executing结合后做的一个值,这一点毫无疑问是比windows下的要高.
其次,windows能做到的时候,成本也大幅度上来了.
只要写的正确配置的正确,任何技术任何平台的性能都差不多--这个我不赞同:衡量的标准应该是在差不多的时间内完成的.同样一个基于.net framework 2.0的website,一个用原生的asp.net框架,一个用自己根据业务特点而写的web框架(毕竟这个完整的asp.net2.0框架不是为large scale类型的网站制定的),肯定性能截然不同,同样,同一个应用程序基于iis6和iis7而编写,性能也有可能会差很多(比如从单纯考虑GC对基于asp.net框架对website的影响上)
此外我觉得数据库的说法也有些不妥,我觉得数据存储似乎应该更合适.
whatever,我认为究竟如何搭建一个large scale web application,还是要根据业务特点选用合适的服务器,选用合适的技术.
@Jeffrey Zhao
关于这种服务器架构很多大型的网站也在用.两层前端.而且都比较廉价.
相对来说我比较幸福,从ASP转过来的.
感谢楼主分享.
最近在用django开发,.net的框架把我惯坏了,总需要考虑数据提交,URL定义等很多WEB开发很基础的东西。WEB基础太差了,不过django的性能的确不错!
不光是从asp过来的,如果你是从php过来的,你会更加有优势。
顶一下!难得的文章了 我想还是应该 Deep Inside 的吧
@StillWartersRunDeep
基于python的框架我就用过web.py,对django还真是不熟,不过看起来web.py比dj更lightweight一点吧
@在线代理
这个不见得. asp也算是博大精深了,只不过暴露出来的东西让大家更多的看到的是他简单易用的一面--这也是微软做asp的目的.
"不过看起来web.py比dj更lightweight一点吧"
是的,web.py是个很有学术价值的开源项目。
代码简洁明了。最近就在研究web.py的代码。
和django这类全站式的框架是不太一样的。
不地两个框架的代码写的都相当不错
“数据库”的确不妥,应该说是“数据访问”。
我还是坚持“只要写的正确配置正确,不论什么技术(作web 2.0应用)性能都差不多”,因为IIS的性能和asp.net的性能丝毫不差。
还有就是我还是没有听懂你说350这个概念,但是我做过的项目里,每秒350个动态请求完全不是问题。你说的“成本”问题,我也不觉得有什么额外成本——当然我说的是硬件之类的,如果你是指windows是要钱的,那么我就无话可说了。
你说“毕竟这个完整的asp.net2.0框架不是为large scale类型的网站制定的”,是指WebForm吗?性能完全没有问题的。我觉得你也在认为windows平台上的性能不行,但是数据要靠实践才能说话,虽然我们必须将眼界放宽,但是不能有偏见和猜测。
@Jeffrey Zhao 赵哥,你说的这个350个动态请求参照的应该是看的requests/sec这个值.这个值通常在700下都没有问题(2008没有在生产环境中体会过).但是评估asp.net程序性能还有一个计数器是request executing,当然这个值究竟为多少合适各种说法都有,究竟是否依据cpu数量(准确说是taskmgr里看到的cpu的个数)我觉得还是要看.net在处理什么而定.
我说的成本确实是指windows的成本
“毕竟这个完整的asp.net2.0框架不是为large scale类型的网站制定的” 这不单是webform,是整个的asp.net框架. 这里不是说asp.net性能不好,而是说它不够好,原本可以做的更出色,更直白,只不过要顾及这顾及那,所以我才有如此的说法.举个例子,域用户验证机制对large scale的website在通常情况下需要吗?
@Ariel Y. ariel哥,我还是坚持在.net阵营的.只不过最近在跟朋友搭一个website的时候交流中的一些感想:)
.net 封装,这没有错,主要是我们开发人员要懂细节,懂底层 asp.net自己性能方面确实不怎么样,但是他简单,呵呵,对付中小型的系统还是可以的
@new 维生素C.net()
.net里还是实现了一定程度上的可插拔,比如windows验证没有用,它也不会降低性能阿。
至于350个请求700个请求,如果单比IIS在极限特殊状况下的响应能力(比如纯响应请求,不输出资源),可能的确不如一些定制的服务器,但是需要明确的就是,它对于动态请求完全不会成为性能瓶颈,瓶颈在数据访问上,iis处理请求的能力完全游刃有余……
@Jeffrey Zhao
"比如windows验证没有用,它也不会降低性能阿" 对,这个不会.但是像默认添加的那些http module(.net framework的配置里的),却是或多或少的存在影响的,并且这些东西都有积少成多的特点,积少成多的结果就是对性能的影响.
其次"对于动态请求完全不会成为性能瓶颈,瓶颈在数据访问上"这个说法我也赞同,但我认为不是这么肯定.比如GC,比如进程的lock,即使不读数据库,这两个东西也完全可以导致high cpu或者server too busy.反观asp.net本身的使用上并没有大量的使用BackgroundWorker类.
iis的能力不容怀疑,的确不错,但是还不够好.iis是对操作系统依赖性相当大的.
我这篇文章的目的没有批评微软技术的不好,而只是说我认为我们在做有web2.0思想(大多web2.0网站主线很明确,服务种类也相对单一)的large scale(要足够的large)website的时候,找到最核心的业务选用最恰当的技术来实现,才是最好的方案.不应该是从技术角度出发来分析问题,语言和框架等只是一个工具.懂细节,懂底层能让架构更简单,更实用(当然各种成本也要尽可能的低).
哈哈,终于看到Ubuntu了。。。。 呵呵,支持。。。。
" 在举一个case:如果您遇到需要删除一个Repeater里的所有checkbox为checked的items,除了在服务器端遍历这堆checkbox外,为何不用javascript去遍历然后将特征值以某种形式post到服务器,服务器删除完后给一个ok的回应,脚本再将客户端的页面的相关的内容从dom中去除或隐藏掉?"
对于这种情况,我一直担心一个问题就是,就假设50条记录就好,在客户端用JS进行操作肯定会占用用户机器的CPU,这会不会使用户产生反感?
@Q.Lee.lulu
1.这个操作如果要重视用户体验的话,就要在脚本上下功夫,不同的脚本性能差别可能天壤之别.
2.思路就在,把服务器段计算放在客户端完成.潜在危险是数据安全性.得到的好处是计算转移,或者说是性能损耗转移.
虽然windows的bug一大堆,API陈旧,但是还是要支持一下,因为它改变了人们的生活,而不是创建了便宜的服务器,其实linux/unix服务器的维护更新成本也不低,扩展能力有限。
@new 维生素C.net()
如果因为GC导致cpu hang的话,几乎一定是因为程序写的不对,这不是技术的问题,而是使用者的问题。事实上相比如python与ruby等语言及其运行环境,.NET的GC实现非常好,执行效率也很高。
@Jeffrey Zhao
不 .net的GC效率没那么高.
cpu也没有hang的说法.
动态语言的垃圾回收器不能与.net同日而语.
.net的GC会占用较高的cpu,并且中断通讯的继续进行.这是目前不可改变的事实
...感觉越来越跑题了...
博主帮忙发一份,你那http交互的工具bearyqb@163.com
@new 维生素C.net()
GC过渡导致CPU高居不下是常见问题,那是因为写错了。
.NET里GC的确会造成暂时停止某些处理,但是这个不会造成问题,把GC的时间平均到业务处理时间上就几乎可以忽略不计。如果因为GC导致CPU占用过多,或者因为CPU太频繁导致性能低下,那是程序的问题,不是.NET的责任。
.NET程序的性能远优于脚本语言是共识吧,如果不是瓶颈在数据访问上,.NET应用程序性能也该比基于Python或Ruby的框架要快。
@Jeffrey Zhao
1.我没说高居不下,我说的是GC会占用较高的CPU.
2.暂停处理不会造成问题,但是这本身是语言的一个问题.至少现在看来微软是无法避免这个问题,当然这与操作系统有关.
3.我从没说过.net性能低.也没说过它比python或ruby的框架慢.我说的是asp.net框架.
一个request发送出去后还没有response,我们可不可以继续发送request呢?能发送多少个?
---------
很多地方不懂,弱弱的问句,那么改成post呢?IIS6的话,一秒能post多少次?请教。
对于像我这样以前是做Winform的.Net程序员来说,现在转做Web开发了,对Web开发的底层接触实在是太少了,不知道楼主有没有什么好的,建设性的意见传教下啊.现在还真的是有点不知所措呢,要学习的东西似乎太多了,搞得方向有点迷失了.
我只知道从HTTP/1.1开始可以不Response就可以Request但不知道限制多少。
|