如何实现更好的网站性能

时间:2011-09-28 08:34:55

标签: asp.net performance iis-7

Hy那里!

我在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));
        }
    }
}
好像很好,不是吗?实际上它没有任何变化,因为压力超过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>

4 个答案:

答案 0 :(得分:3)

答案 1 :(得分:2)

您使用Page,可能还有Session,因此每个页面因会话而加载锁定所有其他页面。 !因此,您可以将其称为异步,或调用PageAsyncTask,但由于会话,页面将锁定所有其他调用,并且页面调用将在一行中执行。

仅为测试禁用会话,如果您不使用任何会话数据,请对此页面禁用它。

另请注意:Replacing ASP.Net's session entirely

Web Garder

您可以设置一个Web园,即为同一个Web应用程序提供更多池。通过这样做,您需要重新检查所有代码并包含与互斥锁或数据库锁的同步,因为对于两个或更多池,相同的数据可以由不同的线程进行访问和写入。

http://msdn.microsoft.com/en-us/library/aa479328.aspx

答案 2 :(得分:1)

答案很简单:

不要阻止线程

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

如果代码在没有实际执行任何操作的情况下阻塞线程几秒钟(因为CPU使用情况见证了),那么某种类型的IO很慢,显然应该是异步的。如果这些请求不阻止线程,则Web服务器可以服务几乎无限量的并发请求(仅受可用硬件资源限制)。如果它们阻塞线程,它只能执行与可用线程一样多的请求,这些线程有一个硬上限。

异步执行

重写您的代码,使其不会通过调用Begin...End...方法而不是同步兄弟来锁定线程。 Async CTP可以帮助将这些Begin和End调用包装在看起来同步的代码中,但是这里的性能优势看起来如此之大,以至于您应该考虑重写任何代码,即使没有{ {1}}东西。

答案 3 :(得分:1)

我们曾遇到过类似的问题。事实证明,导致问题的不是我们的代码。

在我们的案例中,问题出在Windows 2008 R2中的TCP Chimney卸载。 Windows 2008通过将工作卸载到网卡来实现聪明,但如果网卡出现问题,速度会变慢,但所有正常的性能值都显示负载很小。

http://www.iislogs.com/steveschofield/troubleshooting-iis-7-network-performance-issues-and-tcp-chimney-offload-receive-side-scaling-and-network-direct-memory-access