【问题标题】:Why is a new AppDomain being created every few seconds (WCF/IIS 7)?为什么每隔几秒就会创建一个新的 AppDomain (WCF/IIS 7)?
【发布时间】:2012-02-17 05:44:31
【问题描述】:

我正在尝试调试一些恶作剧的 MT 代码。最近,最疯狂的事情(在添加大量日志之后)似乎是在我的单工作进程、单机 IIS 托管的 WCF 服务上,在开始时为前几个请求创建了几个应用程序域,然后每个几秒钟后又创建了一个。

下面的每一行都从大致以下堆栈跟踪记录:

AddItem (WCF service method)
calls SomeRepositoryClass.Open (instance of class was created for this request)
calls WritePlanBufferManager constructor (static instance), accessed in lock construct (on static readonly object field)

日志(A=AppDomain.CurrentDomain.Id,T=Thread.CurrentThread.ManagedThreadId):

    Line 1: [21:21:21.7544122 A:002 T:011] Created new WritePlanBufferManager for appdomain 2
    Line 2: [21:21:31.0299427 A:004 T:008] Created new WritePlanBufferManager for appdomain 4
    Line 3: [21:21:36.5912608 A:006 T:012] Created new WritePlanBufferManager for appdomain 6
    Line 4: [21:21:37.9533387 A:008 T:010] Created new WritePlanBufferManager for appdomain 8
    Line 670: [21:21:41.1065191 A:010 T:020] Created new WritePlanBufferManager for appdomain 10
    Line 1336: [21:21:43.4236516 A:012 T:020] Created new WritePlanBufferManager for appdomain 12
    Line 2002: [21:21:45.8347895 A:014 T:020] Created new WritePlanBufferManager for appdomain 14
    Line 2656: [21:21:48.2479276 A:016 T:020] Created new WritePlanBufferManager for appdomain 16
    Line 3322: [21:21:50.9600827 A:018 T:020] Created new WritePlanBufferManager for appdomain 18
    Line 3988: [21:21:53.2752151 A:020 T:010] Created new WritePlanBufferManager for appdomain 20
    Line 4654: [21:21:55.7353558 A:022 T:020] Created new WritePlanBufferManager for appdomain 22
    Line 5320: [21:21:58.0414877 A:024 T:007] Created new WritePlanBufferManager for appdomain 24
    Line 5984: [21:22:00.5546315 A:026 T:020] Created new WritePlanBufferManager for appdomain 26
    Line 6650: [21:22:02.9327675 A:028 T:020] Created new WritePlanBufferManager for appdomain 28
    Line 7316: [21:22:05.4109092 A:030 T:020] Created new WritePlanBufferManager for appdomain 30
    ....many more

还有很多我正在尝试解决的其他问题,但最初我想将我的问题一次限制在一个 AppDomain 上。

每个WritePlanBufferManager 对象都用于创建多个 (~13) 线程,用于延迟/异步排队和处理项目。

服务配置是标准的、最小的、开箱即用的。 Web.config 几乎是空的,并且没有 WCF 配置。

应用程序池的最大工作进程数 = 1,快速故障保护/启动/关闭/Ping 全部禁用。该服务受到来自单个客户端、单个线程的请求的冲击。

那么,基本问题 - 为什么我会获得多个 AppDomain,为什么会频繁创建额外的 AppDomain?


更新:似乎我的 AppDomain 正在卸载,并且所有线程在几秒钟(大约一分钟)后中止。但是,在应用程序池上没有 CPU 限制、几天的空闲超时、最多 1 个工作进程、禁用 Ping(并且超时设置为几天)、禁用快速故障保护并且关闭所有进程回收选项。

所以,问题变成了,为什么我的 AppDomain(s) 被卸载 - 事件日志中没有任何内容 - 因此我的线程被中止?

【问题讨论】:

    标签: wcf iis iis-7


    【解决方案1】:

    听起来您的服务InstanceContext 是针对每个呼叫或每个会话配置的。 WCF 确实实现了一个实例缓存机制,因此您会看到该进程启动。

    如果您想要一个真正的单例实例实现,那么您需要将 InstanceContext 设置为 single(并根据您的问题信息将 ConcurrencyMode 设置为多线程)。获取单例实例的另一种方法是编写代码以使用 ServiceHost 的this constructor

    我不鼓励在生产中使用单例 WCF 服务实例,因为我相信 WCF 框架通过每次调用实例化处理请求比我自己滚动处理请求做得更好。 YMMV :)

    【讨论】:

    • 我现在就试一试。与此同时 - 我的部分调用必须在服务返回之前执行,并且 90% 的工作可以在接下来的几秒钟内执行,并且更好地进行批处理和持久化。我认为“静态保留”的线程管理器可以很好地完成这项工作。在您看来,什么是合适的替代方案?我真的需要向 Windows 服务等添加另一个往返吗?
    • 没有雪茄,恐怕。完全相同的行为,我正在使用[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]。最初只有 3 个应用域,但仍然不止一个..
    • 为了清楚起见,听起来您的评论指的是客户端代码。如果是这样,那么它将取决于托管客户端代码的内容。如果它是托管在 IIS 中的 Web 应用程序,则客户端将处于与您的服务类似的环境中,但具有 ASP.NET 的多线程约束。如果不是,那么是的,实现一个线程管理器来处理批处理是可行的。我不会尝试在基于 ASP.NET 的客户端中实现线程管理器(太复杂,让我的大脑受伤)。
    • 实际上,这听起来很适合单身人士。我从未看过 WCF 源代码,但要完成它所做的一切,它很可能会为内存管理创建“子”AppDomain。请记住,WCF 最初是在不关闭创建它们的 AppDomain 的情况下无法从内存中卸载动态创建的程序集时编写的。只要 AppDomain 不继续旋转,那么您就拥有了单例。
    • 这里都是服务器端代码。我还是很迷茫,我不确定你说的客户端代码是什么意思
    猜你喜欢
    • 2017-12-10
    • 2019-09-05
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2010-12-17
    • 1970-01-01
    相关资源
    最近更新 更多