好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

【高性能web开发】 ASP.NET Web服务器

【高性能web开发】 ASP.NET Web服务器

【高性能web开发】 ASP.NET Web服务器 (一)

本文通过一个特别的案例:最终用户使用浏览器向服务器请求包含100条最新新闻纪录的页面,慢慢的展开。

本文集中在ASP.NET Web服务器(特指用于接收用户请求,处理业务逻辑和响应HTML的服务器; 分布式,客户端,IIS,数据库和应用服务器配置和优化部分,稍后介绍)

 
 

应用程序级别

1.生产环境使用Release版本,而不是Debug版本

关闭所有调试日志和信息 移除所有用于调试,测试和跟踪的代码 使用宏操作可以很方便的关闭和管理这些代码

 #if  DEBUG
Console.WriteLine( "" ); // 日志?输出?调试?
#endif

配置Web.Config关闭调试模式

2.移除不必要的HTTP Module

通过运行时访问HttpContext.Current.ApplicationInstance.Modules确定使用到的Module 通过web.config移除不必要的HTTP Module 例如如果你不想使用Session那么就移除SessionModule   本案例中,由于新闻数据和用户无关,也许我们可以移除很多Module

3.移除不必要的文件

特别是没用的dll和PDB文件

4.启用服务器配置

例如GC运行于服务器模式

5.检查Global等全局性代码和功能

页面级别

1.考虑使用比Aspx轻量级的处理模式,例如ashx(httphandler) 

例如需要一个页面作为接口提供或者接收数据,(而不是返回一堆HTML) aspx页面生命周期过于笨重,速度缓慢 aspx内部经常使用服务器控件,这也是重量级的主 aspx内部服务器控件产生的ViewState等。。。。 个人比较喜欢MVC做页面和WCF做服务

2.避免使用重量级解决方案

Asp.net UpdatePanel  (这东西搞搞管理员模块也就算了,就不要拿到最终用户界面来吓人了) EXT,ComponentArt等重量级第三方解决方案

3.避免太深的页面或者类继承(例如APage:BPage....)

不要设计超级父类,集中了一大堆功能 继承级别过深是较为消耗性能的

4.优化逻辑

例如已经在PageLoad中初始化过的对象,不要在例如按钮点击等事件中再初始化一次 例如不要有这种代码。。。

   DataSet ds =  new  DataSet(); //   无奈的初始化。。。。偶尔还能看到非常重量级的初始化  
ds = ClassA.LoadDataSet();

5.小心使用重量级资源,包括但不仅限于以下内容

Thread Sesssion Application 内核锁 内存 大量小对象 (GC压力,例如大量的使用小字符串),可以使用WinDbg+SOS调查

6. 设计往往对与性能有至关重要的影响

例如长时间的操作,异步比同步性能要好很多 例如大批量同类的操作,批量操作比一次操作一条要好的多 CPU未满,而且希望缩短响应时间,考虑多线程 CPU满了 考虑空间换时间 CPU没满 考虑时间换空间  (注意 IO压力大也会导致CPU100% 这个时候还是考虑空间换时间) 例如设计时候考虑数据和样式分离,每次只要重新拉数据就行了例如每次拉取数据的时候,服务器只返回已经更新了的数据 例如按照更新时间排列,如果更新了早一些的数据;那么每次读取的时候按照更新时间排列就是一个问题,不如在内存中保存最新的100条数据,有更新的话直接把该集合中最旧的一条移除,最新的一条插入 (可以多留几条备用) 这个例子一般是读多写少,读写比例可能达到1000:1,是很好的使用缓存的例子

缓存

1.页面缓存和页面片段缓存

 <%  @ OutputCache Duration  =  "  60  "   VaryByParam  =  "  none  "  %> 

< html >
< script language ="C#" runat ="server" >
void Page_Load(Object sender, EventArgs e)
{
TimeMsg.Text = DateTime.Now.ToString( " G " );
}
</ script >

< body >
< h3 > Using the Output Cache </ h3 >

< p > Last generated on: < asp:label id ="TimeMsg" runat ="server" />
</ body >
</ html >

2.适当的使用使用304缓存,或者浏览器端缓存

3.使用HttpRuntimeCache缓存数据,或使用静态对象缓存数据

如果不需要控制过期时间,或者永不过期,建议用静态对象缓存数据,Cache其实还是很重量的

4.就这个方案而言

可以把这100条数据放在内存中,如果有更新的时候直接更新内存,需要读取的时候直接从内存中读取 缓存的同步和更新永远都是一个大问题,选择不同的缓存取决于你所想要的性能和能承受的缺陷 (例如如果能接受1分钟的的数据延迟,缓存) 良好的线程同步知识,可以减少很多的BUG

代码级别
1.将可能的类设计为封闭的(不可继承)

例如新闻的实体类

2.使用更为有效率的方法

例如使用Request.QueryString[Key] 而不是Request[Key] 例如Int.TryParse,而不是Int.Parse 谨慎使用异常

慢慢补充,未完待续。。。。。。

使用工具测量是很重要的一个方面,例如DotTrace,Visual Studio 2010性能测试工具,LoadRunner等压力测试工具

但是此类工具无法弥补基本概念上的缺失,例如封闭类的性能会比非封闭类的性能好 (在这个方面FxCop之类的工具可以稍微帮你一下) ,

但是工具可以帮你较为准确的测量修改后的性能,最终跑出来的性能才是决定一个优化的价值的关键

此外高性能一般和可维护性是冲突的,需要找一个平衡点

本人水平有限,希望大家一起讨论

【设计原则和建议】 lock

lock是.net中最常用的锁

了解lock机制,引用类型,值类型,字符串和应用程序域的朋友可能对以下的内容都很熟悉了
 

1.先来看看推荐的lock代码

     class  LockDemo
{
private static object asyncLock = new object (); // 使用static object作为互斥资源
public static void Test()
{
lock (asyncLock) // 保证该方法是线程安全的
{
// 程序代码
}
}

private object asyncLock2 = new object (); // 使用object作为互斥资源
public void Test2()
{
lock (asyncLock2) // 保持该方法是线程安全的
{
// 程序代码
}
}
}


2.请保证被lock的对象不会为null

             object  o =  null ;
lock (o) // 如果o有可能为null 会抛出异常
{
}


3.如果类本身是public的 绝对不要在类的内部使用lock(this)

因为从外部有可能lock这个实例

4.严禁lock(typeof(MyType)) ,如果myType具有公开访问性

5.严禁lock(typeof(int)) ,所有的基本类型也是一致的

6.严禁lock("string"),所有想lock同一个string的代码都惨了

7.严禁lock值类型,例如lock(int)...会自动装箱 (只能在Monitor.Enter 模拟,编辑器会阻止lock(int))

8.必要时候双重检查防止代码重复执行

         private   static   bool  condition =  true ;
public static void Test3()
{
if (condition)
{
lock (asyncLock) // 虽然CLR已经提供了很多的方法,不过这个经典模式还是很常用的
{
if (condition)
{
condition = false ;
}
}
}
}

9.lock的基本实现,大家应该都很熟悉了

  object  o =  new   object ();
Monitor.Enter(o);
try
{
// 代码
}
finally
{
Monitor.Exit(o);
}



10.CLR中有两种锁可以不进内核模式,一个是自旋锁,另外一个就是lock,这两个速度都比较快,适合时间很短的锁定 (如果是进内核模式的锁 至少就30ms了)

有朋友指出了lock是混合模式,验证中...

11.使用lock编程简单,比读写锁,信号量等使用方便

12.因为性能和编程原因,某些时候不要使用lock

简单操作用Interlocked 类自带的一些操作 短时间锁定,自旋锁更快 如果可以,优先使用无lock的代码,例如.net新增的线程安全的集合类  适当的时候使用读写锁取代lock (读多写少) 长时间锁定考虑信号量等方案 (例如异步IO操作)

13.一部分类本身提供了一些对象用于锁定

Hashtable.SyncRoot
 

部分内容引用自MSDN,和其他第三方文章

因为本人水平有限,如有遗漏或谬误,还请各位高手指正


作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于【高性能web开发】 ASP.NET Web服务器的详细内容...

  阅读:55次