Тапсырмалар кезегі және теңгерім
1) Міндеттер кезегінің қажеті
Тапсырмалар кезегі (job queue/work queue) өндірушілер мен орындаушыларды уақыт пен жылдамдық бойынша ажыратады:- Шыңдарды тегістейді: майдан мен ауыр кіші жүйелер арасындағы буфер.
- SLA тұрақтандырады: жүктеме сыныптарының басымдықтары мен оқшаулануы.
- Істен шығуға төзімділікті жеңілдетеді: ретра, DLQ, қайта қою.
- Көлденең масштабтау: Воркерлерді API алмастырусыз қосыңыз.
Типтік домендер: төлемдерді өңдеу, нотификациялар, есептерді/медианы генерациялау, ETL/ML-постпроцессинг, сыртқы API-мен интеграциялау.
2) Модель және негізгі ұғымдар
Продюсер: тапсырманы жариялайды (payload + метадеректер: idempotency key, басымдық, мерзім).
Кезек/топик: тапсырмалар буфері/журналы.
Воркер: тапсырманы алады, өңдейді, растайды (ack) немесе қатемен қайтарады.
Visibility Timeout/Lease: өңдеу уақытында міндеттерді «жалға алу», одан кейін - авто-қайта жеткізу.
DLQ (Dead Letter Queue): әрекеттер/қателер шегінен кейін тапсырмаларды «көму».
Rate Limit/Concurrency: per-воркер/per-кезек/per-тенант тұтынуға шектеулер.
- Pull: воркердің өзі тапсырманы сұратады (жүктемені мөлшерлейді).
- Push: брокер пушит; әлсіз воркерлерді «құюдан» қорғау қажет.
3) Жеткізу семантикасы және растаулар
At-most-once: ретрассыз; тез, бірақ жоғалуы мүмкін.
At-least-once (көптеген кезектер үшін дефолт): дубликаттар болуы мүмкін → өңдеушінің ұқсастығы талап етіледі.
Effectively exactly-once: қосымша деңгейінде қол жеткізіледі (идемпотенттілік, дедуп-стор, транзакциялар/аутбокс). Брокер көмектесе алады, бірақ «сиқырлы оқ» емес.
- Ack/Nack: айқын нәтиже.
- Requeue/Retry: с backoff + jitter.
- Poison message: DLQ қызметіне жіберу.
4) Теңгерімдеу және жоспарлау
4. 1 Кезектілік және алгоритмдер
FIFO: қарапайым және болжамды.
Priority Queue: басым сыныптар (P0... P3).
WRR/WSR (Weighted Round-Robin/Random): сыныптар арасындағы CPU/perezput үлестері.
WFQ/DRR (желілердегі «әділ» кезектердің аналогы): per-тенант/клиент үлестері.
Deadline/EDF: мерзімі өткен тапсырмалар үшін.
Fair Share: «шулы көршілерді» шектеу (per-tenant quotas).
4. 2 Өңдеу ағындары
Single-flight/Coalescing: тапсырманың қайталануын біріктіріңіз.
Concurrency caps: тапсырмалар/интеграциялар түрлері бойынша параллелизмге қатаң лимиттер (сыртқы API).
4. 3 Гео және шардалау
Кілт бойынша шарлар (tenant/id) → деректердің орналасуы, шардалар шегінде тұрақты тәртіп.
Sticky кэшіне/ресурстарына: «бекітілген» күйі бар воркерлерге хэш-роутинг.
5) Ретраи, backoff және DLQ
Экспоненциалды backoff + jitter: 'base 2 ^ attempt ± random'.
Максималды әрекет және тапсырманың жалпы мерзімі (time-to-die).
Қателердің жіктелуі: 'retryable' (желі/лимит), 'non-retryable' (валидация/бизнес-тыйым салу).
Parking/Delay Queue: кейінге қалдырылған тапсырмалар (мысалы, 15 минуттан кейін қайталау).
DLQ-саясат: «улы» хабарламаның қайда және қандай жағдайда түсетінін міндетті түрде көрсетіңіз; reprocessor.
6) Ұқсастық және дедупликация
Idempotency-Key тапсырмасында; Соңғы N кілттер үшін TTL бар стор (Redis/DB):- seen → skip/merge/result-cache.
- Natural keys: кездейсоқ UUID орнына 'order _ id/ payment_id'' пайдаланыңыз.
- Outbox: бизнес-операциямен бір БД-транзакцияда міндет фактісін және оның мәртебесін жазу.
- Синктегі Exactly-once: 'UPSERT' кілті бойынша, нұсқаларын тексеру, кезектегі «at-least-once» + ДБ-дағы іспеттілік.
7) Мульти-тенанттылық және SLA сыныптары
Келесі сыныптарға бөліңіз: 'critical', 'standard', 'bulk'.
per-тенант квоталары мен басымдықтары (Gold/Silver/Bronze).
Оқшаулау: P0-ден төмен воркерлердің dedicate-пулдары; фондық - жеке кластерде.
Admission control: мерзімі ұзартылғаннан артық қабылдамаңыз.
8) Воркерлердің автоскейлингі
Скейлингке арналған өлшемдер: queue depth, arrival rate, processing time, SLA-мерзім.
KEDA/Horizontal Pod Autoscaler: тереңдігі бойынша триггерлер SQS/Rabbit/Kafka lag.
Тежеуші факторлар: сыртқы API rate limits, дерекқор (бэкэндті бұзбаңыз).
9) Технологиялық нұсқалар мен паттерндер
9. 1 RabbitMQ/AMQP
Exchanges: direct/topic/fanout; Queues с ack/ttl/DLQ (dead-letter exchange).
Prefetch (QoS) «воркердегі қанша тапсырманы» реттейді.
ini x-dead-letter-exchange=dlx x-dead-letter-routing-key=jobs.failed x-message-ttl=60000
9. 2 SQS (және аналогтар)
Visibility Timeout, DelaySeconds, RedrivePolicy (DLQ).
Теңсіздік - қосымшада (дедуп-кесте).
Лимиттер: 1-10 хабарлама батшы; демпотенттік синкаларға бағдарланыңыз.
9. 3 Kafka/NATS JetStream
Масштабты пайплайндар үшін: жоғары өткізу, ретеншн/реплтер.
Таск-кезек: бір тапсырма = бір хабарлама; Партиялану/subject арқылы «кілтке бір воркерді» бақылау.
Ретраилер: backoff бар жеке топиктер/subject-суффикстер.
9. 4 Redis-кезек (Sidekiq/Resque/Bull/Celery-Redis)
Өте төмен жасырындылық; тұрақтылықты (RDB/AOF), retry кілттерін және single-flight үшін lock-keys бақылаңыз.
Ұзақ мерзімді ретеншн үшін емес, «жеңіл» міндеттер үшін жарамды.
9. 5 Фреймворк
Celery (Python), Sidekiq (Ruby), RQ/BullMQ (Node), Huey/Resque - дайын ретрациялар, кестелер, middleware, метриктер.
10) Маршруттау және теңгерімдеу схемалары
Round-Robin: біркелкі, бірақ тапсырмалардың «ауырлығын» ескермейді.
Weighted RR: воркер/пулдың қуаты бойынша бөлу.
Fair/Backpressure-aware: Воркер жаңа тапсырманы тек дайын болғанда алады.
Priority lanes: сыныпқа жеке кезектер; воркерлер [P0 →... → Pn] тәртібінде оқиды.
Hash-routing: 'hash (key)% shards' - stateful/кэшталатын өңдеу үшін.
11) Таймауттар, мерзімдер және SLA
Per-task timeout: ішкі «жалдау» жұмысы (воркер кодында) ≤ Visibility Timeout брокері.
Global deadline: T уақыттан кейін тапсырманың мәні жоқ - NACK → DLQ.
Budget-aware: мерзім жақындағанда (brownout) жұмысты қысқартыңыз (ішінара нәтижелер).
12) Бақылау және басқару
12. 1 Өлшемдері
`queue_depth`, `arrival_rate`, `service_rate`, `lag` (Kafka), `invisible_messages` (SQS).
`success/failed/retired_total`, `retry_attempts`, `dlq_in_total`, `processing_time_ms{p50,p95,p99}`.
`idempotency_hit_rate`, `dedup_drops_total`, `poison_total`.
12. 2 Логи/трейсинг
Корреляция: 'job _ id', 'correlation _ id', дедупликация кілті.
'retry/backoff/dlq' оқиғасы ретінде белгілеңіз; бастапқы сұраудың span-дан сызу.
12. 3 Дашборд/Алерт
Триггерлер: тереңдігі> X, p99> SLO, DLQ биіктігі, «жабысқақ» тапсырмалар (visibility> N), «ыстық» кілттер.
13) Қауіпсіздік және сәйкестік
Жалға алушыларды оқшаулау: жеке кезектер/кілт-кеңістік, ACL, квоталар.
Көлікте және/немесе «тыныштықта» шифрлау.
PII-payload-да ең аз; шикі PII орнына хэш/ID.
Құпиялар: тапсырмалар денесіне токендер қоймаңыз, vault/refs пайдаланыңыз.
14) Қарсы үлгілер
Идемпотенттілігі жоқ ретрайлер → операция дублдері/ақша «екі рет».
Бір үлкен кезек «барлығына» → оқшаулау жоқ, күтпеген кідірістер.
DLQ жоқ шексіз ретрайлер → мәңгілік «улы» тапсырмалар.
Visibility Timeout <өңдеу уақыты → каскадты қайталаулар.
Кезектегі үлкен payload → желіні/жады қысады; объектілік есікте сақтаған және сілтемені берген дұрыс.
Backpressure → воркерлері жоқ пуш-модель тұнады.
Бір воркер пулында сыни және bulk тапсырмаларын араластыру.
15) Енгізу чек-парағы
- Тапсырмаларды SLA (P0/P1/P2) және көлемі бойынша жіктеңіз.
- Қажетті семантикасы мен ретеншні бар брокерді/фреймворкті таңдаңыз.
- Кілттерді, басымдықтарды және маршрутизацияны (hash/shards/priority lanes) жобалаңыз.
- backoff + jitter және DLQ саясаты бар ретраларды қосыңыз.
- Үйлесімділікті жүзеге асырыңыз (кілттер, upsert, TTL-мен дедуп-стор).
- Таймауттарды теңшеңіз: per-task, visibility, ортақ мерзім.
- Интеграциялар/тенанттар бойынша concurrency және rate шектеңіз.
- Сақтандырғышы бар тереңдігі/лагы бойынша автоскейлинг.
- Метриктер/трейсинг/алерталар; runbooks «дауыл» және DLQ толуы.
- Фейл тестілері: воркердің құлауы, «улы» хабарлама, артық жүктеме, ұзақ тапсырмалар.
16) Конфигурация және код мысалдары
16. 1 Celery (Redis/Rabbit) - базалық флоу
python app = Celery("jobs", broker="amqp://...", backend="redis://...")
app.conf.task_acks_late = True # ack после выполнения app.conf.broker_transport_options = {"visibility_timeout": 3600}
app.conf.task_default_retry_delay = 5 app.conf.task_time_limit = 300 # hard timeout
@app.task(bind=True, autoretry_for=(Exception,), retry_backoff=True, retry_jitter=True, max_retries=6)
def process_order(self, order_id):
if seen(order_id): return "ok" # идемпотентность do_work(order_id)
mark_seen(order_id)
return "ok"
16. 2 RabbitMQ — DLQ/TTL
ini x-dead-letter-exchange=dlx x-dead-letter-routing-key=jobs.dlq x-message-ttl=600000 # 10 минут x-max-priority=10
16. 3 Kafka - деңгейлер бойынша ретра
orders -> orders.retry.5s -> orders.retry.1m -> orders.dlq
(scheduler/cron-consumer арқылы кейінге қалдырыңыз.)
16. 4 NATS JetStream — consumer с backoff
bash nats consumer add JOBS WORKERS --filter "jobs.email" \
--deliver pull --ack explicit --max-deliver 6 \
--backoff "1s,5s,30s,2m,5m"
17) FAQ
Q: pull қарсы push таңдау қашан?
A: Pull табиғи backpressure және «адал» теңгерім береді; push төмен жылдамдықта және ең аз TTFB қажет болғанда оңай, бірақ шектеуіштерді талап етеді.
Q: «Ыстық» кілтті қалай болдырмау керек?
A: Құрамдас кілт бойынша шардалаңыз ('order _ id% N'), буферлеңіз және batch-өңдеу жасаңыз, per-кілт лимиттерін енгізіңіз.
Q: «exactly-once» болуы мүмкін бе?
А: Іс жүзінде - идемпотенттілік және транзакциялық аутбокс арқылы. Толық «математикалық» exactly-once бүкіл жолда сирек қол жетімді және қымбат.
Q: Үлкен тапсырмаларды қайда сақтау керек?
А: Объектілік қоймада (S3/GCS), ал тапсырмада - сілтеме/ID; брокер мен желіге қысымды төмендетеді.
Q: TTL/visibility қалай таңдауға болады?
A: Visibility ≥ p99 өңдеу уақыты × қор 2-3 ×. TTL тапсырмалары - бизнес-мерзімнен аз.
18) Қорытынды
Кезектердің күшті жүйесі - бұл жеткізу семантикасы, басымдықтар мен шектеулер арасындағы теңгерім. Кілттер мен маршрутизацияны жобалаңыз, теңсіздікті, backoff және DLQ ретрациясын қамтамасыз етіңіз, ресурстарды SLA кластары бойынша бөліңіз және метрикаларды қадағалаңыз. Сонда сіздің фондық процестеріңіз болжанатын, тұрақты және масштабталатын болады - шыңдардың астында тосын сыйсыз.