go - 安排任务/消息以供以后处理/交付

标签 go scheduled-tasks publish-subscribe

我正在创建一个新服务,为此我有一个包含状态字段的数据库条目 (Mongo),我需要根据当前时间更新该字段,例如,开始时间设置为两点几个小时后,我需要在数据库中将状态从 CREATED -> STARTED 更改,并且可以有多个这样的状态。

我想到的方法:

  1. 继续查询 <= 当前时间的数据库条目,然后相应地更改它们的状态。这会导致无缘无故的额外读取和一半时间的空读取,并且随着更多状态的进入,它会很快变得复杂。

  2. 我编写了一个作业调度程序(我正在使用 go,所以这并不难),并安排所有作业,但如果出现 panic /崩溃,我可能会丢失队列数据。

  3. 我使用 celery 等产品,找到了一个 go 实现 https://github.com/gocelery/gocelery

我发现的另一个任务调度程序在 Google Cloud 上 https://cloud.google.com/solutions/reliable-task-scheduling-compute-engine ,但我不想陷入专有技术。

我想为此使用一些 PubSub 服务,但找不到有延迟消息的服务(如果有的话)。我的问题主要是无法找到此问题的实际名称,以便能够正确搜索它,我什至尝试过搜索 Microsoft 文档。如果有人能给我指明正确的方向,或者如果我写的任何方法是我应该使用的方法,请告诉我,那将是一个很大的帮助!

更新: 针对同样的问题,找到了 Netflix 的另一种解决方案 https://medium.com/netflix-techblog/distributed-delay-queues-based-on-dynomite-6b31eca37fbc

最佳答案

我认为您是对的,您要解决的问题是作业或任务调度问题。

许多公司使用的一种方法是您提议的系统:将作业插入到数据存储中并指定执行时间,然后可以轮询该数据存储以查找要运行的作业。有一些优化可以防止额外的读取,比如定期轮询数据库和使用指数退避。该系统的优点是可以容忍节点故障,缺点是增加了系统的复杂性。

环顾四周,除了您链接的那个 ( https://github.com/gocelery/gocelery ) 还有这个模型的其他实现 ( https://github.com/ajvb/kalahttps://github.com/rakanalh/scheduler 是我在快速搜索后找到的)。

您描述的另一种方法“安排正在进行的作业”在 go 中非常简单,因为停放的 goroutines 非常便宜。只需廉价地为您的工作生成一个 goroutine 就很简单。这很简单,但缺点是如果进程挂掉,工作就会丢失。

go func() {
    <-time.After(expirationTime.Sub(time.Now()))

    // do work here.
}()

我见过但不推荐的最后一种方法是回调模型(类似于 https://gitlab.com/andreynech/dsched )。这是您的服务调用另一个服务(通过 http、grpc 等)并在特定时间安排回调的地方。优点是如果您有多个不同语言的服务,它们可以使用相同的调度程序。

总的来说,在您决定解决方案之前,我会考虑一些权衡:

  • 失业的可接受程度如何?如果某些作业在一小部分时间内丢失是可以接受的,那么进程内解决方案也许是可以接受的。
  • 作业要等多久?如果它比主机的关闭时间长,也许基于数据存储的解决方案更好。
  • 您是否需要在多台机器上分配作业负载?如果您需要分配负载,分片和调度是棘手的事情,您可能需要考虑使用更现成的解决方案。

祝你好运!希望对您有所帮助。

关于go - 安排任务/消息以供以后处理/交付,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52242316/

相关文章:

linux - libgit2 alpine linux docker 错误

objective-c - 在特定时间运行 Mac 应用程序方法涉及哪些步骤?

scheduled-tasks - 任务计划程序-Windows server 2012 - 任务的上次运行被用户终止

sockets - ZeroMQ PUB/SUB DEALER/ROUTER混合模式

node.js - Redis 发布/订阅设计问题

azure - 在Golang SDK中获取Azure位置列表的问题

go - 接口(interface)指针的奇怪行为

json - 如何为 Go 中从标量派生的类型实现 UnmarshalJSON?

java - 从 Spring 3 迁移到 Spring 4 - org.springframework.scheduling.quartz.CronTriggerBean

database - 面向时间序列的物联网平台