繁体   English   中英

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

[英]What's the best way to deploy an executable process on a web server?

原来的问题:

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

我在我的服务器上部署了一个.NET Web项目。 它仍处于测试阶段,所以发布了大量的释放和重新发布。

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

问题是:部署此应用程序的最佳方式是什么,以便每当我发布新版本时它都会更新? 它应该在不同版本之间一直运行,所以理想情况下我想要某种设置,即shutdown-deploy-startup过程涉及尽可能少的步骤。

谢谢!

编辑 - 赏金开始了

到目前为止给出的答案是有用和有趣的,但没有为我提供一个清晰,简洁和优雅的解决方案。 请不要认为我对部署项目有广泛的了解,因为我没有。 Bounty会找到能够提供以下解决方案的人:

  1. 发布最新版本的网站;
  2. 关闭服务器上运行的任何admin.exe实例;
  3. 更新admin.exe;
  4. 启动admin.exe;
  5. 所有这些都应该优选地在一个步骤中完成,或者尽可能少的步骤,看到它将在产品的整个寿命期间重复进行;
  6. 所有上述操作都应该优先完成,无需安装任何第三方软件。

谢谢您的帮助!

次要编辑 - 澄清

我认为到目前为止提供的很多解决方案都高估了问题的复杂性,所以让我澄清一下:所有要部署的东西,只需要部署在台计算机上,也很高兴Visual Studio可以提供所有源代码。 我只需要(1)将网站发布到web文件夹,(2)关闭,重新安装并重新启动同一服务器上的admin.exe。 有没有一个简单的方法一步到位? 是否可以使用VS部署项目完成?

听起来您需要查看自定义MSBuild脚本以进行部署。

MSBuild不仅仅是构建解决方案。 您也可以使用它来复制文件并更新它们。 执行此操作的任务的良好资源是此处的MSBuild社区任务。

然后,您可以在部署网站部署的同时包括后台进程的部署。

另一种方法可能是使用Windows PowershellPSExec之类的东西来远程执行复制和更新命令。

使用Hudson等持续集成服务器,这两种方法都可以很好地实现自动化。 我有一个构建过程,它自动监视我的源代码存储库,构建程序,部署到登台服务器,运行验收测试,然后部署到预览框。 我有另一个(手动)作业,只需点击一下即可部署此预览版本,最大限度地减少停机时间,并(通常)减少错误命令的错误。

“正确”的方式可能是设置部署脚本和安装程序,但只需单击Visual Studio中的发布并跳过远程桌面就可以在开发过程中更加方便。

我有一个管理员Web应用程序作为命令行应用程序的前端 - 与您正在做的略有不同,但相同的解决方案应该工作。

只需在管理员Web应用程序中添加对控制台项目的引用即可。 即使您没有在控制台项目中调用任何方法,该引用也会导致在您发布管理网站时重建和上载控制台应用程序。

添加到Web应用程序的简单启动/停止页面负责第2步和第4步 - 我们调用Process.Start()/ Process.Kill(),尽管您显然可以根据admin的设置选择更干净的关闭。可执行程序。

下面是我的开始/停止页面中的代码 - 我将它们设置为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"));
    }

可能有一种更清洁的方式,但可能将其安装为Windows服务,然后使用installutil.exe编写安装/卸载命令的脚本。 然后只需更新服务所在的文件夹,并为每次更新重新运行脚本?

大服务的教程在这里

希望这可以帮助

我建议编写一个可以在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 $ \\路径寻址)。

不幸的是,部署永远不会很好也不优雅:

如果您需要澄清任何事情,请告诉我

这是一个讨厌的想法。 如果你是admin.exe没有做任何太难的核心,为什么不扔进IIS? 要编写C#Web服务,您可能不需要进行太多更改。

为了确保重复调用它,您可以使用各种方法,如Windows Scheduler,每分钟运行一次wget。 使用文件锁保持并发副本,如果完成时间超过一分钟。

这将使您的部署像文件副本(FTP)一样简单。 我甚至认为你在推送C#DLL时不需要重启IIS。 如果这样做,您可以通过SSH编写脚本。

对我而言,您的问题听起来很像SharePoint通过在每个WFE中运行的Timer服务解决的部署问题,stsadm将管理任务排入队列,该服务出列并运行它们等。

我要做的是

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

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

我会编写一个命令行应用程序来完成所有这些工作。

这是一个粗略的例子:

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

你可能会明白这一点。 如果您希望它自动执行,只需使用任务计划每天调用它,或者通常您需要它。

在服务器/ Web上存储最新版本的在线项目。 例如:在version.txt中,值为“2.1.0”,或者如果您也有访问权限,则查询数据库。

您在客户端上运行的应用程序将定期读取version.txt文件的内容,然后与内置(自我)版本号进行比较。

  • 如果检测到补丁或次要版本,例如2.1.123,则会悄悄地旋转出第二个应用程序(updater.exe)
    • 做升级,
    • 它应从服务器/网站下载更新的(首选压缩)项目。
    • 停止所有运行的实例。
    • 解压缩内容。
    • 备份现有文件(重命名)
    • 复制/安装新版本的项目,
    • 启动应用程序(当应用程序成功重启时,它将删除自己的备份文件)。
  • 如果检测到主要版本,例如:3.0.0
    • 通知用户有重大升级
    • 如果用户接受,请下载安装程序
    • 运行完整的安装程序更新

这有帮助吗?

用于Web应用程序的VS部署项目并不容易掌握,有些不可靠。 我建议的是什么:

  1. 将Admin.exe修改为.NET Windows服务。 看看为什么你需要这样做。
  2. 使用sc.exe,InstallUtil.exe或安装程序构建服务(如installer.codeeffects.com)可在每次部署时快速重新安装服务。 顺便说一下,如果我没记错的话,在installer.codeeffects.com上你可以下载一个VS示例代码,说明如果你不熟悉服务,如何构建.NET Windows服务。

可以像这样进行部署(假设您在自动化方面的需求很少,而且几乎可以手动部署):

运行上述任一工具以首先重新安装您的服务。 sc.exe和InstalUtil.exe工具支持命令行。 因此,如果您的Web应用程序,VS和服务在同一台计算机(您的开发计算机,我假设?)上运行,您可以右键单击VS中的Web项目,选择“属性”并设置构建前或构建后命令那里的Build Events选项卡。 这样,您的VS可以在发布Web应用程序之前自动重建并重新安装您的服务。 这就是为什么exe程序在你的情况下不好的主要原因,Windows服务会更好地为你服务。

然后部署您的Web应用程序(假设它已按照上面的讨论进行构建)。 这里没有大佬,只需使用VS中的发布命令或移动您的Web应用程序的所有文件,除了.cs文件,/ Properties /和/ obj /文件夹。 或者,如果从项目文件夹运行,只需右键单击主页面并选择“在浏览器中查看” - 这将通过VS启动运行时而不启动调试器。

很抱歉这么长的帖子。 我是否正确理解了您的问题和说明? :)

如何在部署后点击admin.exe。 然后在admin.exe中,在检查业务规则的完整性之前,检查更新是否可用。 如果是,请更新,然后继续检查。

为了简化操作并确保我能够回滚所有内容,我将创建一个执行以下操作的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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM