Планирование задач / сообщений для последующей обработки / доставки - PullRequest
0 голосов
/ 09 сентября 2018

Я создаю новый сервис, и для этого у меня есть записи в базе данных (Mongo), которые имеют поле состояния, которое мне нужно обновить на основе текущего времени, поэтому, например, время запуска было установлено равным двум Через несколько часов мне нужно изменить состояние CREATED -> STARTED в базе данных, и таких состояний может быть несколько.

Подходы, о которых я думал:

  1. Продолжайте запрашивать записи в базе данных, которые <= текущее время, а затем соответственно меняйте их состояния. Это вызывает дополнительные чтения без причины и половину пустых чтений, и это быстро усложняется с появлением большего количества состояний. </p>

  2. Я пишу планировщик заданий (я использую go, чтобы не было так сложно) и планирую все задания, но я могу потерять данные очереди в случае паники / сбоя.

  3. Я использую некоторые продукты, такие как сельдерей, нашел для него реализацию go https://github.com/gocelery/gocelery

Другой найденный мной планировщик заданий находится в Google Cloud https://cloud.google.com/solutions/reliable-task-scheduling-compute-engine,, но я не хочу зацикливаться на проприетарных технологиях.

Я хотел использовать для этого какой-нибудь сервис PubSub, но не смог найти тот, который задерживал сообщения (если это так). Моя проблема в основном не в том, что я не могу найти фактическое имя для этой проблемы, чтобы найти его правильно, я даже пытался искать документы Microsoft. Если кто-то может указать мне правильное направление, или если какой-то из написанных мною подходов мне следует использовать, пожалуйста, дайте мне знать, это было бы очень полезно!

UPDATE: Нашел еще одно решение от Netflix, для той же проблемы https://medium.com/netflix-techblog/distributed-delay-queues-based-on-dynomite-6b31eca37fbc

1 Ответ

0 голосов
/ 09 сентября 2018

Я думаю, что вы правы в том, что проблема, которую вы пытаетесь решить, это проблема планирования работы или задачи.

Один из подходов, который используют многие компании, - это система, которую вы предлагаете: задания вставляются в хранилище данных со временем выполнения, а затем это хранилище данных может быть опрошено для запуска заданий. Существуют оптимизации, которые предотвращают дополнительные операции чтения, такие как регулярный опрос базы данных и использование экспоненциального отката. Преимущество этой системы в том, что она терпима к сбоям узла, а недостаток - сложность системы.

Оглядываясь вокруг, в дополнение к той, которую вы связали (https://github.com/gocelery/gocelery), есть и другие реализации этой модели (https://github.com/ajvb/kala или https://github.com/rakanalh/scheduler были те, которые я нашел после быстрого поиска) .

Другой подход, который вы описали, «планирование рабочих мест в процессе» очень прост на ходу, потому что припаркованные подпрограммы очень дешевы. Это просто, чтобы просто запустить goroutine для вашей работы дешево. Это просто, но недостатком является то, что если процесс умирает, работа теряется.

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

    // do work here.
}()

Последний подход, который я видел, но не рекомендую, - это модель обратного вызова (что-то вроде https://gitlab.com/andreynech/dsched).). Здесь ваша служба вызывает другую службу (через http, grpc и т. Д.) И планирует обратный вызов. на определенное время. Преимущество состоит в том, что если у вас есть несколько служб на разных языках, они могут использовать один и тот же планировщик.

В целом, прежде чем вы примете решение, я бы рассмотрел некоторые компромиссы:

  • Насколько приемлема потеря работы? Если все в порядке, что некоторые задания теряются в течение небольшого процента времени, возможно, приемлемо внутрипроцессное решение.
  • Как долго будут ждать работы? Если это больше, чем период отключения вашего хоста, возможно, решение на основе хранилища данных будет лучше.
  • Вам нужно будет распределить нагрузку на несколько машин? Если вам нужно распределить нагрузку, шардинг и планирование - это сложная задача, и вы можете рассмотреть возможность использования более готового решения.

Удачи! Надеюсь, это поможет.

...