在hyper v中运行应用程序的大量性能问题

时间:2012-12-11 12:35:13

标签: c# .net performance console-application hyper-v

更新:Se底部:添加了CreateArticleRelations代码示例。

好的,这是一个棘手的问题。在预览和生产环境方面,我在hyper-v中遇到了巨大的性能问题。

首先,这是设置。

所有服务器上的.NET 4.0。

预览

Webserver:虚拟机,8GB内存,4个cpu,windows server 2008 r2(64)

数据库:虚拟服务器,6GB ram,2个cpu,windows server 2008 r2(64)

生产

Webserver:虚拟机,8GB内存,4个cpu,windows server 2008 r2(64)

数据库:物理机,48 gb ram,16 cpu,windows server 2008 r2(64)

这是一家运营这些商店的B2B商店。当为一个产品运行集成时,结果对我来说是令人兴奋的。我会提供照片。

在预览中运行一个产品需要83秒,以便更新所有内容。 在生产中运行一个产品需要301秒(!)来更新所有内容。相同的产品!

如果我在本地运行,则需要大约40秒才能完成。

我已经在两台服务器上运行了dotTrace profiling,以实际查看花费时间的内容。我使用EnterpriseLibrary进行日志记录,使用umbraco作为cms,使用uCommerce作为商务平台。请看下面我看到的一个发现的图片示例。

enter image description here

首先,CreateArticleRelations在生产服务器上需要140秒,但在预览中只需要46秒。相同的产品,相同的数据。然后到真正时髦的东西。在顶部的生产现场,我们看到企业家在64秒内完成,但是在预览运行中,它已经下降,所以甚至不能说绝对没有时间。

日志记录的实现看起来像这样。

      private string LogMessage(string message, int priority, string category, TraceEventType severity, int code, int skipFrames = 2)
  {
     //Check if "code" exists in eCommerceB2B.LogExceptions
     var dbf = new ThirdPartSources();
     var exeptions = dbf.GetLogExeptions();
     foreach (var exeption in exeptions)
     {
        if (code.ToString() == exeption)
           return DateTime.Now.ToString();
     }


     try
     {
        var stack = new StackTrace(skipFrames);

        if (_logWriter.IsLoggingEnabled())
        {
           var logEntry = new LogEntry
                              {
                                 Title =
                                     stack.GetFrame(0).GetMethod().ReflectedType.FullName + " " +
                                     stack.GetFrame(0).GetMethod(),
                                 Message = message,
                                 Priority = priority,
                                 Severity = severity,
                                 TimeStamp = DateTime.Now,
                                 EventId = code
                              };

           logEntry.Categories.Add(category);

           _logWriter.Write(logEntry);

           return logEntry.TimeStampString;
        }

日志记录设置为滚动平面文件和数据库。我试图禁用日志记录并节省大约20秒,但LogMessage仍然在顶部。

这已经让我头疼了好几天,我似乎无法找到解决方案。当然,我可以完全删除日志记录,但我不想找到问题的原因。

困扰我的是,例如,在生产服务器上运行一个方法(CreateArticleRelations)需要几乎4倍的时间。 CPU级别永远不会超过30%,并且可以使用5 GB RAM。应用程序作为控制台应用程序运行。

有人请救救我! :)如果需要,我可以提供更多数据。我敢打赌,这与虚拟服务器有关,但我不知道要检查什么。

更新

根据评论,我试图完全注释掉LogMessage。它完全节省了大约100秒,这告诉我某些事情是非常错误的。在预览中仍然需要169秒创建关系与46秒,并且仍然启用预览日志记录。企业库如何使其表现如此?而且,为什么我的代码在生产服务器上运行速度慢4倍?删除LogMessage后的Se图像。它来自PRODUCTION。

enter image description here

CreateArticleRelations

        private void CreateArticleRelations(Product uCommerceProduct, IStatelessSession session)
    {
        var catalogues = _jsbArticleRepository.GetCustomerSpecificCatalogue(uCommerceProduct.Sku).CustomerRelations;
        var defaultCampaignName = _configurationManager.GetValue(ConfigurationKeys.UCommerceDefaultCampaignName);
        var optionalArticleCampaignName = _configurationManager.GetValue(ConfigurationKeys.UCommerceDefaultOptionalArticleCampaignName);

        var categoryRelations =
            session.Query<CategoryProductRelation>()
                .Fetch(x => x.Category)
                .Fetch(x => x.Product)
                .Where(
                    x =>
                    x.Category.Definition.Name == _customerArticleCategory && x.Product.Sku == uCommerceProduct.Sku)
                .ToList();

        var relationsAlreadyAdded = _categoryRepository.RemoveCataloguesNotInRelation(catalogues, categoryRelations,
                                                                                      session);

        _categoryRepository.SetArticleCategories(session, relationsAlreadyAdded, uCommerceProduct, catalogues,
                                                 _customerCategories, _customerArticleCategory,
                                                 _customerArticleDefinition);

        //set campaigns and optional article
        foreach (var jsbArticleCustomerRelation in catalogues)
        {
            // Article is in campaign for just this user
            if (jsbArticleCustomerRelation.HasCampaign)
            {
                _campaignRepository.CreateCampaignAndAddProduct(session, jsbArticleCustomerRelation, defaultCampaignName);
            }
            else // remove the article from campaign for user if exists
            {
                _campaignRepository.DeleteProductFromCampaign(session, jsbArticleCustomerRelation, defaultCampaignName);
            }

            // optional article
            if(jsbArticleCustomerRelation.IsOptionalArticle) 
            {               
                _campaignRepository.CreateCampaignAndAddProduct(session, jsbArticleCustomerRelation, optionalArticleCampaignName);
            }
            else
            {
                _campaignRepository.DeleteProductFromCampaign(session, jsbArticleCustomerRelation, optionalArticleCampaignName);
            }
        }            
    }

我们几乎在每一行都以某种方式点击数据库。例如,在DeleteProductFromCampaign中,以下代码在预览环境中需要43秒,在生产环境中需要169秒。

        public void DeleteProductFromCampaign(IStatelessSession session, JSBArticleCustomerRelation jsbArticleCustomerRelation, string campaignName)
    {
        var productTarget =
            session.Query<ProductTarget>()
                   .FirstOrDefault(
                       x =>
                       x.CampaignItem.Campaign.Name == jsbArticleCustomerRelation.CustomerNumber &&
                       x.CampaignItem.Name == campaignName &&
                       x.Sku == jsbArticleCustomerRelation.ArticleNumber);

        if (productTarget != null)
        {
            session.Delete(productTarget);
        }
    }

因此,此代码在生产服务器上运行速度慢4倍。服务器之间的最大区别在于生产(物理)服务器设置了无用的实例,而我正在使用其中一个(20 gb om ram)。

0 个答案:

没有答案