您的位置:知识库 »

网站性能越来越差怎么办?

作者: WizardWu  来源: 博客园  发布时间: 2009-01-03 18:05  阅读: 1726 次  推荐: 0   原文链接   [收藏]  

新的一年,你的老板或客户,是否曾和你抱怨公司的网站性能愈来愈差?网站大家都会写,自从有了 Visual Studio 之后,连你家楼下的正妹小喵和隔壁的王大婶都会写 ASP.NET。但同样的一个画面,背后的性能却可能是天差地远,更惶论多人同时上线的企业网站,而程序员的身价也因此有所差别。本帖提供一些改善网站性能的点子,从硬件、软件、程序技巧的层面都有,也欢迎大家分享自己的经验或秘技。


(1) 重新调整或重新设计 DB schema、「索引 (index)」

一个在线系统的性能不佳,主要原因都是来自于数据库规划及 SQL 语句层面,至于 .NET 程序撰写不良都还在其次。

先将数据库适度地做正规化,如:一个 Table 中,避免把常用的字段、很少用的字段,都塞在同一个表中,而影响数据扫描的速度。
应该将很少用的字段,另切割出来成为另一个表。

请参考:
30 分钟快快乐乐学 SQL Performance Tuning:
http://www.cnblogs.com/WizardWu/archive/2008/10/27/1320055.html

----------------------------------------------

(2) 改写 SQL 语句,注意 index 是否在查询时有真的被用到

* 同样的功能,一个不良的「关联子查询」和良好的「独立子查询」,之间的 SQL 性能差距,是不到一秒钟和好几分钟以上的差距。

* 一些 SQL 关键词,只要一出现在 SQL 语句中,就可能造成表的「索引 (index)」完全失效或部分失效,变成要整个表去逐行逐列地扫描,
例如: NOT、NOT IN、!=、<>、OR ...等关键词,
还有「LIKE '%关键词'」的模糊查询,也会造成索引失效,但「LIKE '关键词%'」就不会造成索引失效。

请参考:
30 分钟快快乐乐学 SQL Performance Tuning:
http://www.cnblogs.com/WizardWu/archive/2008/10/27/1320055.html

----------------------------------------------

(3) 使用 Native 的 DataProvider

放弃 OleDb,改用 ADO.NET Native 的 DataProvider,如: SqlClient、OracleClient。但若您公司坚持要用 Sybase 这种从 2003 年之后,就不曾更新 DB driver 的数据库,就只好继续用性能不佳的 OleDb 去联机了。

据版工我用 Visual Studio 内建的 press test 工具,测试 OleDb 和 SqlClient 的性能差距,仿真 30 人同时上线,用浏览器撷取一万笔数据,两者的速度就差了一秒钟;且当数据库的数据越多,或越多人同时上线时,性能差距会更明显。

----------------------------------------------

(4) 用程序或软件做缓存

用程序做缓存,如 ASP.NET 从 1.x 时代,就已内建的 Cache (缓存) 机制;或用一些第三方的辅助软件、Framework,这方面若有其它网友知道好用的软件,亦恳请留言告知。

----------------------------------------------

(5) 用硬件做快取或缓冲、砸钱加装 AP Server

ITHome - 游戏基地网页效能提升的关键人物 (此连结连至台湾网页,若无法开启敬请见谅) :
http://www.ithome.com.tw/itadm/article.php?c=52558

以下引用自原文:

种种缺失使得网站的使用人数锐减。面对网站一堆问题,陈xx也决定要将网站再次大幅度调整,将之前的网页程序,以及 SQL 查询语句全部重写,他们花了三个月的时间执行。

陈xx还在原本的网页服务器,与数据库服务器的架构中,加入一组应用程序服务器,作为网页服务器 cache 数据的来源。

改版之后的新网站,搜寻速度提升许多,先前每日的统计数据中,处理速度超过 3 秒的数据超过 50 万笔;而改版后,每星期超过 3 秒的查询不到 10 笔,而这少数反应速度不够快的查询,也多是内部作业执行大量批处理导致的。

由于原本使用的 L4 Switch 较为老旧,负载量比较差,因此陈xx选择将它汰换新的设备,加强负载量;恰好那时正好准备将应用服务器的架构上线,就藉此机会将网络架构更新。陈xx说,这样的架构搭配负载较强的 L4 交换器,强化网站的处理性能,并凭借此抵御网络攻击。在此之后,网站依然会受到零星攻击,但都不会对造成太大影响。

----------------------------------------------

(6) 用硬件做快取或缓冲、砸钱加装 AP Server

数字之墙 - 网站外销的个人实践(二)运营 (此连结连至台湾网页,若无法开启敬请见谅) :
http://epaper.pchome.com.tw/adm/brief_left.htm?s_code=0263

以下引用自原文:

全盛时期,来自美国 blog 的流量每天达 80 万次。这个数字其实不高,对程序高手来说是小菜一碟,但笔者是半吊子工程师,知识有限也因此可能程序写得不好,频频被主机供货商发信警告,要求改善网站系统性能。最后,我决定开发 cache system。

cache system 缓存系统上线后,将数据库读写,从每天 80 万次降低到每天 16 万次。这期间也请高手朋友帮忙进行数据库结构优化,帮助很大。笔者在过程中学习到,一个良好的「缓存系统 (cache system)」对于提供 Widget 功能的网站来说非常重要。

…中间略…

能够做到随时搬迁整个网站到另一家主机供货商,除了程序本身的调整外,还要归功于网站管理软件的盛行。在此要推荐的一套称为 Plesk 的网站管理软件。有的主机供货商会直接帮你安装 Plesk ,免费或另外付费。 Plesk 的所有管理功能都是透过 Web 界面,方便到无以复加,大大降低对技术能力的要求。

除了 Plesk 以外,网站管理软件还有其它选择。还有 WHM 加上 cPanel 的组合,也是常见的网站管理解决方案。不过笔者还是比较偏好使用 Plesk,毕竟使用起来容易,也难怪他们的市场占有率一直是独大。只是,功力高的工程师可能会喜欢 WHM + cPanel,因为弹性比较大。不论选择哪一种,都可以帮助你节省许多时间。

----------------------------------------------

(7) 加装实体机器做 Loading Balance (负载平衡)。一些 Server OS 亦内建此类设定功能。

----------------------------------------------

(8) 程序技巧 - ADO.NET

能用 DataReader 就不要用 DataSet / DataTable,前者读取速度快又不耗内存;后者虽较有弹性,但速度较慢又会每个使用者消耗许多内存。若您连 DropDownList 控件的数据来源,都用 SqlDataSource 控件的默认值 - DataSet,则当页面里塞了一堆下拉选单时,当然性能会受影响。

但前提是程序员对 ADO.NET 要有一定程度的了解,若只会用 Visual Studio 透过图形界面,拖拉 TableAdapter、DataTable、.xsd 就免谈了。

若为 DataTable 建立 Primary Key,DataTable 会建立一个索引,追踪新增到 DataTable 中的数据是否符合此条件约束 (constraint)。ADO.NET 2.0 会使用 algorithm 的「红黑树算法 (Red-Black Tree,是一种「平衡树」算法) 处理索引,让 DataTable 的数据量大时,较方便维护索引;但缺点是建立索引时会降低一性能。


此外,数据库的走访和捞值,应该尽量在一次 DB connection 做完,一个 connection 可搭配多个 DbCommand 对象使用,不用每次都一个 DbConnection 配一个 DbCommand。


在此推荐一本不错的 ADO.NET 原文书:

Programming Microsoft ADO.NET 2.0 Core Reference
http://www.amazon.com/Programming-Microsoft%C2%AE-ADO-NET-Core-Reference/dp/073562206X/ref=sr_1_1?ie=UTF8&s=books&qid=1230971264&sr=1-1

有探讨到许多市面上书籍少见的深入内容,像 Oracle + ADO.NET 的各种应用、Connection Pooling 的特性、各种的数据库 Balk (批次) 作业应用。


请参考:

适时调整 SqlDataSource 控件的 DataSourceMode 属性:
http://www.cnblogs.com/WizardWu/archive/2008/07/15/1243661.html

使用 ADO.NET 的 NextResult 方法取得多个 Result Set:
http://www.cnblogs.com/WizardWu/archive/2008/07/11/1241174.html

----------------------------------------------

(9) 程序技巧 - .NET 语法

* 避免一些书上教的,把 DataTable 或大量数据,直接塞到 Session,此举在真正要上线的系统必死无疑。Session 在多人同时上线时,内存的消耗是很可观的,因为 Session 是每个用户各存一份在服务器的内存里,而非像「缓存 (cache)」是所有的用户共享服务器的一块内存。在很多 ASP.NET 的需求中,可用 ViewState 或 HiddenField 控件取代 Session。

* 能用「泛型 (Generics)」就不要用旧版的写法,Generics 除了安全外,亦可避免 .NET 类型在 Boxing / Unboxing 转型时影响性能,例如:
动态数组中,能用 List 就不要用旧的 ArrayList,能用 Dictionary 就不要跑双层的循环 (loop)。

当然上述前提,是系统要用 .NET 开发,还在靠 ASP 或非 OOP 语言硬撑的旧系统就免谈了。

----------------------------------------------

(10) 程序技巧 - 数据库「事务 (Transaction)」

您是否知道 SQL Server 的默认「事务隔离等级 (Isolation Level)」,是「ReadCommitted」,当您在写 ADO.NET 用了 SqlTransaction 时,默认是当某个人在修改某一笔记录时,其它所有读取这一笔记录的人,都会被「锁定 (lock)」住,造成其它全部用户的浏览器都在等待中,无法做其它工作。

而 Oracle 事务的特性,是绝不会有类似无法读取的情形,至少会用类似 SQL Server 2005 新增的「快照隔离 (Snapshot Isolation)」,让用户至少能先读取到未 Commit 或 Rollback 的记录,而不用呆坐在浏览器前面傻等。

不过 SQL Server 2005 的「快照隔离」默认未启用。用 SQL Server 开发的系统,若怕用户被锁定的问题,可视 project 需求,改用最宽松的「ReadUncommitted」事务隔离等级,其特性为不会造成任何锁定,但可能会造成 Dirty Read。SQL Server 有下列七种「事务隔离等级」,有兴趣的网友可去查询 ADO.NET 书籍或 MSDN Library:

Chaos
ReadCommitted  // SQL Server 默认值
ReadUncommitted // 最宽松,会有 Dirty Read
RepeatableRead
Serializable    // 最严,会有大量的锁定
Snapshot
Unspecified


请参考:

Oracle 11g 学习笔记 (5):
http://www.cnblogs.com/WizardWu/archive/2008/12/07/1349665.html

----------------------------------------------

(11) ASP.NET 分页

GridView + SqlDataSource 的默认行为,就是每次换页或排序时,不管数据库有几笔记录都全部重捞一次;当数据库有一百万笔数据,就在每个用户换页时,都一百万笔全部重捞出来,此举消耗了大量的 Web server/ AP server 内存、数据库系统资源、网络频宽,结果网站性能可想而知。

很多企业内的小型网站,为了省钱,随便外包给低价抢标的工作室,或没经验的学生和 SOHO 族,可能都因此已经埋下了恐怖的后遗症。


请参考:

ASP.NET 数据分页 1 ~ 4 篇 series :
(有现成的 ASP.NET 2.0 + ObjectDataSource 控件 + Stored Procedure 做「分页」的示例可下载)
http://www.cnblogs.com/WizardWu/archive/2008/09/28/1301616.html
http://www.cnblogs.com/WizardWu/archive/2008/09/07/1286270.html
http://www.cnblogs.com/WizardWu/archive/2008/08/06/1261589.html
http://www.cnblogs.com/WizardWu/archive/2008/08/02/1258832.html
http://blog.sina.com.tw/4907/article.php?pbgid=4907&entryid=3921

----------------------------------------------

(12) Design Patterns

虽然「设计模式」不是为解决性能问题而诞生的,但可适度防止没经验的新人做出蠢事。多学一些 .NET 技术敌营注重的系统架构、OOAD、Design Patterns 和相关 Framework,对提升自己的身价和薪资也有帮助。


相關書籍:

C# 3.0 Design Patterns:
http://oreilly.com/catalog/9780596527730/index.html

Head First Design Patterns:
http://oreilly.com/catalog/9780596007126/index.html

----------------------------------------------

 

0
0
 

热门文章

    最新文章

      最新新闻

        热门新闻