zoukankan      html  css  js  c++  java
  • 【高性能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之类的工具可以稍微帮你一下) ,

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

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

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

  • 相关阅读:
    C++每次读取一行字符串输入(学习笔记) (转)
    Ubuntu使用Windows下的conio.h
    容斥原理、欧拉函数、phi
    UVa1635
    转:用STL中的vector动态开辟二维数组
    [转载]Vector用法(C++ Primer中文版)
    c++中vector的pair与make_pair的使用,双关键字排序
    uva12716 GCD XOR
    在 Ubuntu 14.04 中安装 Pepper Flash Player For Chromium
    Careercup
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/2218291.html
Copyright © 2011-2022 走看看