简体   繁体   English

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

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

The original question: 原来的问题:

The title of this question might be a bit clumsily phrased, but here's the situation: 这个问题的标题可能有点笨拙,但这是情况:

I have a .NET web project deployed on my server. 我在我的服务器上部署了一个.NET Web项目。 It's still in beta, so there's a lot of releasing and re-releasing happening. 它仍处于测试阶段,所以发布了大量的释放和重新发布。

I have also written a C# executable in the same VS solution (call it "admin.exe") that runs in the background on the server, periodically performing certain business rule integrity checks and making appropriate insertions to a warning table in the DB. 我还在同一个VS解决方案(称为“admin.exe”)中编写了一个C#可执行文件,该解决方案在服务器的后台运行,定期执行某些业务规则完整性检查并对数据库中的警告表进行适当的插入。

Question is: what's the best way to deploy this app so that it gets updated whenever I make a new release? 问题是:部署此应用程序的最佳方式是什么,以便每当我发布新版本时它都会更新? It should be running all the time in between releases, so ideally I'd like some sort of setup whereby the shutdown-deploy-startup process involves the minimum possible number of steps. 它应该在不同版本之间一直运行,所以理想情况下我想要某种设置,即shutdown-deploy-startup过程涉及尽可能少的步骤。

Thanks! 谢谢!

Edit - Bounty started 编辑 - 赏金开始了

The answers given thus far have been helpful and interesting, but haven't provided me with a clear, concise and elegant solution. 到目前为止给出的答案是有用和有趣的,但没有为我提供一个清晰,简洁和优雅的解决方案。 Please do not assume I have extensive knowledge of deployment projects, because I don't. 请不要认为我对部署项目有广泛的了解,因为我没有。 Bounty goes to the person who can provide a solution that does the following: Bounty会找到能够提供以下解决方案的人:

  1. Publish the latest version of the web site; 发布最新版本的网站;
  2. Shut down any instances of admin.exe that are running on the server; 关闭服务器上运行的任何admin.exe实例;
  3. Update admin.exe; 更新admin.exe;
  4. Launch admin.exe; 启动admin.exe;
  5. All of the above should be done preferably in one step, or as few steps as possible, seeing as it will be done repeatedly throughout the life of the product; 所有这些都应该优选地在一个步骤中完成,或者尽可能少的步骤,看到它将在产品的整个寿命期间重复进行; and
  6. All of the above should be done preferably without requiring installation of any 3rd party software. 所有上述操作都应该优先完成,无需安装任何第三方软件。

Thank you for your help! 谢谢您的帮助!

Minor edit - clarification 次要编辑 - 澄清

I think a lot of the solutions offered thus far have overestimated the complexity of the problem, so let me clarify: everything that is to be deployed, only has to be deployed on one computer, which also happily has Visual Studio available with all source code. 我认为到目前为止提供的很多解决方案都高估了问题的复杂性,所以让我澄清一下:所有要部署的东西,只需要部署在台计算机上,也很高兴Visual Studio可以提供所有源代码。 I only need to (1) publish the web site to the web folder, and (2) shut down, reinstall and restart admin.exe on the same server. 我只需要(1)将网站发布到web文件夹,(2)关闭,重新安装并重新启动同一服务器上的admin.exe。 Isn't there a simple way of doing this in one step? 有没有一个简单的方法一步到位? Can it be done with a VS Deployment project? 是否可以使用VS部署项目完成?

It sounds like you need to take a look at a custom MSBuild script for deployment. 听起来您需要查看自定义MSBuild脚本以进行部署。

MSBuild does much more than just build solutions. MSBuild不仅仅是构建解决方案。 You can also use it to copy files and update them, too. 您也可以使用它来复制文件并更新它们。 A good resource for tasks to do this is the MSBuild Community Tasks here . 执行此操作的任务的良好资源是此处的MSBuild社区任务。

You can then include the deployment of your background process alongside the deployment of the Web site deployment. 然后,您可以在部署网站部署的同时包括后台进程的部署。

An alternative approach might be to use Windows Powershell with something like PSExec to remotely execute copy and update commands. 另一种方法可能是使用Windows PowershellPSExec之类的东西来远程执行复制和更新命令。

Both these kinds of approach can be automated very well with continuous integration servers such as Hudson . 使用Hudson等持续集成服务器,这两种方法都可以很好地实现自动化。 I have a build process that automatically monitors my source code repository, builds the program, deploys to a staging server, runs acceptance tests, then deploys to a preview box. 我有一个构建过程,它自动监视我的源代码存储库,构建程序,部署到登台服务器,运行验收测试,然后部署到预览框。 I have another (manual) job that with one click deploys this preview version to live, minimising downtime and (usually) reducing errors from mistiped commands. 我有另一个(手动)作业,只需点击一下即可部署此预览版本,最大限度地减少停机时间,并(通常)减少错误命令的错误。

The "correct" way is probably to set up deployment scripts and installers, but being able to just click publish in Visual Studio and skip going in with remote desktop is a lot more convenient during development. “正确”的方式可能是设置部署脚本和安装程序,但只需单击Visual Studio中的发布并跳过远程桌面就可以在开发过程中更加方便。

I have an admin web app that acts as a front end to a command line app - slightly different from what you are doing, but the same solution should work. 我有一个管理员Web应用程序作为命令行应用程序的前端 - 与您正在做的略有不同,但相同的解决方案应该工作。

Simply add a reference to the console project in the admin web app. 只需在管理员Web应用程序中添加对控制台项目的引用即可。 Even though you don't call any methods in the console project, the reference will cause the console app to be rebuilt and uploaded when you publish the admin website. 即使您没有在控制台项目中调用任何方法,该引用也会导致在您发布管理网站时重建和上载控制台应用程序。

A simple start/stop page added to the web app takes care of steps 2 & 4 - Mine calls Process.Start()/Process.Kill(), though you obviously have the option of a cleaner shutdown depending on the setup of admin.exe. 添加到Web应用程序的简单启动/停止页面负责第2步和第4步 - 我们调用Process.Start()/ Process.Kill(),尽管您显然可以根据admin的设置选择更干净的关闭。可执行程序。

Below is the code from my start/stop page - I have them set up as web service methods (to facilitate some monitoring stuff you probably won't need), but they should work just as well called from a simple button click method. 下面是我的开始/停止页面中的代码 - 我将它们设置为Web服务方法(以便于您可能不需要的某些监视),但它们应该可以通过简单的按钮单击方法调用。 Note that the service account will need permission to run/stop the process - on a dev box the simplest option is to set up iis to run as an admin user rather than the default service account. 请注意,服务帐户需要运行/停止进程的权限 - 在开发框中,最简单的选项是将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"));
    }

There is probably a much cleaner way but maybe install it as a windows service then script the install / uninstall commands using installutil.exe. 可能有一种更清洁的方式,但可能将其安装为Windows服务,然后使用installutil.exe编写安装/卸载命令的脚本。 Then just update the folder where the service sits and re-run the script for each update? 然后只需更新服务所在的文件夹,并为每次更新重新运行脚本?

Great service tutorial here 大服务的教程在这里

Hope this helps 希望这可以帮助

I would recommend writing a script that you could run on your PC, that would do the deployment over the network (so that you don't have to log in to the target machine every time). 我建议编写一个可以在PC上运行的脚本,通过网络进行部署(这样您就不必每次都登录到目标机器)。 I have done it using msbuild, but you can really just go for a batch file. 我使用msbuild完成了它,但你真的可以去一个批处理文件。

I assume your admin process is running a windows service (anyway, it makes sense to run it as a service), so you would deploy it like this (this is part of the msbuild script - you can delete the bits with username and password if you don't need it): 我假设您的管理进程正在运行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>

Deploying IIS web sites is usually a bit more pain, but if you have everything set up on the target machine then possibly it would work to just copy the files over the network (again using the \\DeploymentMachine\\share or \\DeploymentMachine\\C$\\path addressing). 部署IIS网站通常会有点痛苦,但如果您在目标计算机上设置了所有内容,那么可能只需通过网络复制文件(再次使用\\ DeploymentMachine \\ share或\\ DeploymentMachine \\ C $ \\路径寻址)。

Unfortunately deployment is never nice nor elegant :( 不幸的是,部署永远不会很好也不优雅:

Please let me know if you need clarification on anything 如果您需要澄清任何事情,请告诉我

Here's a nasty thought. 这是一个讨厌的想法。 If you're admin.exe isn't doing anything too hard core, why not throw into IIS? 如果你是admin.exe没有做任何太难的核心,为什么不扔进IIS? To write a C# Web Service, you probably won't need to change much. 要编写C#Web服务,您可能不需要进行太多更改。

To ensure it gets called repeatedly, you could use any variety of methods, like Windows Scheduler to run wget once a minute. 为了确保重复调用它,您可以使用各种方法,如Windows Scheduler,每分钟运行一次wget。 Keep concurrent copies from running with a file lock, should it ever take MORE than one minute to complete. 使用文件锁保持并发副本,如果完成时间超过一分钟。

This would make your deployment as simple as a file copy (FTP). 这将使您的部署像文件副本(FTP)一样简单。 I don't even think you need to reboot IIS when pushing a C# DLL. 我甚至认为你在推送C#DLL时不需要重启IIS。 If you do, you can script that up over SSH. 如果这样做,您可以通过SSH编写脚本。

To me, your problem sounds a lot like the deployment problem SharePoint solves through their Timer service running in each WFE, stsadm enqueuing admin tasks, that service dequeuing and running them etc. 对我而言,您的问题听起来很像SharePoint通过在每个WFE中运行的Timer服务解决的部署问题,stsadm将管理任务排入队列,该服务出列并运行它们等。

What I would do is to 我要做的是

  • write a service running in each WFE 编写在每个WFE中运行的服务
  • write a small custom "stsadm" tool so you can enqueue tasks, specify when they need to run, etc. 编写一个小的自定义“stsadm”工具,以便您可以排队任务,指定他们何时需要运行,等等。

Another approach: what about using the plain vanilla Windows Task Scheduler? 另一种方法:如何使用普通的Windows任务计划程序? Look here , you can easily enqueue tasks remotely for ex. 这里 ,您可以轻松地远程排队任务。

I would write a command-line application that would do all of that. 我会编写一个命令行应用程序来完成所有这些工作。

Here is a rough example: 这是一个粗略的例子:

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

You probably get the point. 你可能会明白这一点。 If you want it to do it automatically just use the Task Schedular to call it every day, or however often you want it. 如果您希望它自动执行,只需使用任务计划每天调用它,或者通常您需要它。

Store on the server/web the most recent version of the project that is online. 在服务器/ Web上存储最新版本的在线项目。 eg: in a version.txt the value "2.1.0", or query the database if you have access too. 例如:在version.txt中,值为“2.1.0”,或者如果您也有访问权限,则查询数据库。

Your application running on clients, will periodically read the contents of the version.txt file, then compared against the inbuilt(self) version number. 您在客户端上运行的应用程序将定期读取version.txt文件的内容,然后与内置(自我)版本号进行比较。

  • If a patch or minor release is detected eg 2.1.123, spins out a second app(updater.exe) that will quietly 如果检测到补丁或次要版本,例如2.1.123,则会悄悄地旋转出第二个应用程序(updater.exe)
    • do the upgrade, 做升级,
    • it shall download the updated(preferred zipped) project from server/web. 它应从服务器/网站下载更新的(首选压缩)项目。
    • Stop any running instances. 停止所有运行的实例。
    • Unzipping the content. 解压缩内容。
    • Backup existing files(rename) 备份现有文件(重命名)
    • copy/install the new version of the project, 复制/安装新版本的项目,
    • Start the application (when the app is restarted successfully it will delete its own backup file). 启动应用程序(当应用程序成功重启时,它将删除自己的备份文件)。
  • if a major release is detected eg: 3.0.0 如果检测到主要版本,例如:3.0.0
    • notifies the user there is a major upgrade 通知用户有重大升级
    • if user accepts, download the installer 如果用户接受,请下载安装程序
    • runs a full installer update 运行完整的安装程序更新

Does this help? 这有帮助吗?

VS Deployment project for a web app is not that easy to master and somewhat not reliable. 用于Web应用程序的VS部署项目并不容易掌握,有些不可靠。 What I'd suggest: 我建议的是什么:

  1. Modify your Admin.exe into a .NET Windows service. 将Admin.exe修改为.NET Windows服务。 Seebelow why would you need to do it. 看看为什么你需要这样做。
  2. Use sc.exe, InstallUtil.exe or installer-building services like installer.codeeffects.com to reinstall your service fast on every deployment. 使用sc.exe,InstallUtil.exe或安装程序构建服务(如installer.codeeffects.com)可在每次部署时快速重新安装服务。 Btw, if I remember correctly, at installer.codeeffects.com you can download a VS example code of how to build a .NET Windows service if you're new to services. 顺便说一下,如果我没记错的话,在installer.codeeffects.com上你可以下载一个VS示例代码,说明如果你不熟悉服务,如何构建.NET Windows服务。

Deployment could be done like this (assuming that your needs in automation is minimal and you're fine deploying almost manually): 可以像这样进行部署(假设您在自动化方面的需求很少,而且几乎可以手动部署):

Run either of the above mentioned tools to reinstall your service first. 运行上述任一工具以首先重新安装您的服务。 The sc.exe and InstalUtil.exe tools support command line. sc.exe和InstalUtil.exe工具支持命令行。 Therefore, if your web app, VS and the service is running on the same machine (your development computer, I assume?), you can right-click the web project in VS, select Properties and set pre- or post-build commands in the Build Events tab there. 因此,如果您的Web应用程序,VS和服务在同一台计算机(您的开发计算机,我假设?)上运行,您可以右键单击VS中的Web项目,选择“属性”并设置构建前或构建后命令那里的Build Events选项卡。 This way your VS can automatically rebuild and reinstall your service before you publish your web app. 这样,您的VS可以在发布Web应用程序之前自动重建并重新安装您的服务。 This is the main reason why the exe program is not good in your case, a Windows service would serve you better. 这就是为什么exe程序在你的情况下不好的主要原因,Windows服务会更好地为你服务。

Then deploy your web app (assuming it's been build as discussed above). 然后部署您的Web应用程序(假设它已按照上面的讨论进行构建)。 No biggies here, just use the Publish command from your VS or move all files of your web app except for the .cs files, /Properties/ and /obj/ folders. 这里没有大佬,只需使用VS中的发布命令或移动您的Web应用程序的所有文件,除了.cs文件,/ Properties /和/ obj /文件夹。 Or, if running from the project's folder, just right click the main page and select "View in Browser" - this will start the run time through VS without starting the debugger. 或者,如果从项目文件夹运行,只需右键单击主页面并选择“在浏览器中查看” - 这将通过VS启动运行时而不启动调试器。

Sorry for such a lengthy post. 很抱歉这么长的帖子。 Did I understand your question and clarifications correctly? 我是否正确理解了您的问题和说明? :) :)

What about making admin.exe a click once deployment. 如何在部署后点击admin.exe。 Then in your admin.exe, before you check the integrity of business rules, check if an update is available. 然后在admin.exe中,在检查业务规则的完整性之前,检查更新是否可用。 If it is, update and then continue on with your checks. 如果是,请更新,然后继续检查。

In order to make things simple and make sure I would be able to roll back everything, I would create a PowerShell Script that performed the following actions: 为了简化操作并确保我能够回滚所有内容,我将创建一个执行以下操作的PowerShell脚本:

  1. Stop the Application Pool. 停止应用程序池。
  2. Copy the current web app to the "history folder" so you can rollback to that version if required 将当前Web应用程序复制到“历史记录文件夹”,以便您可以根据需要回滚到该版本
  3. Deploy the new web app 部署新的Web应用程序
  4. Stop the current admin.exe from services 从服务中停止当前的admin.exe
  5. Uninstall the admin.exe, by executing the Uninstall.bat (this is quite common for Windows Services) 通过执行Uninstall.bat卸载admin.exe(这在Windows服务中很常见)
  6. Copy the current admin.exe app to the history folder (see 2) 将当前的admin.exe应用程序复制到历史文件夹(参见2)
  7. Copy the new admin.exe to the correct location and run install.bat 将新的admin.exe复制到正确的位置并运行install.bat
  8. Start the new service 启动新服务
  9. Start the application Pool 启动应用程序池

You can automate all of that in a Powershell script (the only thing I'm not sure is about the app pool, but I'm pretty sure that you can do this). 你可以在Powershell脚本中自动化所有这些(我唯一不确定的是应用程序池,但我很确定你可以这样做)。

More info on PowerShell can be found here: http://arstechnica.com/business/news/2005/10/msh.ars/2 有关PowerShell的更多信息,请访问: http//arstechnica.com/business/news/2005/10/msh.ars/2

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

相关问题 在Windows和Web App中处理数据库升级的最佳方法是什么? - What's the best way to process database upgrades in Windows and Web App? 针对 ASP.NET REST Web ZDB974238714CA8DE63FZACE7服务器运行单元测试的最佳方法是什么 - What's the best way to run unit tests against an ASP.NET REST Web API server 读取另一个过程击键的最佳方法是什么? - What's the best way to read another process keystrokes? 监视套接字以获取新数据然后处理该数据的最佳方法是什么? - What's the best way to monitor a socket for new data and then process that data? 检查服务器收到的第一条消息的最佳方法是什么? - What's the best way to check the first message that's received by the server? 将Web应用程序部署到生产中的最佳方法 - Best way to deploy a web app to production 为 Web 服务生成动态 XML 的最佳方法是什么? - What's the Best way to Generate a Dynamic XML for Web Service? 在网络主机上存储密码或私钥的最佳方法是什么? - What's the best way to store a password or private key on a web host? 关闭.Net Winforms应用程序并删除可执行文件的最佳方法是什么 - What's the best way to shut down a .Net winforms application and delete the executable 在c#中获取被调用可执行文件的完整路径和文件名的最佳方法是什么? - What's the best way to get the full path and filename of the invoked executable in c#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM