IIS 8 AppPool 使用过多资源,如何找到罪魁祸首?

IIS 8 AppPool using excessive resources, how to find the culprit?

在我的工作场所,我们已经忙了好几天来维护一个具有相当大的数据库的 .NET Web 应用程序(基于 Umbraco)并且 运行。我们已经使用了书中几乎所有可能的技巧来降低资源使用率,但它根本不起作用。

这是一个非常繁忙的网站,并且实时网站存在严重的性能问题。我们最初在 Azure 上拥有站点 运行 并进行了升级,这看起来还不错(仍然很慢),但是由于 Umbraco 无法正确处理 Azure 上的多个实例*并且需要花费大量时间来修复这些问题,我们被迫将其移至单个非 Azure 专用服务器。

拥有 6 个内核和 12GB 内存,当网站真正活跃时(假设每分钟 100 个请求),该网站仍然会变得疯狂。

呼救声:任何人都可以帮助我们确定是什么原因造成的,因为我们真的 运行 没有想法,只想知道该站点正在做什么,这会耗费大量资源 CPU 以及为什么它储存了接近 2GB 的内存。

当站点不那么活跃时,比如午夜,它运行正常,所以看起来 IIS 确实无法处理那么多的请求(这对我来说似乎不太可能,但没关系)。有什么我们不知道的技巧吗?我们可以在多个处理程序中分离应用程序池吗?

*我们不确定这是 Azure 做的还是 Umbraco 做的,我们查看了源代码,它似乎正确地锁定了文件和线程,但我们仍然遇到了很多实例相互冲突的问题。

这是一个非常广泛的问题,但根据我使用 Umbraco 的经验,我看到的最大性能是在缓存部分视图之后。这是我的实现:

public static class CachedPartialExtensions
{
    public static IHtmlString MyCachedPartial(
                        this HtmlHelper htmlHelper,
                        string partialViewName,
                        object model,
                        int seconds,
                        bool cacheByPage = false)
    {

        var cacheKey = "fpc-";  //prefix to know which keys to clear on page publish 
        cacheKey += cacheByPage ? "page-" + UmbracoContext.Current.PageId : "global";
        cacheKey += partialViewName;

        var partial = HttpContext.Current.Cache[cacheKey] as MvcHtmlString;
        if (partial == null)
        {
            partial = htmlHelper.Partial(partialViewName, model);
            if(partial != null)
            {
                HttpContext.Current.Cache.Add(cacheKey, partial, null,
                    DateTime.Now.AddSeconds(seconds), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
            }
        }
        return partial;
    }

    public static DateTime Hours(this int hours)
    {
        return DateTime.Now.AddHours(hours);
    }
}

例如,如果每个页面的菜单都相同,您将调用

@Html.MyCachedPartial("Global/_Menu", Model, 24.Hours())

如果您有页面特定的局部视图,您会调用

@Html.MyCachedPartial("Global/_PageLeftMenu", Model, 24.Hours(), cacheByPage: true)

我们缓存 24 小时或 publish/unpublish 个事件:

public class MyApplicationEventHandler : ApplicationEventHandler
{
    protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        ContentService.Published += ContentServicePublished;
        ContentService.UnPublished += ContentService_UnPublished;
    }

    void ContentService_UnPublished(IPublishingStrategy sender, PublishEventArgs<IContent> e)
    {
        ClearCache(e.PublishedEntities);
    }

    private void ContentServicePublished(IPublishingStrategy sender, PublishEventArgs<IContent> args)
    {
        ClearCache(args.PublishedEntities);
    }

    private void ClearCache(IEnumerable<IContent> nodes)
    {
        var cacheKeys = ((IEnumerable)HttpContext.Current.Cache).Cast<DictionaryEntry>()
                                                                .Select(de => de.Key.ToString())
                                                                .ToList();

        var cacheKeysToClear = cacheKeys.Where(key => key.StartsWith("fpc-global")).ToList(); 
        foreach (var node in nodes)
        {
            cacheKeysToClear.AddRange(cacheKeys.Where(key => key.StartsWith("fpc-page-" + node.Id)));
        }

        cacheKeysToClear.ForEach(key => HttpContext.Current.Cache.Remove(key)); 
    }
}

在此之后,我们看到了前端性能的显着提升以及 CPU 使用率的显着下降。

希望这对您有所帮助。