Дастаўка, outbox і аднаўленне
Калі ход завяршаецца, адказ усё яшчэ мусіць дайсці да канала, з якога ён прыйшоў — надзейна і роўна адзін раз. AiHummer вырашае гэта з дапамогай транзакцыйнага outbox, ідэмпатэнтных пабочных эфектаў і аднаўлення ходу пасля перазапуску. Пры жаданні шына NATS можа несці дастаўку для большых разгортванняў.
Гарантаваная дастаўка
Адказ не адпраўляецца ўбудавана ў канцы ходу. Замест гэтага ён ставіцца ў чаргу ў outbox у складзе той самай працы, якая яго стварыла, а працаўнік дастаўкі забірае яго і адпраўляе ў зыходны канал. Паколькі адказ трывала запісваецца перад тым, як пакінуць сістэму, збой паміж “адказ створаны” і “адказ адпраўлены” не можа яго згубіць — пры перазапуску запіс у outbox усё яшчэ там, і дастаўка працягваецца.
turn produces reply
└─▶ enqueue in outbox (durable)
└─▶ delivery worker ─▶ originating channel
└─ acknowledged ─▶ marked delivered
Дастаўка спалучаецца з ідэмпатэнтнасцю, так што гэты працаўнік “хаця б адзін раз” дае роўна-аднаразовыя знешнія паводзіны: устойлівы да аднаўлення ключ рэестра і бар’ер пабочных эфектаў гарантуюць, што паўторна дастаўлены ці прайграны адказ адпраўляецца ў канал толькі адзін раз (гл. Шматарэндарнасць і ідэмпатэнтнасць).
[!NOTE] “Роўна адзін раз” тут апісвае знешне бачны вынік: карыстальнік атрымлівае адказ адзін раз. Унутры працаўнік можа спрабаваць дастаўку больш за адзін раз; узровень ідэмпатэнтнасці згортвае гэтыя спробы ў адну бачную адпраўку.
Аднаўленне ходу пасля перазапуску
Калі шлюз перазапускаецца пасярод ходу — разгортванне, збой, перазагрузка хаста — праца не закідваецца. Аднаўленне ходу прайграе перарваны ход, каб ён мог завяршыцца. Гэта бяспечна толькі таму, што пабочныя эфекты ідэмпатэнтныя: любая пошта ці адпраўка ў канал, якая ўжо адбылася да перазапуску, распазнаецца па ключы рэестра і прапускаецца, а часткі, якія не адбыліся, выконваюцца да канца. Карыстальнік бачыць адзіны цэласны адказ, а не недаробленую палову ці дублікат.
Неабавязковая шына NATS
Па змаўчанні дастаўка цалкам працуе праз PostgreSQL, што дазваляе ўтрымаць мінімальнае разгортванне на адным шлюзе плюс базе даных. Для большых ці шматшлюзавых канфігурацый вы можаце перавесці дастаўку на шыну NATS, наладзіўшы яе URL:
# gateway.env
AIHUMMER_NATS_URL=nats://127.0.0.1:4222
Шына сапраўды неабавязковая — пакіньце AIHUMMER_NATS_URL неўсталяваным, і outbox
працуе без яе. Калі яна прысутнічае, NATS становіцца транспартам, па якім цячэ
праца дастаўкі, што падыходзіць гарызантальна маштабаваным шлюзам за проксі.
[!TIP] Абнаўленні без прастою запускаюць два ці больш шлюзаў за зваротным проксі. Планіроўшчык застаецца адналідарным праз кансультатыўную блакіроўку Postgres, а ідэмпатэнтная дастаўка азначае, што дадатковыя шлюзы могуць дзяліць нагрузку, нічога не адпраўляючы двойчы.
За чым сачыць
Дастаўка — гэта месца, дзе праблемы надзейнасці выяўляюцца першымі, таму менавіта
за ёй варта назіраць. AiHummer перадае тэлеметрыю праз OTLP
(AIHUMMER_OTEL_ENDPOINT) і пастаўляе панэлі Grafana; няма канчатковай кропкі
Prometheus /metrics для апытання.
- Дыспазіцыі дастаўкі — вынік кожнай спробы дастаўкі. Узрастаючая частата адмоў паказвае на праблему канала ці ніжэйшага кампанента.
- Глыбіня outbox — колькі адказаў чакае дастаўкі. Устойлівы рост азначае, што дастаўка адстае.
- Глыбіня DLQ — запісы, якія вычарпалі свае паўторы і трапілі ў чаргу мёртвых лістоў. Любы рост DLQ заслугоўвае расследавання.
[!WARNING] Сачыце за гэтым разам з затрымкай ходу і частатой памылак. Узрастаючы outbox ці DLQ — гэта ранняе папярэджанне, што ніжэйшыя каналы дэградуюць, нават калі самі хады яшчэ паспяховыя.
Куды далей
- Ідэмпатэнтнасць, якая робіць дастаўку роўна-аднаразовай: Шматарэндарнасць і ідэмпатэнтнасць.
- Рухавік, які ў першую чаргу стварае адказ: Шлюз і рухавік ходу.