威尔背景服务在kubernetes群集上很好地发挥作用

发布于 2025-01-28 17:44:29 字数 746 浏览 3 评论 0 原文

我有一个kubernetes群集,我打算在吊舱中实现服务 - 该服务将接受GRPC请求,开始长期运行的过程,但返回到呼叫者,以表明该过程已经启动。调查表明, iHostedService backgroundService )是这样做的方法。

我的问题是,将使用 backgroundService 与ASP.NET和K8S的各种整洁功能表现得很好:

  • 将水平缩放理解,即使该服务将出现,服务即使将出现,服务都将过载并旋转新实例由于所有工作都是背景(我感谢可以实现的挂钩,我想知道默认行为是什么),
  • 等待互换了,另一个与背景服务的运行正常(我只在收到一条消息的情况下经历了等待,因此可以处理另一条消息,但是背景服务不是消息传递上下文
  • ) ASP.NET通常会管理限制太多请求,如果服务器太忙,请备份,但是如果“忙碌”是背景过程,则该请求仍然有效,
  • 这是减轻超载服务的最佳方法(如果水平扩展为不是一个选项) - 我可以将GRPC调用reutrn“太忙”,但需要检测到它(不确定这是CPU绑定,内存还是仅仅是背景服务的数量),
  • 我是否应该考虑除 backgroundServiceServiceserviceserviceserviceserviceserviceserviceservices服务。 对于此任务,

我希望答案是“一切都起作用”,但要确认它比希望...确认更好...

I have a kubernetes cluster into which I'm intending to implement a service in a pod - the service will accept a grpc request, start a long running process but return to the caller indicating the process has started. Investigation suggests that IHostedService (BackgroundService) is the way to go for this.

My question is, will use of BackgroundService behave nicely with various neat features of asp.net and k8s:

  • Will horizontal scaling understand that a service is getting overloaded and spin up a new instance even though the service will appear to have no pending grpc requests because all the work is background (I appreciate there's probably hooks that can be implemented, I'm wondering what's default behaviour)
  • Will the notion of awaiting allowing the current process to be swapped out and another run work okay with background services (I've only experienced it where one message received hits an await so allows another message to be processed, but backround services are not a messaging context)
  • I think asp.net will normally manage throttling too many requests, backing off if the server is too busy, but will any of that still work if the 'busy' is background processes
  • What's the best method to mitigate against overloading the service (if horizontal scaling is not an option) - I can have the grpc call reutrn 'too busy' but would need to detect it (not quite sure if that's cpu bound, memory or just number of background services)
  • Should I be considering something other than BackgroundService for this task

I'm hoping the answer is that "it all just works" but feel it's better to have that confirmed than to just hope...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若无相欠,怎会相见 2025-02-04 17:44:29

调查表明,iHostedService(BackgroundService)是这样做的方法。

i 强烈推荐带有单独的背景服务队列。分为两个图像,一个运行ASP.NET GRPC请求,另一个处理耐用队列的图像并不难(这可以是控制台应用程序 - 请参见VS中的服务工作者模板)。请注意,使用 non 的解决方案是不可靠的(即,每当pod重新启动或缩放时,工作可能会丢失)。这包括内存的队列,通常建议将其作为“解决方案”。

如果您确实在控制台应用程序中制作自己的背景服务,建议您应用几个调整(在我的博客上注明):

  • wrap executeasync in task.run
  • 始终具有顶级<代码>在 executeasync 中尝试/ catch
  • 调用 ihostapplicationlifetime.stopapplication 出于任何原因停止时。

将水平缩放了解,即使服务似乎没有待处理的GRPC请求,服务即使所有工作都是背景(我很感谢可以实现的挂钩),即使该服务似乎没有待处理的GRPC请求,也可以实现新实例的水平扩展。想知道什么是默认行为)

我更喜欢使用两个不同图像的原因之一是它们可以在不同的触发器上扩展:GRPC请求API和对工作人员的排队消息。根据您的队列,使用“排队消息”作为触发器可能需要自定义公制提供商。我确实更喜欢使用“排队消息”,因为它是工人形象的自然缩放机制。诸如CPU使用之类的开箱即用解决方案并不总是很好地工作 - 特别是对于您正在使用的异步处理器而言。

是否会等待允许当前过程进行交换,而另一项运行的工作也可以使用背景服务(我只在收到一条消息收到的命中率上等待着它,因此可以处理另一个消息,但是背景服务是不是消息传递上下文)

背景服务可以是异步的,而不会出现任何问题。实际上,批次获取消息并同时处理它们并不少见。

我认为ASP.NET通常会管理限制太多请求,如果服务器太忙,请备份,但是如果“忙碌”是背景过程,则任何一个仍然可以正常工作

编号ASP.NET只有节气门请求,则该请求仍然有效。背景服务确实在ASP.NET上注册,但这仅是 在优雅的关闭时提供最佳效果。 ASP.NET不知道背景服务有多忙,在待处理的队列项目,CPU使用或即将发出的请求方面。

减轻服务过载的最佳方法是什么(如果不是水平缩放的选项) - 我可以让GRPC调用REUTRN“太忙”,但需要检测到它(不确定这是否是CPU绑定,内存,内存,或仅数量的背景服务)

如果您使用耐用的队列 +独立的工作图像解决方案,则不是问题。 GRPC呼叫几乎总是可以在队列中添加另一个消息(非常简单且快速),并且K8可以根据您(可能是自定义的)“出色的队列消息”的指标自动估算。

Investigation suggests that IHostedService (BackgroundService) is the way to go for this.

I strongly recommend using a durable queue with a separate background service. It's not that difficult to split into two images, one running ASP.NET GRPC requests, and the other processing the durable queue (this can be a console app - see the Service Worker template in VS). Note that solutions using non-durable queues are not reliable (i.e., work may be lost whenever a pod restarts or is scaled down). This includes in-memory queues, which are commonly suggested as a "solution".

If you do make your own background service in a console app, I recommend applying a few tweaks (noted on my blog):

  • Wrap ExecuteAsync in Task.Run.
  • Always have a top-level try/catch in ExecuteAsync.
  • Call IHostApplicationLifetime.StopApplication when the background service stops for any reason.

Will horizontal scaling understand that a service is getting overloaded and spin up a new instance even though the service will appear to have no pending grpc requests because all the work is background (I appreciate there's probably hooks that can be implemented, I'm wondering what's default behaviour)

One reason I prefer using two different images is that they can scale on different triggers: GRPC requests for the API and queued messages for the worker. Depending on your queue, using "queued messages" as the trigger may require a custom metric provider. I do prefer using "queued messages" because it's a natural scaling mechanism for the worker image; out-of-the-box solutions like CPU usage don't always work well - in particular for asynchronous processors, which you mention you are using.

Will the notion of awaiting allowing the current process to be swapped out and another run work okay with background services (I've only experienced it where one message received hits an await so allows another message to be processed, but backround services are not a messaging context)

Background services can be asynchronous without any problems. In fact, it's not uncommon to grab messages in batches and process them all concurrently.

I think asp.net will normally manage throttling too many requests, backing off if the server is too busy, but will any of that still work if the 'busy' is background processes

No. ASP.NET only throttles requests. Background services do register with ASP.NET, but that is only to provide a best-effort at graceful shutdown. ASP.NET has no idea how busy the background services are, in terms of pending queue items, CPU usage, or outgoing requests.

What's the best method to mitigate against overloading the service (if horizontal scaling is not an option) - I can have the grpc call reutrn 'too busy' but would need to detect it (not quite sure if that's cpu bound, memory or just number of background services)

Not a problem if you use the durable queue + independent worker image solution. GRPC calls can pretty much always stick another message in the queue (very simple and fast), and K8 can autoscale based on your (possibly custom) metric of "outstanding queue messages".

贪恋 2025-02-04 17:44:29

通常,“一切都起作用”。
对于自动水平尺度,您需要一个自动制剂,请阅读以下内容:
但是您可以自己扩展( kubectl量表部署您的删除 - replicas = 10 )。

假设您将部署后端,这将从一个POD开始。您的Autoscaler会观看您的吊舱(例如使用CPU),并在您的负载高时为您启动一个新的豆荚。

将开始第二个吊舱。每个新请求都会发送到不同的POD(圆形旋转)。
没有必要,您的后端油门通话。它应该尽可能处理许多电话。

Generally, "it all works".
For the automatic horizontal scale, you need a autoscaler, read this: Horizontal Pod Autoscale
But you can just scale it yourself (kubectl scale deployment yourDeployment --replicas=10).

Lets assume, you have a deployment of your backend, which will start with one pod. Your autoscaler will watch your pod (eg. used cpu) and will start a new pod for you, when you have a high load.

A second pod will be started. Each new request will send to different pods (round-robin).
There is no need, that your backend throttle calls. It should just handle many calls as possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文