运行 docker 中的 c# worker 服务有意义吗?
Does it make sense to run a c# worker service in docker?
我正在 docker 中开发一个多容器应用程序。其中一项服务是 C# 中的 long-运行 控制台应用程序,它基本上对数据库进行一些轮询并将数据发送到 e 服务器。我只是通过添加以下语句来保留服务 运行:
while(true);
现在我正在考虑将此服务更改为 .NET Core worker 服务(甚至 windows 服务,因为我只在 windows 主机上使用 windows 容器) .我已经阅读了一些关于工作人员服务的优点的文章,但是当涉及到容器化应用程序时,它们似乎都已经过时了,因为我的容器无论如何都是 运行 作为一种“后台服务”(而且我只使用一种服务每 container/image)。所以我的问题是:
运行 docker 中的核心辅助服务与 docker 中的 运行 控制台应用程序相比,有什么好处或缺点吗?
更新:对于“工作者服务”,我指的是 .NET Core 中可用的新工作者服务模板 3.x:https://www.stevejgordon.co.uk/what-are-dotnet-worker-services
简而言之,您的快乐路径代码的功能可能“大致相同”。
然而:
使用“通用主机”的好处是您可以享受 Microsoft 为您创建的可重用组件的好处......而不是自己动手。
这意味着(恕我直言)更好的代码,因为您不需要亲自处理大量 运行ning 过程中的常见问题。
基本上,与滚动您自己的实现相比,您会“免费”获得大量管道代码。
Pre 3.0/3.1 许多此功能已与 asp.net 名称空间结合。 3.0/3.1 更新有很多“将其放入 asp.net 和 .net(非 asp.net)的公共位置”以供使用。 Aka,与 asp.net.
分手
设置:(专用方法“AddHostedService”)
services.AddHostedService<MyWorkerThatImplementsIHostedService>();
因此,当未来的开发人员查看上面的代码时,他们会确切地知道发生了什么。 (与找出自定义滚动实现相比)
或者在更大的代码示例中:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<MyWorkerThatImplementsIHostedService>();
});
}
上面的代码~~看起来~~ asp.net'ish,但实际上是.net(非asp.net)代码。
也就是说,您的一致性得到了提高。
关机:
您获得了所有内置的“关闭”选项。这些都是“正常”关闭选项……不幸的是,“快乐之路”开发人员通常不会考虑这些选项。如果有任何理由跳进这个迷你图书馆......有某种优雅的出口就是这样。硬退出可能会使您的处理处于未知的难以排除故障的状态。
CNLT-C
Programmatically (see https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.ihostapplicationlifetime.stopapplication?view=dotnet-plat-ext-3.1 )
Kubernetes Shutdown
微软甚至想出了“我能不能把最终关机延迟一些”
参见:
这是一个不错的 link,它显示了一些选项(计时器、队列和监视器)
您还可以将代码部署为:
容器
Windows 服务
** Linux 守护进程(参见 https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.systemd.systemdhelpers.issystemdservice?view=dotnet-plat-ext-3.1 )(这对于传统的 dotnet 框架开发人员来说通常是一个新概念)
Azure 应用服务
哦,是的,Microsoft 甚至为您设计了“HealthChecks”。
瓶口线,用这个代替定制的卷材。考虑周全。
::::::::::::::::::::::以前的评论:::::::::::::::::::::::: ::::::::::(下)
.......
Long-运行C# 中的 ning 控制台应用程序
短版:
对于现代代码部署策略,这不仅仅是技术决策,还是财务决策。
更长的版本:
我最近讨论过这个问题,因为一些代码库已指定用于“转换为 dotnet 核心”和“我们如何转换旧的 windows 服务?”。
这是我的想法:
哲学上。
您必须考虑“我在哪里部署以及部署成本是多少?”,而不仅仅是技术问题。你提到 docker。但是你如何部署它?库伯内斯? (天蓝色的AKS,其他?)这是一条重要的信息。
恕我直言:使用“云”甚至本地 Kubernetes ....你不需要“Windows 服务”的心态,那只会 运行 和 运行 运行、运行不断增加成本。除非你有拥有这个。
您想启动一个进程,让它运行,并尽快关闭它。
现在,如果您需要每小时 运行,那很好。
现在,如果您需要“即时”或“尽快处理”(例如查看队列中的消息),那么也许您付出了代价并拥有了 运行 全部的东西时间,因为处理这些消息比您为 运行ning 服务支付的价格更重要。
从技术上讲,我喜欢
的想法
https://www.stevejgordon.co.uk/what-are-dotnet-worker-services
WHAT ARE WORKER SERVICES? Applications which do not require user
interaction. Use a host to maintain the lifetime of the console
application until the host is signalled to shut down. Turning a
console application into a long-running service. Include features
common to ASP.NET Core such and dependency injection, logging and
configuration. Perform periodic and long-running workloads.
但在财务上,我必须用 运行在 Azure 上(甚至在内部部署)的成本来抵消这一点。
处理 Message Queue 消息意味着 --> “是的,必须一直 运行”。所以我一直都在为拥有它付出代价运行。
如果我知道我的客户一次在半夜发布他们的导入文件,那么我不想支付总是 运行ning 的价格。我想要一个早上触发一次的控制台应用程序。进来,出去。尽快处理并离开。 Kubernetes 有调度机制。
对于 Azure,这不仅仅是技术决策,还是财务决策。
未提及:如果您的代码计划每小时 运行,但随后开始花费超过一小时 运行,您会遇到不同的问题。 Quartz.Net 是处理这些重叠问题的一种方法。
请记住,我必须对这个关于成本的争论非常坚定。大多数开发人员只想将 windows-services 转换为 dotnet-core 并完成它。但这不是长期的想法,因为越来越多的代码转移到云中,云操作的成本开始发挥作用。
PS
此外,请确保将所有代码向下移动到业务层........并让这些方法中的任何一种
Console.App(普通一个)
.NET Core 工作者服务
Quartz.Net 安排作业[=20=]
让上面的项目成为“调用您的业务逻辑层的薄顶层”,然后您就不会把自己逼到墙角了。你做的顶层越薄越好。基本上,我的控制台应用程序是
void Main(string args)
{
//wire up IoC
//pull out the business logic layer object from the Ioc
//call a single method on the business logic layer
}
和一些 appsettings.json 文件被 Program.cs 坐下。没有或很少。尽快将一切下推到业务逻辑层。
如果您总是要在容器中 运行,那么请使用控制台应用程序。我认为 运行ning 作为一种服务并没有内在的好处,因为在 Kubernetes 等适当的编排下,容器应该被认为是短暂的。此外,运行将您的 .NET Core 3.1.x 应用程序作为 Linux 或 Windows 容器时,如果您保持简单,即控制台。
此外,我会在您的控制台中使用以下行,以确保它与为容器分配的 CPU 兼容:
while(true)
{
Thread.Sleep(1 * 1000);
}
我正在 docker 中开发一个多容器应用程序。其中一项服务是 C# 中的 long-运行 控制台应用程序,它基本上对数据库进行一些轮询并将数据发送到 e 服务器。我只是通过添加以下语句来保留服务 运行:
while(true);
现在我正在考虑将此服务更改为 .NET Core worker 服务(甚至 windows 服务,因为我只在 windows 主机上使用 windows 容器) .我已经阅读了一些关于工作人员服务的优点的文章,但是当涉及到容器化应用程序时,它们似乎都已经过时了,因为我的容器无论如何都是 运行 作为一种“后台服务”(而且我只使用一种服务每 container/image)。所以我的问题是:
运行 docker 中的核心辅助服务与 docker 中的 运行 控制台应用程序相比,有什么好处或缺点吗?
更新:对于“工作者服务”,我指的是 .NET Core 中可用的新工作者服务模板 3.x:https://www.stevejgordon.co.uk/what-are-dotnet-worker-services
简而言之,您的快乐路径代码的功能可能“大致相同”。
然而:
使用“通用主机”的好处是您可以享受 Microsoft 为您创建的可重用组件的好处......而不是自己动手。
这意味着(恕我直言)更好的代码,因为您不需要亲自处理大量 运行ning 过程中的常见问题。
基本上,与滚动您自己的实现相比,您会“免费”获得大量管道代码。
Pre 3.0/3.1 许多此功能已与 asp.net 名称空间结合。 3.0/3.1 更新有很多“将其放入 asp.net 和 .net(非 asp.net)的公共位置”以供使用。 Aka,与 asp.net.
分手设置:(专用方法“AddHostedService”)
services.AddHostedService<MyWorkerThatImplementsIHostedService>();
因此,当未来的开发人员查看上面的代码时,他们会确切地知道发生了什么。 (与找出自定义滚动实现相比)
或者在更大的代码示例中:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<MyWorkerThatImplementsIHostedService>();
});
}
上面的代码~~看起来~~ asp.net'ish,但实际上是.net(非asp.net)代码。 也就是说,您的一致性得到了提高。
关机:
您获得了所有内置的“关闭”选项。这些都是“正常”关闭选项……不幸的是,“快乐之路”开发人员通常不会考虑这些选项。如果有任何理由跳进这个迷你图书馆......有某种优雅的出口就是这样。硬退出可能会使您的处理处于未知的难以排除故障的状态。
CNLT-C
Programmatically (see https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.ihostapplicationlifetime.stopapplication?view=dotnet-plat-ext-3.1 )
Kubernetes Shutdown
微软甚至想出了“我能不能把最终关机延迟一些”
参见:
这是一个不错的 link,它显示了一些选项(计时器、队列和监视器)
您还可以将代码部署为:
容器
Windows 服务
** Linux 守护进程(参见 https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.systemd.systemdhelpers.issystemdservice?view=dotnet-plat-ext-3.1 )(这对于传统的 dotnet 框架开发人员来说通常是一个新概念)
Azure 应用服务
哦,是的,Microsoft 甚至为您设计了“HealthChecks”。
瓶口线,用这个代替定制的卷材。考虑周全。
::::::::::::::::::::::以前的评论:::::::::::::::::::::::: ::::::::::(下)
.......
Long-运行C# 中的 ning 控制台应用程序
短版:
对于现代代码部署策略,这不仅仅是技术决策,还是财务决策。
更长的版本:
我最近讨论过这个问题,因为一些代码库已指定用于“转换为 dotnet 核心”和“我们如何转换旧的 windows 服务?”。
这是我的想法:
哲学上。
您必须考虑“我在哪里部署以及部署成本是多少?”,而不仅仅是技术问题。你提到 docker。但是你如何部署它?库伯内斯? (天蓝色的AKS,其他?)这是一条重要的信息。
恕我直言:使用“云”甚至本地 Kubernetes ....你不需要“Windows 服务”的心态,那只会 运行 和 运行 运行、运行不断增加成本。除非你有拥有这个。
您想启动一个进程,让它运行,并尽快关闭它。
现在,如果您需要每小时 运行,那很好。
现在,如果您需要“即时”或“尽快处理”(例如查看队列中的消息),那么也许您付出了代价并拥有了 运行 全部的东西时间,因为处理这些消息比您为 运行ning 服务支付的价格更重要。
从技术上讲,我喜欢
的想法https://www.stevejgordon.co.uk/what-are-dotnet-worker-services
WHAT ARE WORKER SERVICES? Applications which do not require user interaction. Use a host to maintain the lifetime of the console application until the host is signalled to shut down. Turning a console application into a long-running service. Include features common to ASP.NET Core such and dependency injection, logging and configuration. Perform periodic and long-running workloads.
但在财务上,我必须用 运行在 Azure 上(甚至在内部部署)的成本来抵消这一点。
处理 Message Queue 消息意味着 --> “是的,必须一直 运行”。所以我一直都在为拥有它付出代价运行。
如果我知道我的客户一次在半夜发布他们的导入文件,那么我不想支付总是 运行ning 的价格。我想要一个早上触发一次的控制台应用程序。进来,出去。尽快处理并离开。 Kubernetes 有调度机制。
对于 Azure,这不仅仅是技术决策,还是财务决策。
未提及:如果您的代码计划每小时 运行,但随后开始花费超过一小时 运行,您会遇到不同的问题。 Quartz.Net 是处理这些重叠问题的一种方法。
请记住,我必须对这个关于成本的争论非常坚定。大多数开发人员只想将 windows-services 转换为 dotnet-core 并完成它。但这不是长期的想法,因为越来越多的代码转移到云中,云操作的成本开始发挥作用。
PS
此外,请确保将所有代码向下移动到业务层........并让这些方法中的任何一种
Console.App(普通一个)
.NET Core 工作者服务
Quartz.Net 安排作业[=20=]
让上面的项目成为“调用您的业务逻辑层的薄顶层”,然后您就不会把自己逼到墙角了。你做的顶层越薄越好。基本上,我的控制台应用程序是
void Main(string args)
{
//wire up IoC
//pull out the business logic layer object from the Ioc
//call a single method on the business logic layer
}
和一些 appsettings.json 文件被 Program.cs 坐下。没有或很少。尽快将一切下推到业务逻辑层。
如果您总是要在容器中 运行,那么请使用控制台应用程序。我认为 运行ning 作为一种服务并没有内在的好处,因为在 Kubernetes 等适当的编排下,容器应该被认为是短暂的。此外,运行将您的 .NET Core 3.1.x 应用程序作为 Linux 或 Windows 容器时,如果您保持简单,即控制台。
此外,我会在您的控制台中使用以下行,以确保它与为容器分配的 CPU 兼容:
while(true)
{
Thread.Sleep(1 * 1000);
}