如何在`RoleEntryPoint中优雅地关闭mongod.OnStop()`方法
本文关键字:mongod OnStop 方法 RoleEntryPoint | 更新日期: 2023-09-27 17:58:49
我需要优雅地关闭用RoleEntryPoint.OnStop()
方法中的System.Diagnostics.Process
启动的mongod.exe。
我受到一篇文章的启发,该文章使用CloudDrive在Microsoft Windows Azure上运行MongoDb。一切似乎都很好,但在WorkerRole重启后,mongod表示:
**************
old lock file: .'mongod.lock. probably means unclean shutdown
recommend removing file and running --repair
see: http://dochub.mongodb.org/core/repair for more information
*************
所以我创建了一个简单的控制台应用程序,下面的代码模拟了mongod.exe被杀死时的相同结果。只有当控制台窗口(父进程)关闭时,才会释放锁定文件。由于CloudDrive在父进程终止之前被卸载(RoleEntryPoint
),mongod.lock文件从未在Windows Azure WorkerRole环境中发布。
static void Main(string[] args)
{
StartMongo();
Console.ReadLine();
_mongoProcess.Close();
}
private static void StartMongo()
{
_mongoProcess = new Process();
var startInfo = _mongoProcess.StartInfo;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = false;
startInfo.FileName = @"mongod.exe";
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.Arguments = "--dbpath .";
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
_mongoProcess.ErrorDataReceived += (sender, evt) => WriteLine(evt.Data);
_mongoProcess.OutputDataReceived += (sender, evt) => WriteLine(evt.Data);
_mongoProcess.Start();
_mongoProcess.BeginErrorReadLine();
_mongoProcess.BeginOutputReadLine();
}
我是如何意识到父进程在保持锁定的?我只是简单地将进程更改为在新的shell窗口中运行,并没有重定向任何输出(startInfo.UseShellExecute = true
)。启动了两个控制台窗口,当mongod关闭时,它在主应用程序终止前释放了锁定。我需要实现此行为才能在Windows Azure中的RoleEntryPoint
中使用它。
有人知道怎么做吗?
编辑:
我意识到,也许是父进程拥有ErrorDataReceived
和OutputDataReceived
的侦听器,它们将mongod输出流正确地关闭/刷新到mongod.lock……会吗?
在OnStop
方法中,您可以调用关闭命令。你可以做一些类似的事情
var server = MongoServer.Create("mongodb://host:port");
server.Shutdown();
如果您使用的是官方的1.0驱动程序,那么即使关闭了服务器,shutdown命令也会挂起。Azure将回收此角色实例,尽管挂起,因为您在OnStop中只有大约30秒的时间。此错误已在GitHub的最新版本驱动程序中修复https://github.com/mongodb/mongo-csharp-driver.
此外,使用mongodb 1.8.1并启用日志。那你就不需要修理了。如果由于某种原因Azure在关闭完成之前回收了角色实例并且没有清理,则需要这样做。有关日记的更多信息,请访问http://www.mongodb.org/display/DOCS/Journaling
感谢Sridhar的回答,只是为了重述并添加一些代码作为参考。
使用日志启动流程
startInfo.Arguments = @"--journal --dbpath c:'path'to'db";
正在关闭,然后等待5秒进行处理以退出。在我最新版本的官方mongo-csharp驱动程序中,它从MongoDB.Driver.dll!MongoDB.Driver.Internal.MongoConnection.ReceiveMessage
抛出EndOfStreamException
。我希望这个问题能尽快解决。
var t = new Task(() =>
{
var server = MongoServer.Create();
//server.RunAdminCommand("shutdown"); -- throws exception
server.Shutdown();
});
t.Start();
try
{
t.Wait(5000);
}
catch (EndOfStreamException e)
{
// silently ignore
}
finally
{
if (!_mongoProcess.HasExited)
{
_mongoProcess.Kill();
}
}
EDIT:使用server.Shutdown()
而不是server.RunAdminCommand("shutdown")
难道不能只做_mongoProcess吗。OnStop()中的Kill()?