تضمین سازگاری داده ها با الگوی صندوق عقب تراکنش در AWS

مقدمه
در سیستم های توزیع شده ، تضمین سازگاری داده ها در سراسر خدمات بسیار مهم است. کی معاملات پایگاه داده و صف پیام اتمی نیستند ، شکست می تواند باعث ناسازگاری شود.
در الگوی صندوق عقب معامله تضمین کردن پایگاه داده می نویسد و انتشار پیام به صورت اتمی رخ می دهد، اجتناب از وقایع از دست رفته.
1. مشکل: بانک اطلاعاتی و پیام رسانی اتمی نیستند
یک سرویس سفارش را تصور کنید که:
داده های سفارش را به Amazon RDS (postgresql/mysql) می نویسد.
برای سایر خدمات (به عنوان مثال ، موجودی ، حمل و نقل) یک رویداد (سفارش) به آمازون SQS منتشر می کند.
🔥 سناریوی شکست:
این سرویس سفارش RDS را می نویسد
این سرویس نتوانسته است سفارش داده شده به SQS ❌ (خطای شبکه ، زمان بندی و غیره) را منتشر کند
💥 مشکل: سفارش در پایگاه داده ذخیره می شود ، اما سایر خدمات (موجودی ، حمل و نقل) هرگز این رویداد را دریافت نمی کنند.
🚨 ناسازگاری داده ها می توانند منجر به:
مشتریانی که بدون تحقق سفارش شارژ می شوند.
بدون به روزرسانی موجودی ، منجر به بیش از حد.
هیچ حمل و نقل ایجاد نشده و منجر به حمایت از تشدید می شود.
2. راه حل الگوی صندوق عقب معامله
🔹 مرحله 1: جدول صندوق عقب را تعریف کنید
CREATE TABLE order_outbox (
id SERIAL PRIMARY KEY,
order_id UUID NOT NULL,
event_type TEXT NOT NULL,
payload JSONB NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
processed_at TIMESTAMP NULL
);
🔹 مرحله 2: سفارش و رویداد را در یک معامله بنویسید (TypeScript)
import { Pool } from 'pg';
const pool = new Pool({ connectionString: "your-db-connection" });
async function placeOrder(orderId: string, customerId: string, totalPrice: number) {
const client = await pool.connect();
try {
await client.query('BEGIN');
await client.query("INSERT INTO orders (order_id, customer_id, total_price) VALUES ($1, $2, $3)",
[orderId, customerId, totalPrice]);
await client.query("INSERT INTO order_outbox (order_id, event_type, payload) VALUES ($1, $2, $3)",
[orderId, "OrderPlaced", JSON.stringify({ orderId, customerId, totalPrice })]);
await client.query('COMMIT');
} catch (error) {
await client.query('ROLLBACK');
throw error;
} finally {
client.release();
}
}
🔹 مرحله 3: نظرسنجی و انتشار رویدادها (AWS Lambda / ECS وظیفه)
import { Pool } from 'pg';
import { SNS } from 'aws-sdk';
const pool = new Pool({ connectionString: "your-db-connection" });
const sns = new SNS();
const topicArn = "arn:aws:sns:us-east-1:your-account-id:order-events";
async function processOutbox() {
const client = await pool.connect();
try {
const { rows } = await client.query("SELECT id, payload FROM order_outbox WHERE processed_at IS NULL");
for (const event of rows) {
try {
await sns.publish({ TopicArn: topicArn, Message: JSON.stringify(event.payload) }).promise();
await client.query("UPDATE order_outbox SET processed_at = NOW() WHERE id = $1", [event.id]);
} catch (error) {
console.error(`Failed to send event ${event.id}:`, error);
}
}
} catch (error) {
console.error("Error processing outbox:", error);
} finally {
client.release();
}
}
4. چرا ما فقط نمی توانیم با SNS معامله برگشتیم
sns و پایگاه داده ها معاملات را به اشتراک نمی گذارند
- پشتیبانی از پایگاه داده (RDS ، PostgreSQL ، MySQL) معاملات اسیدیبشر
- Amazon SNS یک سرویس خارجی است و نمی تواند بخشی از همان معامله باشد.
🔹 سناریوهای شکست بدون صندوق
- DB INSERT موفق می شود ، SNS شکست می خورد:
- سفارش در ذخیره می شود RDS ✅
- پیام SNS شکست می خورد
- خدمات دیگر هرگز این رویداد را دریافت نمی کنند!
- پیام SNS ارسال شده ، درج DB شکست می خورد:
- پیام SNS ارسال شده
- DB INSERT شکست می خورد
- خدمات دیگر رویدادی را برای نظم مشاهده می کنند که وجود ندارد!
🔹 در صورت عدم موفقیت باید چه اتفاقی بیفتد؟
- در صورت عدم موفقیت SNS: این رویداد در صندوق عقب باقی مانده و بعداً می توان آن را مجدداً مورد استفاده قرار داد.
- در صورت عدم موفقیت معاملات DB: هیچ چیز متعهد نیست ، و اطمینان از سازگاری دارد.
- مجدداً و صف های برگ برگ (DLQ): پیام های SNS ناموفق را می توان برای اشکال زدایی بیشتر به DLQ منتقل کرد.
5. موارد استفاده در دنیای واقعی
- پردازش سفارش تجارت الکترونیکی: تضمین سفارشات به طور قابل اعتماد به خدمات موجودی ، صورتحساب و حمل و نقل تبلیغ می شود.
- پردازش پرداخت: اطمینان از معاملات باعث ایجاد اعلان ها و گزارش های صحیح می شود.
- ثبت نام کاربر: تضمین ایمیل یا اعلان ها پس از ثبت نام جدید کاربر به طور قابل اعتماد ارسال می شود.
- رویدادهای دستگاه IoT: اطمینان از داده های تله متری از دستگاه ها به طور مداوم منتشر می شود.
6. تفاوت از الگوی حماسه
نشان | صندوق عقب معامله | الگوی حماسه |
---|---|---|
رویکرد | تضمین انتشار رویداد اتمی است | معاملات را به مراحل کوچکتر تقسیم می کند |
مورد استفاده | پیام های قابل اعتماد را تضمین می کند | فرایندهای کسب و کار چند مرحله ای را کنترل می کند |
پیچیدگی | ساده تر | پیچیده تر |
نمونه | انتشار رویداد قابل اعتماد به SNS | رزرو هتل و پرواز با مراحل برگشت |
پایان
در الگوی صندوق عقب معامله تضمین کردن قوام رویداد با انجام معاملات پایگاه داده و انتشار رویداد Atomic. اجرای آن با آمازون RDS ، SNS و Lambda/ECS فراهم می کند قابل اعتماد ، مقیاس پذیر و جدا شده راه حل.
🚀 آیا این الگوی را پیاده سازی کرده اید؟ تجربه خود را در نظرات به اشتراک بگذارید!
🔔 برای بینش بیشتر معماری AWS دنبال کنید!