gpt4 book ai didi

c# - 在 IIS 中发生网站重启时,如何检索已启动的 Ignite 实例?

转载 作者:行者123 更新时间:2023-11-30 14:07:11 26 4
gpt4 key购买 nike

我在我的 ASP.NET MVC 5 网站中使用 Apache Ignite .NET EntityFramework 二级缓存。在我的开发机器上一切都按预期工作,但是当我尝试在生产 IIS 上使用 Web 部署发布网站时,事情变得复杂了。

当我在 IIS 上发布或重新启动网站时,我总是得到一个 class org.apache.ignite.IgniteException: Ignite instance with this name has already been started: 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 部分仍然存在。

解决方法是在 Application_End 事件中使用 Ignition.StopAll 停止所有 Ignite 节点,就像在 Global.asax.cs 中这样:

    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);
}
}

Mutex 在这里是必需的,因为旧域停止与新域开始重叠。进程 ID 包含在互斥锁名称中以确保进程范围内的独占锁,但不是机器范围内的。


另一种解决方法,可能更健壮和干净:

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

关于c# - 在 IIS 中发生网站重启时,如何检索已启动的 Ignite 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42961879/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com