我需要在System.Diagnostics.Process
方法中正常关闭以RoleEntryPoint.OnStop()
启动的mongod.exe。
我受到Running MongoDb on Microsoft Windows Azure with CloudDrive文章的启发。 一切似乎都运行良好,但是在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 ...它可以吗?
答案 0 :(得分:2)
在OnStop
方法中,您可以invoke the shutdown command。你可以做点什么
var server = MongoServer.Create("mongodb://host:port");
server.Shutdown();
如果您使用的是官方1.0驱动程序,即使关闭服务器,shutdown命令也会挂起。 Azure将回收此角色实例,因为您在OnStop中只有大约30秒的时间。 GitHub https://github.com/mongodb/mongo-csharp-driver中最新版本的驱动程序已修复此错误。
另外use mongodb 1.8.1 with journaling enabled。那时你不需要修理。如果由于某种原因Azure在关闭完成之前回收角色实例并且不干净,则需要这样做。有关日记的更多信息,请访问http://www.mongodb.org/display/DOCS/Journaling
答案 1 :(得分:1)
感谢Sridhar的回答,只是为了重新概括并为其他人添加一些代码作为参考。
使用日记功能启动流程
startInfo.Arguments = @"--journal --dbpath c:\path\to\db";
关闭,然后等待5秒钟进行退出。在我最新的官方mongo-csharp驱动程序中,它从EndOfStreamException
抛出MongoDB.Driver.dll!MongoDB.Driver.Internal.MongoConnection.ReceiveMessage
。我希望很快就能解决。
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();
}
}
编辑:使用server.Shutdown()
代替server.RunAdminCommand("shutdown")
答案 2 :(得分:0)
你不能在OnStop()中做_mongoProcess.Kill()吗?