2

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

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

首先,这里是设置。

所有服务器上的 .NET 4.0。

预习

网络服务器:虚拟机,8gb 内存,4 cpu,windows server 2008 r2 (64)

数据库:虚拟服务器、6gb 内存、2 个 cpu、windows server 2008 r2 (64)

生产

网络服务器:虚拟机,8gb 内存,4 个 cpu,windows server 2008 r2 (64)

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

这是一个在这些上运行的 B2B 商店。当为一种产品运行集成时,结果让我大吃一惊。我会提供图片。

在预览中运行一个产品需要:83 秒才能更新所有内容。在生产中运行一种产品需要 301 秒 (!) 才能更新所有内容。同款产品!

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

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

在此处输入图像描述

首先,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 内存可用。这些应用程序作为控制台应用程序运行。

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

更新:

根据评论,我尝试完整地注释掉 LogMessage。它总共节省了大约 100 秒,这告诉我有些事情是非常错误的。仍然需要 169 秒来创建关系,而在预览中需要 46 秒,并且在预览中日志记录仍处于启用状态。企业库使其以这种方式运行可能有什么问题?而且,为什么我的代码在生产服务器上运行速度要慢 4 倍?删除 LogMessage 后的图像。它来自生产。

在此处输入图像描述

创建文章关系

        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)。

4

0 回答 0