NSQ Re-Queue половина сообщения - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть массив Ids типа int64 И это мое сообщение Nsq, которое я пытаюсь опубликовать.

nsqMsg := st{
    Action  :     "insert",
    Ids     :     Ids
    GID     :     Gids
}

msg, err := json.Marshal(nsqMsg)
if err != nil {
    log.Println(err)
    return err
}
err = nsqProducer.Publish(TOPIC-NAME, msg)
if err != nil {
    log.Println(err)
    return err
}

В то время как у моего потребителя я беру каждый идентификатор один за другим и выбираю информацию, основанную на моем идентификаторе, из моего хранилища данных.

Таким образом, при извлечении может быть случай, если мой метод CreateObject возвращает ошибку, поэтому я обрабатываю этот случай, запрашивая msg (который выдает ошибку), и поэтому его можно повторить.

for i := 0; i < len(data.Ids); i++ {

    Object, err := X.CreateObject(data.Ids[i)
        if err != nil {
            requeueMsgData = append(requeueMsgData, data.Ids[i])
            continue
        }
        DataList = append(DataList, Object)
    }

    if len(requeueMsgData) > 0 {
        msg, err := json.Marshal(requeueMsgData)
        if err != nil {
            log.Println(err)
            return err
        }
        message.Body = msg
        message.Requeue(60 * time.Second)
        log.Println("error while creating Object", err)
        return n
}

Итак, это правильный способ сделать это? Есть ли у них этот недостаток? Лучше ли опубликовать его снова?

Ответы [ 2 ]

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

В соответствии с тем, что говорил Долан, есть несколько случаев, с которыми вы можете столкнуться:

  • Время ожидания основного сообщения / аренды истекло, и вы снова получаете ВСЕ идентификаторы (из исходного сообщения). NSQ обеспечивает семантику "хотя бы один раз" .
  • Время ожидания любого отдельного сообщения истекло и оно никогда не завершается (откат к основному IDS)

Поскольку nsq может (и большинство def будет: p) доставлять сообщения более одного раза, CreateObjects может / должен быть идемпотентным для обработки этого случая.

Кроме того, повторная доставка является важным механизмом безопасности, Исходное сообщение не должно быть найдено до тех пор, пока все индивидуальные идентификаторы или подтвержденные не будут созданы или успешно помещены в очередь, что гарантирует отсутствие потери данных.


IMO, как вы обрабатываете, выглядит совершенно неплохо, но наиболее важные соображения IMO обращаются с корректностью / целостностью данных в среде, где будут получены дубликаты сообщений .


Другой вариант может заключаться в том, чтобы пакетировать Requeue так, чтобы он пытался создать одно выходное сообщение с ошибочными идентификаторами, что могло бы сократить количество сообщений в очереди в любой момент времени:

Рассмотрим сообщение с 3 идентификаторами:

идентификаторы сообщений: [id1, id2, id3]

id1 успешно создается, а id2 и id3 завершаются ошибкой:

программа может выполнить все операции и выдать одно сообщение с требованием, с id2, id3.

Но компромисс с этим тоже.

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

Некоторые очереди (например, Kafka) поддерживают подтверждение, когда элементы, которые были сняты с очереди, не удаляются из очереди до тех пор, пока потребитель фактически не подтвердит успешное получение элемента.

Преимущество этой модели состоит в том, что, если потребитель умирает после потребления, но до подтверждения, элемент будет автоматически поставлен в очередь. Недостатком вашей модели является то, что в этом случае предмет может быть потерян.

Риск модели подтверждения состоит в том, что предметы теперь могут потребляться вдвое. Когда потребитель пытается получить потребление, которое имеет побочные эффекты (например, увеличение счетчика или изменение базы данных), но не подтверждает, что повторные попытки могут не дать желаемого результата. (обратите внимание, что при чтении документов nsq повторные попытки не гарантируются, даже если вы не ставите данные в очередь, поэтому ваш код, вероятно, в любом случае должен будет защищаться от этого).

Вам следует изучить тему «Точно один раз» и «Максимум один раз», если вы хотите понять это глубже.

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

...