在Web服务器上部署可执行进程的最佳方法是什么?

9

原问题:

这个问题的标题可能有点笨拙,但是情况是这样的:

我在我的服务器上部署了一个.NET web项目。它还处于beta阶段,因此仍然需要频繁发布和重新发布。

我还编写了一个C#可执行文件(称其为“admin.exe”),它在后台运行于同一VS解决方案中,定期执行某些业务规则完整性检查,并在数据库中适当插入警告表。

问题是:最佳部署方式是什么,以便在进行新的发布时能够更新该应用程序? 它应该在发布之间始终运行,因此理想情况下,我希望某种设置方式涉及最少的步骤来完成关闭-部署-启动过程。

谢谢!

编辑 - 悬赏开始

迄今为止给出的答案都很有帮助和有趣,但没有为我提供清晰、简洁和优雅的解决方案。请不要假定我对部署项目有广泛的知识,因为我没有。悬赏将授予能够提供执行以下操作的解决方案的人:

  1. 发布最新版本的网站;
  2. 关闭服务器上正在运行的任何admin.exe实例;
  3. 更新admin.exe;
  4. 启动admin.exe;
  5. 尽可能少地使用步骤完成上述所有操作,因为它将在产品的生命周期内重复执行;以及
  6. 最好不需要安装任何第三方软件即可完成上述所有操作。

谢谢你的帮助!

小编辑 - 澄清

我认为迄今为止提供的许多解决方案都高估了问题的复杂性,因此让我澄清一下:所有要部署的内容只需部署在一个计算机上,该计算机还有可用的Visual Studio和所有源代码。 我只需要(1)将Web站点发布到Web文件夹中,以及(2)在同一台服务器上关闭、重新安装和重新启动admin.exe。 有没有简单的方法可以一次完成这些操作? 可以使用VS部署项目完成吗?


Shaul - 你需要进行几次澄清,这意味着你的问题缺少一些背景,或者至少缺少一些具体客户需求。例如:如果你想从Visual Studio执行此操作,可以使用Post-build事件,也可以编写自定义的MSBuild步骤,或者只需编写脚本来执行上述1-6步骤。如果这不足够,那么可能存在一些隐藏的要求未被明确表达,这是我的猜测。祝你好运。 - Ariel
你应该澄清你的 admin.exe 是否是 Windows 服务。这关系到它如何停止和重新启动。 - Jacob
Jacob - 现在它不是一个Windows服务,但如果这样做会更容易,它可以成为一个... - Shaul Behr
11个回答

3
“正确”的方式可能是设置部署脚本和安装程序,但在开发过程中,只需在Visual Studio中单击发布并跳过使用远程桌面会更加方便。
我有一个管理Web应用程序,它作为命令行应用程序的前端 - 与您所做的略有不同,但相同的解决方案应该适用。
简单地在管理员Web应用程序中添加对控制台项目的引用。即使您不调用控制台项目中的任何方法,该引用也会导致重新构建和上传控制台应用程序时发布管理员网站。
在Web应用程序中添加一个简单的启动/停止页面即可完成步骤2和4 - 我的调用Process.Start()/Process.Kill(),尽管根据admin.exe的设置,您显然可以选择更干净的关闭选项。
以下是我的启动/停止页面代码 - 我已将它们设置为Web服务方法(以便促进一些您可能不需要的监视内容),但它们应该能够从简单的按钮单击方法调用。请注意,服务帐户需要权限来运行/停止进程 - 在开发框中,最简单的选项是设置iis以使用管理员用户而不是默认服务帐户运行。
    private void KillProcess(string name)
    {
        var binpath = Server.MapPath("~/bin");
        var pp2 = Process.GetProcesses();

        var pp = from p in pp2 where p.ProcessName.Contains(name) && !p.ProcessName.Contains("vshost") select p;
        foreach (var p in pp)
        {
            p.Kill();
        }
    }

[WebMethod]
    public void StartQueueRunner()
    {
        var binpath = Server.MapPath("~/bin");
        System.Diagnostics.Process.Start(Path.Combine(binpath, "TwoNeeds.QueueRunner.exe"));
    }

[WebMethod]
    public void StartQueueRunner()
    {
        var binpath = Server.MapPath("~/bin");
        System.Diagnostics.Process.Start(Path.Combine(binpath, "TwoNeeds.QueueRunner.exe"));
    }

+1 这听起来非常有前途。请澄清一下您在网络应用程序中所说的“启动/停止”页面是什么意思 - 我还不太熟悉ASP.NET... - Shaul Behr
  • 悬赏:我还没有时间来实现这个解决方案,但是悬赏时钟在几个小时内就要结束了,到目前为止,这个解决方案看起来最有希望。你的陈述“……在Visual Studio中只需单击发布按钮……在开发过程中更加方便。”真的很准确。我可能会再次联系你,以帮助解决实际问题。 谢谢!
- Shaul Behr

3
听起来您需要查看自定义MSBuild脚本以进行部署。
MSBuild不仅可以构建解决方案,还可以用于复制文件和更新文件。这个链接提供了很好的任务资源。
您可以将后台进程的部署与网站部署一起完成。
另一种方法是使用Windows PowershellPSExec之类的工具远程执行复制和更新命令。
这两种方法都可以很好地与持续集成服务器(如Hudson)自动化。
我有一个构建过程,它会自动监视我的源代码库,构建程序,部署到暂存服务器,运行验收测试,然后部署到预览箱。我还有另一个(手动)作业,只需单击即可将此预览版本部署到生产环境,从而最大限度地减少停机时间和(通常)减少由错误命令导致的错误。

感谢您的回答 - 请查看我的编辑以获取进一步的澄清。 - Shaul Behr

2

可能有更简单的方法,但也许可以将其安装为Windows服务,然后使用installutil.exe脚本安装/卸载命令。然后只需更新服务所在的文件夹并重新运行每个更新的脚本?

这里有一篇很棒的服务教程。

希望能对您有所帮助。


感谢您的回答 - 请查看我的编辑以获得进一步的澄清。 - Shaul Behr

2
我建议您编写一个脚本,在PC上运行,通过网络进行部署(这样您就不必每次都登录目标计算机)。我使用msbuild完成了部署,但您也可以直接使用批处理文件。
我假设您的管理流程正在运行Windows服务(无论如何,将其作为服务运行是有意义的),因此您可以像这样部署它(这是msbuild脚本的一部分 - 如果您不需要,可以删除带有用户名和密码的部分):
<ItemGroup>
    <ReleaseFiles Include="localPath\bin\*.dll"/>
    <ReleaseFiles Include="localPath\bin\*.exe"/>
    <ReleaseFiles Include="localPath\bin\*.pdb"/>
    <ReleaseFiles Include="localPath\bin\*.config"/>   
</ItemGroup>

<Target Name="Release">
    <Message Text="Installing Admin on $(DeploymentMachine) as user $(User)"/>
    <Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) stop &quot;Admin&quot;" />
    <Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) delete &quot;Admin&quot;" />
    <Delete ContinueOnError="true" Files="\\$(DeploymentMachine)\C$\path-to-admin\*.*"/>
    <MakeDir Directories="\\$(DeploymentMachine)\C$\path-to-admin"/>
    <Copy SourceFiles="@(ReleaseFiles)" DestinationFiles="@(ReleaseFiles->'\\$(DeploymentMachine)\C$\path-to-admin\%(RecursiveDir)%(Filename)%(Extension)')" />
    <Exec Command="sc.exe \\$(DeploymentMachine) create &quot;Admin&quot; binpath= &quot;C:\path-to-admin\admin.exe&quot; start= auto obj= $(User) password= $(Password)"  />
    <Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) start &quot;Admin&quot;" />
</Target>

部署IIS网站通常会有些麻烦,但如果您在目标机器上设置好了一切,那么可能只需通过网络复制文件即可(再次使用\DeploymentMachine\share或\DeploymentMachine\C$\path寻址)。不幸的是,部署永远不会很好看或优雅:( 如果您需要任何澄清,请告诉我。

1

这是一个不太好的想法。如果您的admin.exe没有做任何太过复杂的事情,为什么不将其放入IIS中呢?编写C# Web服务时,您可能不需要进行太多更改。

为了确保它被重复调用,您可以使用各种方法,例如Windows计划任务程序每分钟运行一次wget。使用文件锁定来防止并发副本运行,以防它需要超过一分钟才能完成。

这将使您的部署变得像文件复制(FTP)一样简单。我甚至认为在推送C# DLL时无需重新启动IIS。如果需要重新启动,您可以通过SSH脚本化。


0

把admin.exe做成点击一次部署,怎么样?然后在你的admin.exe中,在你检查业务规则完整性之前,先检查是否有可用更新。如果有,那就升级,然后继续进行检查。


0
为了让一切变得简单并确保我能回滚所有操作,我会创建一个PowerShell脚本来执行以下操作:
  1. 停止应用程序池。
  2. 将当前的Web应用复制到“历史文件夹”中,以便在需要时可以回滚到该版本
  3. 部署新的Web应用
  4. 从服务中停止当前的admin.exe
  5. 通过执行Uninstall.bat卸载admin.exe(这在Windows服务中非常常见)
  6. 将当前的admin.exe应用程序复制到历史文件夹中(参见2)
  7. 将新的admin.exe复制到正确位置并运行install.bat
  8. 启动新服务
  9. 启动应用程序池
您可以在PowerShell脚本中自动执行所有操作(唯一不确定的是应用程序池,但我相信您可以做到这一点)。
有关PowerShell的更多信息,请访问此处:http://arstechnica.com/business/news/2005/10/msh.ars/2

0

对我来说,你的问题听起来很像SharePoint通过在每个WFE中运行的定时器服务解决的部署问题,stsadm排队管理任务,该服务出列并运行它们等。

我会这样做:

  • 编写在每个WFE中运行的服务
  • 编写一个小型自定义“stsadm”工具,以便您可以排队任务,指定它们需要运行的时间等。

另一种方法:使用普通的Windows任务计划程序怎么样?请看这里,您可以轻松地远程排队任务。


感谢您的回答 - 请查看我的编辑以获得进一步的澄清。 - Shaul Behr

0
我会编写一个命令行应用程序来完成所有这些操作。
以下是一个大致的示例:
Site.api.publish();
admin.api.shutdown();
while(shell.status("admin.exe") == true) {}; //still running
file.replace("admin.exe", "path-to-compile\admin.exe");
shell.run("admin.exe");

您可能已经明白了。如果您想自动执行它,只需使用任务计划程序每天或者您希望的频率调用它即可。

感谢您的回答 - 请查看我的编辑以获得进一步的澄清。 - Shaul Behr

0
将项目的最新版本存储在服务器/网络上。例如:在版本文件(version.txt)中的值为“2.1.0”,或者如果您可以访问数据库,则查询数据库。
运行在客户端上的应用程序会定期读取版本文件(version.txt)的内容,然后与内置(self)版本号进行比较。
如果检测到补丁或小版本更新(例如2.1.123),则会启动第二个应用程序(updater.exe),该应用程序将悄悄地:
- 执行升级 - 从服务器/网络下载更新的(首选为zipped)项目。 - 停止任何正在运行的实例。 - 解压缩内容。 - 备份现有文件(重命名)。 - 复制/安装项目的新版本。 - 启动应用程序(成功重新启动应用程序时,将删除其自身的备份文件)。
如果检测到主要版本更新(例如:3.0.0),则:
- 发送通知用户有重大升级可用。 - 如果用户接受,则下载安装程序。 - 运行完整的安装程序更新。
这对您有帮助吗?

感谢您的回答 - 请查看我的编辑以获得进一步的澄清。 - Shaul Behr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接