[英]What's the best way to deploy an executable process on a web server?
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! 谢谢!
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会找到能够提供以下解决方案的人:
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 Powershell与PSExec之类的东西来远程执行复制和更新命令。
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 "Admin"" />
<Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) delete "Admin"" />
<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 "Admin" binpath= "C:\path-to-admin\admin.exe" start= auto obj= $(User) password= $(Password)" />
<Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) start "Admin"" />
</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 我要做的是
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文件的内容,然后与内置(自我)版本号进行比较。
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:
我建议的是什么:
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脚本:
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.