Ανταλλαγή μηνυμάτων
Η ανταλλαγή μηνυμάτων είναι ένα σύνολο αρχιτεκτονικών τεχνικών που εξασφαλίζουν τη συνέπεια μεταξύ των αλλαγών του τοπικού κράτους (βάση δεδομένων/κρυφή μνήμη) και των μηνυμάτων στον μεσίτη/λεωφορείο. Σκοπός: «η κατάσταση είναι σταθερή ↔ το μήνυμα δεν χάνεται ή δεν επαναλαμβάνεται» σε περίπτωση αστοχιών, επαναδρομολογήσεων, κλιμάκωσης και πολλαπλής μίσθωσης.
1) Σημασιολογία παράδοσης
Το πολύ μία φορά: Γρήγορες και φθηνές, πιθανές απώλειες, όχι λήψεις.
Τουλάχιστον μία φορά: δεν χάνει μηνύματα, τα αντίγραφα είναι δυνατά → απαιτείται ιδεατότητα.
(Πραγματική) Ακριβώς μία φορά: καμία απώλεια και καμία ορατή λήψη για επιχειρηματικά αποτελέσματα, που επιτυγχάνεται με συνδυασμό τεχνικών (outbox/inbox, συναλλαγές παραγωγού/καταναλωτή, dedup).
2) Γιατί το «δύο γράμματα» είναι επικίνδυνο
Αφελής λογική «πρώτα γράψτε στη βάση δεδομένων, στη συνέχεια στείλτε στο λεωφορείο» (ή αντίστροφα) διαλείμματα όταν πέφτουν μεταξύ βημάτων: τα δεδομένα είναι σταθερά, και το γεγονός χάνεται? είτε το γεγονός έχει εξαφανιστεί, αλλά δεν υπάρχουν δεδομένα. Η ανταλλαγή μηνυμάτων γεφυρώνει αυτό το κενό.
3) Βασικά πρότυπα
3. 1 Outbox (κατασκευαστής)
Σε μια τοπική συναλλαγή, γράφουμε την επιχειρηματική αλλαγή και τη σειρά στον πίνακα 'outbox'? ένας ξεχωριστός εκδότης διαβάζει outbox και δημοσιεύει σε μεσίτη με retras και backoff. Εξαιρούνται οι ζημίες. τα διπλά σβήνονται από την ευφυΐα μεταξύ των καταναλωτών.
3. 2 Inbox/Idempotent Καταναλωτής
Πριν από την εκτέλεση του αποτελέσματος, ο καταναλωτής καθιστά το «INSERT» στα «εισερχόμενα (καταναλωτής, event_id)» ως το κύριο κλειδί. Βασική σύγκρουση = γεγονός που έχει ήδη υποστεί επεξεργασία → παραλείψτε. Αυτός είναι ο τρόπος με τον οποίο επιτυγχάνεται «ακριβώς μία φορά».
3. 3 Ανάγνωση-διεργασία-εγγραφή με συναλλαγή αντιστάθμισης
Πρότυπο για λεωφορεία προσανατολισμένα στο ημερολόγιο: ο καταναλωτής διαβάζει την παρτίδα, στην ίδια συναλλαγή καταγράφει την επιχειρηματική αλλαγή και την "επιτυχημένη αντιστάθμιση. "Μετά τη δέσμευση, ο μεσίτης εξετάζει τα μηνύματα που καταναλώνονται. Αυτό εξαλείφει το «διάβασμα → πτώση → επανάληψη» χωρίς αντίγραφα του αποτελέσματος.
3. 4 TSS/Sagas για διυπηρεσιακές επιδράσεις
Όταν χρειάζεστε μια συνεπή διαδικασία πολλαπλών σταδίων, χρησιμοποιήστε TCC ή sagas. μηνύματα - μεταφορά εντολών/γεγονότων και συναλλαγή - σε επίπεδο βαθμίδων και αποζημιώσεων.
4) Ευέλικτοι παραγωγοί και καταναλωτές
Παραγωγός: το σταθερό 'μήνυμα _ id '/' idempotency _ key', η επανάληψη με το ίδιο κλειδί δεν δημιουργεί νέα αποτελέσματα για τους συνδρομητές. διατήρηση της αλληλουχίας ανά κλειδί.
Καταναλωτής: 'inbox' + business idempotency (upsert/merge, check latest version/review).
5) Τάξη και αιτιώδης συνάφεια
Συμμετοχή με επιχειρηματικό κλειδί (για παράδειγμα, «σύνολο _ id», «ενοικιαστής _ id») έτσι ώστε τα γεγονότα ενός αντικειμένου να φτάνουν σε τάξη.
να διατηρούν διαδοχικούς αριθμούς/χρονοσφραγίδες εντός της παρτίδας· κατά τον επανασχεδιασμό από το DLQ, παρατηρούν «ανά κλειδί και διαδοχικά».
Εάν η παγκόσμια τάξη δεν είναι κρίσιμη, εξασφαλίστε την τοπική τάξη ανά κλειδί και καθορίστε τις αναλλοίωτες περιοχές.
6) Αντισταθμίσεις και αποτελέσματα καθορισμού
Επιλογή Α: «Αντιστάθμιση σε DB»
Γράψτε το «τελευταίο επεξεργασμένο όφσετ (κατάτμηση, όφσετ)» στην ίδια συναλλαγή όπου αλλάζετε δεδομένα τομέα. Κατά την επανεκκίνηση, συνεχίστε από την επόμενη όφσετ, αποφεύγοντας επαναλαμβανόμενο αποτέλεσμα.
Επιλογή B: Συναλλαγή μεσίτη
Ορισμένοι μεσίτες υποστηρίζουν την ατομική καταγραφή μηνυμάτων και αντισταθμίσεων σε μία συναλλαγή παραγωγού/καταναλωτή. Χρήση, εφόσον είναι διαθέσιμη, αλλά πάντα συμπληρώνεται με ιδεατότητα για τον καταναλωτή.
7) Retrai, backoff, DLQ
Επαναλάβετε μόνο ανασυρόμενα σφάλματα (timeouts, 5xx), με εκθετική οπισθοδρόμηση και νευρικότητα.
Μη ανακτήσιμο (σχήμα/επικύρωση) - αμέσως σε DLQ με μεταδεδομένα (ενοικιαστής, κλειδί, όφσετ, λόγος).
Δώστε την ανασύσταση από το DLQ (παρτίδα, όριο ταχύτητας), ελέγξτε το κύκλωμα πριν επαναλάβετε, παρατηρήστε τη σειρά ανά κλειδί.
8) Πολυπλοκότητα και περιφέρειες
Ενσωμάτωση 'ενοικιαστής _ id', 'σχέδιο', 'περιοχή' σε μεταδεδομένα μηνυμάτων και κλειδιά κατάτμησης.
Ανά μισθωτή δίκαιη μεταχείριση: Περιορισμός της δημοσίευσης/επεξεργασίας έτσι ώστε ο «θορυβώδης» πελάτης να μην αφαιρεί τον προϋπολογισμό από τα υπόλοιπα.
Κατοικία: αποθήκευση μηνυμάτων και outbox στην ίδια περιοχή με τα δεδομένα τομέα. διαπεριφερειακές αναπαραστάσεις - ασύγχρονα μεγέθη.
9) Παρατηρησιμότητα και λογιστικός έλεγχος
Ανίχνευση: συσχέτιση 'event _ i /' cregate _ i /' saga _ id', χρονικά διαστήματα «read process write/commit».
Μετρήσεις: υστέρηση έκδοσης/επεξεργασίας (p95/p99), ποσοστό επιτυχίας, ρυθμός DLQ, redrive επιτυχία, «διπλά καταπιεσμένα».
Αρχεία καταγραφής: σύντομη για επιτυχία· λεπτομέρειες σχετικά με τα σφάλματα (λόγος, απόπειρα, κλειδί, αντιστάθμιση).
Έλεγχος: ποιος επανασχεδιάστηκε/γύρισε πίσω, ποια παρτίδα και με ποιο αποτέλεσμα.
10) Ασφάλεια και συμμόρφωση
Ελαχιστοποίηση του PII σε ωφέλιμο φορτίο. Μάσκα κατά τη μεταφορά σε DLQ/logs.
Υπογραφή/κρυπτογράφηση μηνυμάτων για εξωτερικά λεωφορεία. χρήση mTLS μεταξύ υπηρεσιών.
Διαχείριση της διάρκειας ζωής και του «δικαιώματος να ξεχνάτε» ανά ενοικιαστή/περιφέρεια.
11) Τυπικά συστήματα ένταξης
1. Πηγή υπηρεσιών (εγγραφή)
Τοπική συναλλαγή: domain record + outbox.
Εκδότης: παρτίδες, «SKIP LOCKED», backoff, όρια ανά ενοικιαστή.
Παρακολούθηση lag 'now − occurred_at'.
2. Υπηρεσία-καταναλωτής (από την πλευρά της ανάγνωσης)
Διαβάζοντας την παρτίδα → προσπαθώντας να 'ΕΙΣΆΓΟΥΜΕ εισερχόμενα (καταναλωτής, event_id)' → αν πετύχουμε, εκτελούμε το αποτέλεσμα.
Στην ίδια συναλλαγή, καθορίζουμε το «passed offset» (επιλογή Α) ή βασιζόμαστε στη συναλλαγή του μεσίτη (επιλογή Β).
Σχετικά με το σφάλμα: επανακαταμέτρηση ή DLQ ανά πολιτική.
3. Προβολή/Υλοποιημένη προβολή
Μόνο idempotent ενημερώσεις (upsert), συμπαγή κλειδιά αφαίρεσης, περιοδική επαλήθευση ελέγχου.
12) Υποδείγματα διαμόρφωσης (παράδειγμα)
yaml producer:
idempotency_key: event_id partition_key: "{tenant_id}:{aggregate_id}"
retry:
max_attempts: 8 initial_ms: 200 max_ms: 8000 strategy: exponential_full_jitter
consumer:
batch: 500 offset_commit: "with_domain_tx" # или "broker_tx"
inbox_enabled: true concurrency_per_partition: 4 dlq:
enabled: true batch_redrive: 200 rate_limit_per_sec: 50 order_by_key: true
observability:
metrics:
- processing_lag_ms
- publish_success_ratio
- dlq_rate
- redrive_success_ratio tracing_tags: [event_id, tenant_id, aggregate_id, partition, offset]
13) Κατάλογος επιλογών πριν από την πώληση
- Εξάλειψη των «δύο γραμμάτων»: προεξοχή του παραγωγού ή καθορισμός της αντιστάθμισης και του αποτελέσματος μιας συναλλαγής στον καταναλωτή.
- Idempotent καταναλωτής: 'inbox '/dedup journal, business idempotence of operations.
- Ακολουθείται ο διαχωρισμός ανά επιχειρηματικό κλειδί, τοπική τάξη.
- Backoff + jitter retraces, ταξινόμηση σφαλμάτων, πλούσια σε μεταδεδομένα DLQ.
- Redrave δόση, ασφαλής? υπάρχουν βιβλία αναπαραγωγής.
- Όρια και προτεραιότητες πολυκατοικιών· 'tenant _ id/plan/region' tags.
- Τηλεμετρία: υστερήσεις, ποσοστό επιτυχίας, «αντίγραφα καταπιεσμένα», ειδοποιήσεις από το p95/p99.
- Εφαρμόζονται πολιτικές PII/διατήρησης/κρυπτογράφησης.
- Δοκιμές: πτώση μεταξύ βημάτων, αντιγράφων, σειρά κλειδιών, επανασχεδιασμός μάζας.
14) Τυπικά σφάλματα
Αποστολή στο λεωφορείο και εγγραφή στη βάση δεδομένων σε ξεχωριστά βήματα χωρίς συναλλαγή outbox/offset.
Ένας καταναλωτής χωρίς ιδιοτέλεια → επαναλαμβάνει τις παρενέργειες.
Η παγκόσμια τάξη «έλα ό, τι μπορεί» είναι δαπανηρή και σπάνια δικαιολογημένη. επαρκής τάξη ανά κλειδί.
Μαζική ανατροπή χωρίς όρια → δευτερεύον συμβάν.
Έλλειψη μετρήσεων ανίχνευσης/υστέρησης → «κρυμμένη υποβάθμιση».
Ανάμειξη PII σε DLQ/logs.
15) Γρήγορες συνταγές
SaaS events: Outbox + idempotent consumer (inbox), κατάτμηση ανά «ενοικιαστή _ id: σύνολο _ id».
ETL/προβολές: Ανάγνωση-διεργασία-γραφή με καθορισμό αντισταθμίσεων σε μία συναλλαγή, παρτίδες 500-1000, upsert.
Υψηλό φορτίο: εκδοτικές εκδόσεις, «SKIP LOCKED», WFQ ανά ενοικιαστή, lag control.
Αυστηρή ζώνη συμμόρφωσης: περιφερειακή εξωτερική θυρίδα, κρυπτογράφηση ωφέλιμου φορτίου, διατήρηση και έλεγχος των redrives.
Συμπέρασμα
Η ανταλλαγή μηνυμάτων είναι η πειθαρχία της σύνδεσης δεδομένων και μηνυμάτων. Συνδυάζοντας outbox/inbox, idempotency, αντισταθμίζει τη σταθεροποίηση μαζί με εφέ και διαχειριζόμενα retrays με DLQ, παίρνεις πρακτική συμπεριφορά ακριβώς μία φορά χωρίς παγκόσμιες κλειδαριές και διατηρείς SLO ακόμα και με συντριβές, κορυφές και πολύπλοκη εκμετάλλευση πολλαπλών ενοικιαστών.