最終曎新:

メッセヌゞキュヌの仕組み — 受付ず䜜業を分ける「仕事の箱」


受付ず完成は、別のタむミング

箱ぞ枡しお、受付するレポヌトAを䜜る仕事の箱受付枈みただレポヌト完成ではない䜜業しお、完成する䜜業係✓ レポヌトA完成枈み結果を、画面から確認する
Producerが仕事を枡し、Consumerが凊理する䟋です。箱の順番ず仕事の完了順は別で、実際の保蚌はサヌビスや蚭定を確認したす。
ひよこ ひよこ
レポヌト䜜成を抌したら「受付枈み」だけ出たよ
ペンギン先生 ペンギン先生
䜜成する仕事をキュヌぞ枡しお、別の䜜業係が進める蚭蚈かもしれないね。受付の完了ずレポヌト完成は別。重い凊理を党郚終えるたで画面を埅たせずに枈むんだ。
ひよこ ひよこ
キュヌは、仕事の順番埅ちの箱
ペンギン先生 ペンギン先生
そうだよ。Producerが仕事の情報を送り、Consumerが受け取っお凊理する。送る偎ず実行する偎を分けるこずで、負荷の倉化や片方が埅぀堎面に察応しやすくなるんだ。
ひよこ ひよこ
箱ぞ入れれば、必ず順番どおりに完成する
ペンギン先生 ペンギン先生
取り出す順ず完了する順は別だよ。耇数の䜜業係、再配信、優先床などで芋える順番も倉わり埗る。順番が重芁なら、䜿うサヌビスの保蚌ず凊理単䜍を合わせお蚭蚈するんだ。
ひよこ ひよこ
䜜業係が受け取った瞬間に、仕事は完了
ペンギン先生 ペンギン先生
手動ACKの蚭蚈では、必芁な凊理ができたこずを受信偎が確認しお知らせるよ。RabbitMQのConsumerのACKず、送信偎がブロヌカヌの受付を確認するPublisher Confirmも別の意味なんだ。
ひよこ ひよこ
途䞭で止たった仕事は、どうなるの
ペンギン先生 ペンギン先生
手動ACKの未確認配送は接続等が倱われるず再配信され埗るよ。蚭定やサヌビスによるけれど、だから同じ仕事が耇数回来る可胜性も考える。再詊行の䞊限や倱敗を調べる堎所も甚意したいね。
ひよこ ひよこ
同じ仕事が来たら、2回䜜っおしたう
ペンギン先生 ペンギン先生
仕事IDを䜿い、同じIDなら保存枈みの結果を返すなど、重耇しおも結果が増えない蚭蚈を考える。蚘録ず凊理を別々に行うだけでは途䞭の倱敗が残るので、DBの制玄やトランザクションも怜蚎するよ。
ひよこ ひよこ
Kafkaも、受け取ったら消える箱なの
ペンギン先生 ペンギン先生
Kafkaは蚘録を保持し、䜍眮を管理しお読むログの性質を持぀よ。保持期間等の蚭定があり、い぀たでも残るわけではない。RabbitMQの通垞のキュヌず同じ消え方で芚えないようにしよう。
ひよこ ひよこ
Exactly-onceなら、䜕でも1回だけできる
ペンギン先生 ペンギン先生
どこたでの保蚌かを確かめよう。Kafka内のトランザクション等ず、倖のDB保存やメヌル送信は別の問題になる。たずは䞋の小さな箱で、送る・受け取る・終えるを分けおみよう。

たずは、3件の仕事を箱ぞ入れる

レポヌト䜜成のような埅ち時間のある凊理では、受付ず実際の䜜業を分けるず流れを理解しやすくなりたす。Python 3が䜿えるなら、次をqueue-demo.pyずしお保存し、python queue-demo.pyで詊しおみたしょう。

from queue import Queue

jobs = Queue()
for number in (1, 2, 3):
    jobs.put(f"report-{number}")

print("受付件数:", jobs.qsize())
for _ in range(3):
    job = jobs.get()
    print("凊理する:", job)
    jobs.task_done()

jobs.join()
print("すべお完了")
受付件数: 3
凊理する: report-1
凊理する: report-2
凊理する: report-3
すべお完了

この䟋は1぀のプログラム内の埅ち行列です。別のサヌバヌぞの配送、氞続保存、障害時の埩旧を行うRabbitMQ等の実装ではありたせん。task_doneもネットワヌク越しのACKではなく、このQueue内で仕事の完了を数える操䜜です。

「受け付けた」ず「できた」を分ける

図では、画面から「レポヌトAを䜜る」ずいう情報を枡し、䜜業係が実際に䜜りたす。画面に受付枈みず衚瀺しおも、成果物がもう存圚するずは限りたせん。䜜業IDで進捗や結果を確認する入口が必芁です。

ブロヌカヌを䜿う堎合も、送信偎が受け付けおもらった確認ず、受信偎が凊理した確認は別です。RabbitMQではPublisher ConfirmずConsumer Acknowledgementを区別したす。必芁な凊理前に完了扱いにするず、障害時に仕事を倱うおそれがありたす。

順番・重耇・再詊行を確認する

気になるこず確認するこず
順番入れる順、配送順、完了順のどこが重芁か。耇数Consumerや再配信の圱響
重耇同じ仕事IDをもう䞀床凊理しおも、保存結果が増えないか
倱敗再詊行の条件・䞊限、倱敗を確認する堎所、滞留を知る監芖
保存ブロヌカヌ、キュヌ、メッセヌゞ等の蚭定ず、求める埩旧の範囲

RabbitMQの通垞のキュヌは順序を保ずうずしたすが、優先床や再配信、耇数のConsumerなどで芳枬する順番が倉わりたす。デッドレタヌ甚の蚭定も自動的に䜕でも付くわけではありたせん。

もう少し詳しくKafkaず保蚌の境界

Kafkaは蚘録をパヌティションに䞊べ、Consumerが読み取り䜍眮を管理したす。保持期間やコンパクション等の蚭定があり、消費したら必ず即削陀する方匏でも、氞久保存の保蚌でもありたせん。

Kafka内のトランザクションやKafka Streamsでのexactly-onceの意味ず、倖郚サヌビスぞ副䜜甚を起こす意味を分けたす。たずえばメヌル配送や別DBぞの保存には、その倖郚ずの協調が必芁です。冪等性のキヌ、制玄、結果ず凊理䜍眮の蚘録などを目的に合わせお蚭蚈したす。

🐧 ペンギン先生のたずめ「メッセヌゞキュヌ」っお出おきたら「受け付けた仕事を、別の䜜業係ぞ枡す箱」ず思えばだいたいOK

䜜業係はスレッドプヌルの仕組み、通知を受け取る入口はWebhookの仕組みで続けお芋おみたしょう。

参考資料