如何实现更好的网站性能

And*_*air 6 asp.net performance iis-7

我在那儿!

我在Windows 2008服务器上运行IIS7.
在偷看时间,我们有以下行为:

  • CPU负载接近空闲
  • 请求排队(使用资源监视器监视)
  • 执行时间超过10秒

1-4)请参阅以前的版本和编辑

5)做东西异步

正如所建议的那样,我创建了一个简单的网页......一个页面......这个代码隐藏:

using System;
using System.Threading;
using System.Web;
using System.Web.UI;

namespace PerformanceTest
{
    public partial class AsyncPage : Page
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            var pageAsyncTask = new PageAsyncTask(this.BeginAsyncOperation, this.EndAsyncOperation, this.TimeoutAsyncOperation, null);
            this.RegisterAsyncTask(pageAsyncTask);
            // or
            //this.AddOnPreRenderCompleteAsync(this.BeginAsyncOperation, this.EndAsyncOperation);

            // this might be useful for doing cleanup or sth alike
            this.PreRenderComplete += HandlePreRenderComplete;
        }

        private void HandlePreRenderComplete(object sender, EventArgs e)
        {
            this.Trace.Write("HandlePreRenderComplete");
            this.Trace.Write(string.Format("managedThreadId #{0}", Thread.CurrentThread.ManagedThreadId));
        }

        private delegate void Sleep(int miliseconds);

        private IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback asyncCallback, object state)
        {
            this.Trace.Write("BeginAsyncOperation");
            this.Trace.Write(string.Format("managedThreadId #{0}", Thread.CurrentThread.ManagedThreadId));

            var sleep = new Sleep(Thread.Sleep);
            return sleep.BeginInvoke(1000, asyncCallback, state);
        }

        private void EndAsyncOperation(IAsyncResult asyncResult)
        {
            this.Trace.Write("EndAsyncOperation");
            this.Trace.Write(string.Format("managedThreadId #{0}", Thread.CurrentThread.ManagedThreadId));
        }

        private void TimeoutAsyncOperation(IAsyncResult asyncResult)
        {
            this.Trace.Write("TimeoutAsyncOperation");
            this.Trace.Write(string.Format("managedThreadId #{0}", Thread.CurrentThread.ManagedThreadId));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

看起来挺好的,不是吗?实际上它没有任何改变,因为压力超过30秒,响应时间上升到8秒,CPU使用率接近0%.

6)更新了machine.config

<system.net>
    <connectionManagement>
        <add address="*" maxconnection="12" />
    </connectionManagement>
</system.net>
<system.web>
    <processModel autoConfig="true"
                  maxWorkerThreads="100"
                  maxIoThreads="100"
                  minWorkerThreads="50"
                  minIoThreads="50" />
    <httpRuntime minFreeThreads="88"
                 minLocalRequestFreeThreads="76" />

</system.web>
Run Code Online (Sandbox Code Playgroud)

Asb*_*erg 1

答案很简单:

不要阻塞线程

事实上,IIS 和 ASP.NET AppDomain 只能处理 N 个并发请求。您可以增加这个数字,但是对数千个并发运行的线程进行完全锁定是一个瓶颈噩梦。如果不确切知道是什么导致 ASP.NET 页面在不到一秒的时间内做出响应,就很难提出任何性能调整建议,但这里的问题可能不在于 IIS,而在于代码。

如果代码阻塞线程几秒钟而没有实际执行任何操作(正如 CPU 使用情况所证明的那样),则存在某种 IO 速度太慢,显然应该异步进行。如果这些请求不阻塞线程,Web 服务器可以处理几乎无限量的并发请求(仅受可用硬件资源的限制)。如果它们阻塞线程,则它只能执行与可用线程一样多的请求,这有一个硬性上限。

异步做事

Begin...重写您的代码,这样它就不会通过调用和End...方法而不是它们的同步兄弟来锁定线程。异步CTP可以帮助将这些 Begin 和 End 调用包装在看起来同步的代码中,但这里的性能优势看起来非常巨大,以至于您应该考虑重写锁定页面的任何代码,即使没有这些内容async

  • 仅增加并发线程数量只能达到此目的。真正的问题是每个请求在等待 IO 时都会锁定线程。Begin 不会锁定线程,而是会释放线程,以便其他请求可以使用它,而 End 只会在结果准备好时在处理结果所需的纳秒内被调用。 (2认同)