WEB应用程序的性能提升和应用编码同样重要,它往往在设计上应一并考虑,然后在编码工作整体完成时花大量精力来调整,kolidon近一年在此问题上殚精竭虑并略有心得。

众所周知,对代码的细微调整常常有显著作用,在LAMP平台上,使用xdebug+cachegrind这样的profiling工具是最佳选择,在ASP.NET应用中,系统自带的DEBUG功能已经非常强大。而本文讨论范围不仅限于代码优化和profiling。

1. MYSQL/MSSQL数据库优化
在WEB2.0时代,数据库服务器面临重大挑战,在典型的社区平台应用中,数据库查询基本上在每一次页面请求发生多次,在这里,数据库服务器的磁盘性能基本上是决定一切的关键。但基本上,一台一般服务器(双xeon5210+4G内存量级),每秒数千次查询勉强能应付高峰时段一千至两千次页面请求,若应用量级更大,对MYSQL来说,采用双机或三机主从结构,分离读写是第一步选择,对MSSQL来说,目前能见到的公开资料和应用讨论并不多,但在某个开源应用DNN与MSSQL SERVER EXPRESS的结合,有令人惊讶的效率;

2.查询语句优化,简化SQL语句,减少关联查询、索引、减少全表扫描次数(MSSQL 尽量使用存储过程)
统计每一类可能出现的查询并记录到专门编程日记上以对在可能是优化之,国内几家CMS厂商对这一类话题有较多的贡献,特别是在MYSQL数据库架构和SQL查询优化的细节上(但我更相信是出自一些大型厂商如IBM的资料整理工作);

3.程序中间代码编译缓存(这一点上,ASP.NET完胜)
OP码缓存功能如apc、Eacc、Xcache一定要开启,据kolidon反复测试,在IIS平台下首选eacc,稳定性不错,性能可以接受,Linux/Unix平台首选Xcache,性能超强(很多专用的WEB2.0应用将20ms当作目标,这一条和下一条经验比较关键);

4.程序内cache
在经验2中,我们已经提到每一条可能发生的查询都应该被记录,当然,此处就是尽可能的缓存结果了,在专用应用如discuz中,所有能够被缓存的对象均已被缓存,因此,不论系统访问量多么巨大,查询数量都能维持在很代的水平,而每次查询确实非常简洁,缓存的destroy和generate策略被精心设计,在每一次查询前后被核对,事实证明,这已经成为当前专有WEB应用的基本设计原则。

而开放框架应用所遭遇的最大挑战,在于插件生成的查询方式和数目完全不可控——在drupal及joomla一类的开放构架应用中,查询数量关系一切。因此,kolidon以为,在开放框架应用的设计上,也应有类似准则和规范以控制查询数目,这个规范,我有空时将专门讨论,当然,还会有小技巧如:kolidon——修改数据库类,建立SELECT查询的缓存策略(待撰写);

5.不要忽略浏览器HTTP请求顺序——重视HTTP请求顺序和速度
一般来说,若核心内容已经被输出,则它的格式应该在无js及css的情况下即具有一定可读性(那么,少量的内嵌CSS和JS代码可以被接受),而随后的CSS和JS,因一般采用标准的框架,代码量相对较大,会需要被外挂,外挂前,首先当然是合并以消来多余的请求,不少工具可以帮助我们做到这一点。甚至,有一套名为PHP_SPEEDY的应用,可以通过直接在当前应用内嵌入指定代码发挥作用,它可以自动合并的有js请求,合并所有css请求,自动压缩,并设置过期时间(原理是扫描母应用中的相应字串,读文件并生成特殊唯一的文件名)。而在ASP.NET的开源应用中,有些框架如DNN自行管理UI元件,用一套精心设计的机制来决定何时分发何种JS及CSS,效果也不错。

最关键的,IE浏览器会有并发HTTP请求的限制,这使大量HTTP请求需要更长的时间完成;

6.页面内容的代码顺序也很重要——重视浏览器生成页面的速度
我们需要仔细审核TEMPLATE(虽然程序部分的TEMPLATE分析器的选择也很重要——smarty或者pattemplate都不错),这一般是考虑到制作者更侧重于UI设计而可能忽略浏览器显示效率这个基本面——减少图片数目,审核所有HTML代码以确定浏览器能够顺利地绘制(简单而言,就是不要套太多层表格、不要使用太大的图片作为修饰,不要在页面上使用JS或CSS做过我的特殊显示效果等)。

另外,若必要,所有背景图片应合并成单张图并使用position属性以仅使用图片中的不同位置,这样,图片总大小不变或减小,而请求数大大减少(关于5和6,YAHOO性能团队有一个名为YSlow的插件及配套的“性能优化XX条准则”,基本上,能够解决这方面的一切问题)。

好吧,行文至此,我得承认,WEB应用的本质就是HTTP请求,因此,题目仅仅是夸张地表述。

7.最后,你在使用什么WEBSERVER呢?
OK,kolidon自己在某台服务器上使用的是IIS6+PHP+FASTCGI+ASP.NET2,数据库用MSSQL SERVER EXPRESS2005,因为有不少旧的应用需要运行在这个平台上,但几年来,遭遇的问题多不胜数——当然,管理员经验丰富能避免一些,并且你知道,这些问题都是可以解决的,只是每次解决后,问题总会再次出现,然后,你没办法知道究竟是因为因而造成了恶果。而能够提供解决办法的来源仅此一家(也可以用google去和大量的垃圾站长分享他们的未作保证的文献),而IIS与系统其他组件有太多的耦合。

关于IIS的不满主要有:1) URL REWREITER(有两个,一个商业的有免费应用,一个开源的但稳定性欠佳,另外,ASP.net似乎已经解决了些问题)。2) 配置文件metabase.xml文件的读写API及可靠性,这个集中式的配置文件很大,我的几年下来有两次损坏经历,解决办法是重装IIS然后恢复以前的备份),而读写API仅有少量商业软件的实现。3) 安全设置和应用程序池回收也让人迷惑:默认的,WINDOWS2003需要更改大量系统文件夹的权限以减少通过WEB被攻击的机会:上传木马-权限提升-系统被爆,而应用程序池这个发明或需进一步加强稳定性和性能(有专门文章讨论IIS6下的虚拟主机设置,特别是ASP.NET虚拟主机设置,但我更愿意在专门时间研究微软的所有默认帐户的权限问题)。4)辅助工具欠缺,比如集成的负载均衡和反向代理等。

IIS7已经释出多时,国外的虚拟主机提供商已有win2008+IIS7平台,据说对nix平台上的WEB服务器思路多有借鉴.

因此,如果可能,Apache/Lighttpd/Nginx+FASTCGI+PHP可能会是上佳选择,当然,除了性能、简洁,更重要的是,我们总有无数的工具可以帮助我们找到和解决问题,如,LVS、Squid一类负载均衡,反向代理,Memcached一类的专用缓存服务器。还有,无尽的开源应用。

我的开发平台上的配置是:Ubuntu sever,Nginx+PHP(fastcgi)+fpm+Xcache+Memcache,运行Memcached+Mysqld守护程序。
据信,金山的爱词霸社区应该是Apache双机负载均衡(来源:该项目组某成员博客)。