创build针对Linux Docker容器的长期运行的.NET Core服务
似乎有两种实质性的.NET Core项目:ASP.NET Core Web App和Console App。 我想在一个Docker环境(Linux容器)中构build一个类似Windows服务的东西,这个过程开始的地方无限期地运行,并且只在被告知的时候停止。 这两个项目types都不适合。 我错过了什么吗?
这两种types的应用程序都是有意义的,这取决于您如何计划与此服务进行通信。
如果你想通过一些TCP端口上的标准HTTP与它进行通信,那么使用ASP.Net核心Web应用程序将使事情变得简单。
如果你想通过一些比RabbitMQ,Kafka,原始TCP套接字或其他东西更“奇特”的方式进行通信,那么Console Application就是你想要的。 正如Gareth Luckett的答案所指出的,诀窍就是确保你的main
function块。 正在运行的Docker容器只要容器应该运行,就会期望主线程阻塞。
“控制台”这个词在这里可能有些误导。 微软使用它来区分它与“GUI”应用程序(如WinForms,WPF,UWP,Xamarin等)或通过IIS带来的Web应用程序。 ASP.NET核心应用程序只是带有库的控制台应用程序来托pipeWeb服务器。
所以对于你的应用程序,“控制台”是你想要的项目types。 正如@mason所提到的,即使Windows服务也只是“控制台”应用程序 – 一个不是GUI应用程序的.exe文件。
不幸的是,由于控制台应用程序在运行时需要stdin,因此通过docker它将立即退出。 你可以使用asp.net“托pipe”它。
public class Program { public static ManualResetEventSlim Done = new ManualResetEventSlim(false); public static void Main(string[] args) { //This is unbelievably complex because .NET Core Console.ReadLine() does not block in a docker container...! var host = new WebHostBuilder().UseStartup(typeof(Startup)).Build(); using (CancellationTokenSource cts = new CancellationTokenSource()) { Action shutdown = () => { if (!cts.IsCancellationRequested) { Console.WriteLine("Application is shutting down..."); cts.Cancel(); } Done.Wait(); }; Console.CancelKeyPress += (sender, eventArgs) => { shutdown(); // Don't terminate the process immediately, wait for the Main thread to exit gracefully. eventArgs.Cancel = true; }; host.Run(cts.Token); Done.Set(); } } }
启动类:
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IServer, ConsoleAppRunner>(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { } }
ConsoleAppRunner类
public class ConsoleAppRunner : IServer { /// <summary>A collection of HTTP features of the server.</summary> public IFeatureCollection Features { get; } public ConsoleAppRunner(ILoggerFactory loggerFactory) { Features = new FeatureCollection(); } /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary> public void Dispose() { } /// <summary>Start the server with an application.</summary> /// <param name="application">An instance of <see cref="T:Microsoft.AspNetCore.Hosting.Server.IHttpApplication`1" />.</param> /// <typeparam name="TContext">The context associated with the application.</typeparam> public void Start<TContext>(IHttpApplication<TContext> application) { //Actual program code starts here... Console.WriteLine("Demo app running..."); Program.Done.Wait(); // <-- Keeps the program running - The Done property is a ManualResetEventSlim instance which gets set if someone terminates the program. } }
来源: https : //stackoverflow.com/a/40549512/2238275
- 如何在.NET核心应用程序泊坞窗图像中包含依赖关系?
- 将Docker容器从Visual Studio 2017 RTM部署到生产服务器
- 在Docker中运行.Net Core 2.0上的IdentityServer4 – 访问主机资源
- WebSocket客户端错误.net核心与Linux Docker图像与botframework直线
- 如何检查在PS1中dotnet恢复是否正常?
- 用已经下载的NuGet包构build自定义的Docker microsoft dotnet映像
- 捕获404并redirect到wwwroot
- 通过docker容器从控制台应用程序连接到redis
- 在Docker-image microsoft / aspnetcore-build:1.1.0-msbuild中构buildASP.NET Core 1.1 preview4项目