首页 > 解决方案 > 解决 IIS 服务器挂起问题

问题描述

我有一个非常基本的 web api,它使用实体框架来访问 SQL 服务器后端。api 代码只是将请求传递给一些存储的过程并返回数据;没什么特别的。我正在使用 .net 4.6(因为我在 win 2008 标准上运行而受到限制)。我没有使用异步/等待,因为我再次受到不支持该模式的旧日志库的限制。

我正在运行一个突发测试,其中我创建了 30 个同时调用一个 api 端点的线程。每个线程将在调用之间等待一秒钟。这会产生大约 20 个请求/秒的负载。

当我运行测试时,性能很好。调用在 < 50 毫秒内返回。然后,大约两分钟后(总是在同一时间),asp.net 将开始排队请求(根据 perf mon),然后突然间 IIS 将挂起并且我会超时。CPU 将飙升至 99%,这很奇怪,因为我的代码都是异步等待数据库调用的。性能不会像大多数情况下那样稳步下降。这很好,而且很快,直到突然之间就不是了。

我的代码没有抛出任何错误。事件日志中没有任何用处。我拥有所有默认的 IIS 设置,除了在其他地方阅读该建议后我将 http.sys 队列限制从 1000 更改为 5000,但这没有帮助。

关于我可以尝试或查看或做什么的任何建议?我在这里有点难过。

编辑:错误地说我正在使用异步/等待。我不是。

这是代码,减去变量赋值和其他不相关的代码。api调用进入top方法,然后是第二个,然后是第三个

[HttpGet]
    [Route("productvariantassociationids")]
    public LocatorServiceOutputModel GetProductVariantAssociationIds([FromUri]ProductVariantInput input)
    {
        var output =  ProductService.GetProductVariantAssociationIds(input);

        if ((output == null) || (output.Data == null) || (((List<int>)output.Data).Count == 0))
            throw new HttpResponseException(System.Net.HttpStatusCode.NotFound);

        return output;
    }

public LocatorServiceOutputModel GetProductVariantAssociations(ProductVariantInput input)
    {   
        var output = new LocatorServiceOutputModel();
        var cachedData = CacheService.Get<List<ProductVariantAssociation>>(input.ToString());

        if (cachedData != null)
        {
            output.Data = cachedData;
            output.FromCache = true;                
        }
        else
        {
            var associations = ProductRepository.GetProductVariantAssociations(input.ProductLineTypeID, input.ProductVersionTypeID, input.FormCodeTypeID, input.PremiumStructureTypeID,
                                                                            input.DefinitionOfDisabilityTypeID, input.StateTypeID, input.ApplicationDate, input.InsurredAge);

            var mappedAssociations = Mapper.Map<List<ProductVariantAssociation>>(associations);
            CacheService.Set(input.ToString(), mappedAssociations);

            output.Data = mappedAssociations;
        }

        output.Success = true;
        return output;
    }

public List<DBRiderBenefit> GetRiderBenefits(int? productVariantAssociationID = null, StateTypeEnum? stateTypeID = null, int? insurredAge = null, DefinitionOfDisabilityTypeEnum? definitionOfDisabilityType = null,
                                                EliminationPeriodTypeEnum? eliminationPeriodTypeID = null, BenefitPeriodTypeEnum? benefitPeriodTypeID = null, MentalSubstanceLimitationEnum? mentalSubstanceLimitationID = null,
                                                OccupationClassTypeEnum? occupationClassTypeID = null, OccupationGroupTypeEnum? occupationGroupTypeID = null, string occupationTypeValueText = null,
                                                bool? isExercise = null, string callingSystemID = null, int? productVersionRevisionId = null)
    {
        using (ProductLibraryContext context = new ProductLibraryContext())
        {

            List<DBRiderBenefit> results = null;

            if (productVersionRevisionId != null)
            {
                results = context.Database.SqlQuery<DBRiderBenefit>("exec [USP_ProductLibrary_Get_RiderBenefit] @ProductVariantAssociationID, @StateTypeID, @IssuredAge, @DefinitionOfDisabilityID, @EliminationPeriodTypeID, @BenefitPeriodTypeID, @MentalSubstanceLimitationID, @OccupationClassTypeID, @OccupationGroupTypeID, @OccupationType_ValueText, @IsExercise, @CallingSystemId, @ProductVersionRevision"
                                                                                , paramProductVariantAssociationID, paramStateTypeID, paramInsuredAge, paramDefinitionOfDisabilityID, paramEliminationPeriodTypeID, paramBenefitPeriodTypeID
                                                                                , paramMentalSubstanceLimitationID, paramOccupationClassTypeID, paramOccupationGroupTypeID, paramOccupationTypeValueText, paramIsExercise, paramCallingSystemId, paramProductVersionRevision).ToList();
            }
            else
            {
                results = context.Database.SqlQuery<DBRiderBenefit>("exec [USP_ProductLibrary_Get_RiderBenefit] @ProductVariantAssociationID, @StateTypeID, @IssuredAge, @DefinitionOfDisabilityID, @EliminationPeriodTypeID, @BenefitPeriodTypeID, @MentalSubstanceLimitationID, @OccupationClassTypeID, @OccupationGroupTypeID, @OccupationType_ValueText, @IsExercise, @CallingSystemId"
                                                                                , paramProductVariantAssociationID, paramStateTypeID, paramInsuredAge, paramDefinitionOfDisabilityID, paramEliminationPeriodTypeID, paramBenefitPeriodTypeID
                                                                                , paramMentalSubstanceLimitationID, paramOccupationClassTypeID, paramOccupationGroupTypeID, paramOccupationTypeValueText, paramIsExercise, paramCallingSystemId).ToList();
            }

            return results;
        }
    }

标签: performanceiisiis-7performance-testing

解决方案


推荐阅读