2015-02-09 41 views
2

我很抱歉提前对长篇文章,因为我一直在收集诊断,但似乎不能把我的手指放在这个问题上。DbContext/Ninject相关性GetService缓慢SingleOrDefault负载测试

EF6 /网络API 2

首先,我注意到一个缓慢运行的端点和负荷下测试得到的更糟。

代码:

//configuration 
kernel.Bind<T>() 
.To<T>() 
.InTransientScope() 

//Caller elsewhere in code base 
public http.IDependencyScope BeginScope() 
{ 
    return new NinjectScope(_kernel.BeginBlock()); 
} 


public class NinjectScope : IDependencyScope 
{ 
    public object GetService(Type serviceType) 
    { 
    Debug.WriteLine("COREIOC_Enter GetService Timein: {0}", DateTime.Now.ToLongTimeString()); 
    Stopwatch coreIOC = new Stopwatch(); 
    coreIOC.Start(); 

    IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true); 
    Debug.WriteLine(string.Format("COREIOC_Complete CreateRequest Elapsed: {0}", coreIOC.Elapsed)); 

    var abc = resolutionRoot.Resolve(request); 
    Debug.WriteLine(string.Format("COREIOC_Resolve Elapsed: {0}", coreIOC.Elapsed)); 

    var xyz = abc.SingleOrDefault(); 
    Debug.WriteLine(string.Format("COREIOC_SingleDef Resolve Elapsed: {0}", coreIOC.Elapsed)); 

    coreIOC.Stop(); 
    Debug.WriteLine(string.Format("COREIOC_Exit Elapsed: {0}", coreIOC.Elapsed)); 

    return xyz; 
    } 
} 

调试输出:(注意SingleDef是4秒)

COREIOC_Enter GetService Timein: 7:15:56 AM: 
COREIOC_Complete CreateRequest Elapsed: 00:00:00.0008914 
COREIOC_Resolve Elapsed: 00:00:00.0032197  
COREIOC_SingleDef Resolve Elapsed: 00:00:04.4787988 
COREIOC_Exit Elapsed: 00:00:04.4803695 

有趣的后续调用显示此 “旋转起来” 的时间消失了

COREIOC_Enter GetService Timein: 7:27:08 AM: 
COREIOC_Complete CreateRequest Elapsed: 00:00:00.0000266 
COREIOC_Resolve Elapsed: 00:00:00.0018957 
COREIOC_SingleDef Resolve Elapsed: 00:00:00.0307401 
COREIOC_Exit Elapsed: 00:00:00.0354408 

所以这将是一个打开和关闭的情况下除非下一个负载测试中的端点表示EVERY呼叫4秒的延迟。 (例如同时250试运行将显示每个人服用4+秒)。

手写负载测试代码:

public override IEnumerator<WebTestRequest> GetRequestEnumerator() 
{ 
    WebTestRequest request6 = new WebTestRequest("http://localhost:57874/api/acts/10553697"); 
    request6.Timeout = 120; 
    request6.Method = "GET"; 
    request6.Headers.Add(new WebTestRequestHeader("Authorization", "Bearer h0aHdT6...")); 
    request6.Headers.Add(new WebTestRequestHeader("Accept","application/...")); 
    request6.Headers.Add(new WebTestRequestHeader("ContentType", "application/json")); 
    request6.ValidateResponse += new EventHandler<ValidationEventArgs>(request6_ValidateResponse); 
    yield return request6; 
    request6 = null; 
} 

所以

  1. 是我的负载测试不正确或,
  2. 我的EF 6的设置不正确或,
  3. 是我的对象重用不正确的,或者
  4. 是有proble m与我实际使用SingleOrDefault?

我一直在通过ninject实例化的对象的构造函数,并没有看到它们导致延迟。

我的确遇到过SO post,作为一名PluralSight粉丝,我能够立即访问课程。然而,这是一个七小时的课程,最后我不确定这是EF造成延误。

回答

0

对不起,任何人关注。我想通了,但忘了在这里更新。

所以你可以说问题出在Ninject上......但是你也可以做出一个强有力的例子,那就是我们的设计是问题所在。

在一天结束时,我会说这是我们的设计是问题所在。 Ninject的一点灵活性可能会让设计不再成为一个问题,但如果一个糟糕的设计从未出现,那么它的设计仍然很糟糕?

无论如何,我们的终端在他们执行的操作中是灵活的。这很好,除了再加上Ninject所有的东西,即使它不是必需的。

例如,一个端点可能有13个注入对象,但是对于给定的操作只需要3个(其他10个将被其他消费者使用)。

不管只需要3个Ninject会实例化所有的13分钟和10分钟以下的750分钟恒定负载...这是很多JITting正在进行。

因此,为了更具体的目的,爆发了几个终点,并且jit时间急剧下降。

从上面的例子:

13喷射在一端点对象成为:

  1. 3注入对象
  2. 5喷射的对象
  3. 4喷射的对象
  4. 3个注入对象

因此,终点1-4不等于13,因为现在有一些冗余。同样的对象是通过一些端点注入的,但是在一天结束时,所有的东西都会像我们所期望的那样在负载下运行。