c# – 如何在IIS中重新启动网站时检索已启动的Ignite实例?
我在ASP.NET MVC 5网站中使用Apache Ignite .NET EntityFramework二级缓存.一切都在我的开发机器上按预期工作,但当我尝试在生产IIS上使用Web Deploy发布网站时,事情变得复杂.
我总是得到一个类org.apache.ignite.IgniteException:当我在IIS上发布或重新启动网站时,已经启动了具有此名称的Ignite实例:GridName.错误非常明显,Ignite已经在运行. 我发现逃避此错误的唯一方法是重新启动网站的应用程序池.但是,每次我在生产中发布网站(每周发生几次)时,我都不想这样做. 我尝试在global.asax Dispose()或Application_End()中停止Ignite实例,但事实是AppDomain需要很多秒才能停止.因此,Ignite有时间在停止之前尝试自行启动并导致上述错误. 我还尝试调用Ignition.TryGetIgnite()来检索正在运行的实例,而不是尝试启动它,但它总是返回null.在Apache Ignite Github存储库中查看此函数的源代码,我看到Ignition对象只是在内存中保留一个静态节点列表并在此列表上执行操作.由于此时AppDomain重新启动,因此列表为空,但Ignite节点仍在JVM中运行. 有没有办法检索Ignite实例或可靠地停止它,所以我不需要每次都重启应用程序池? 解决方法
这是一个已知问题:AppDomain已停止,但JVM仍在运行(因为进程未停止),因此Ignite节点的Java部分仍然存在.
解决方法是在Global.asax.cs中的Application_End事件中使用Ignition.StopAll停止所有Ignite节点: protected void Application_Start() { ... using (new Mutex(true,"ignite_" + Process.GetCurrentProcess().Id)) { var ignite = Ignition.TryGetIgnite() ?? Ignition.Start(); } } protected void Application_End() { using (new Mutex(true,"ignite_" + Process.GetCurrentProcess().Id)) { Ignition.StopAll(true); } } 此处需要互斥锁,因为旧域停止与新域启动重叠. 另一个解决方法,可能更强大和干净: 1)停止AppDomain.DomainUnload中的所有节点: AppDomain.CurrentDomain.DomainUnload += (sender,args) => Ignition.StopAll(true); 2)每次使用不同的IgniteConfiguration.GridName: Ignition.Start(new IgniteConfiguration { GridName = Guid.NewGuid().ToString() }); 这样,现有节点不会阻止您启动新节点.最终,旧节点将被停止并从内存中清除. 文档:https://apacheignite-net.readme.io/docs/deployment#section-aspnet-deployment (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |