رفتن به محتوا
IROSG.
مقاله‌ها

NATS JetStream؛ پیام ماندگار چگونه به مصرف‌کننده می‌رسد؟

Stream، Consumer و تأیید دریافت را جدا کنیم؛ ماندگاری پیام به معنی اجرای دقیقاً یک‌باره هر اثر تجاری نیست.

نمودار منبع: NATS JetStream؛ پیام ماندگار چگونه به مصرف‌کننده می‌رسد؟

چه چیزی به Core NATS اضافه می‌شود؟

Core NATS برای دریافت پیام به مشترک متصل در زمان انتشار تکیه دارد. JetStream لایه ماندگاری و بازپخش پیام را اضافه می‌کند تا ناشر و مصرف‌کننده لازم نباشد هم‌زمان حاضر باشند. این تفاوت برای کارهایی که باید بعد از توقف موقت پردازش ادامه یابند مهم است.

Stream پیام‌های subjectهای انتخاب‌شده را نگه می‌دارد. Consumer نمای وضعیت‌دار خواندن از آن جریان است و پیشرفت دریافت را دنبال می‌کند. برنامه کلاینت پیام را می‌گیرد و طبق قرارداد، دریافت یا پردازش آن را تأیید می‌کند. چند Consumer می‌توانند از یک Stream مستقل بخوانند.

چرا احتمال تکرار را باید جدی گرفت؟

در الگوی تحویل حداقل یک‌باره، نرسیدن تأیید در زمان مناسب می‌تواند باعث تحویل دوباره شود. ممکن است برنامه کار را انجام داده، اما پیش از ارسال تأیید قطع شده باشد. بنابراین تحویل دوباره الزاماً به معنی دوبار منتشرشدن پیام توسط ناشر نیست.

تمرین پیشنهادی تحریریه

برای یک سامانه فرضی سفارش، برای هر رویداد شناسه یکتا تعیین کنید. ابتدا پیام را دریافت کنید، ثبت نتیجه را انجام دهید و سپس تأیید بفرستید. حالا در محیط آزمایشی، برنامه را میان این دو مرحله متوقف کنید. پس از شروع دوباره، بررسی کنید آیا دریافت مجدد همان شناسه باعث ایجاد سفارش تکراری می‌شود یا خیر.

در مرحله بعد، دو گروه مصرف‌کننده مستقل بسازید: یکی برای پردازش سفارش و دیگری برای گزارش. نیازهای نگه‌داری آن‌ها را جدا بنویسید؛ حذف پیام پس از انجام یک کار نباید ناخواسته امکان گزارش یا بازپخش موردنیاز گروه دیگر را از بین ببرد.

تصمیم‌های قبل از انتشار

پیشنهاد ما روشن‌کردن مدت نگه‌داری، سقف ظرفیت، سیاست برخورد با پیام ناموفق و مسئول رسیدگی به عقب‌ماندگی است. داشتن Stream ماندگار به‌تنهایی تضمین نمی‌کند هر اثر تجاری دقیقاً یک‌بار اجرا شود. این تضمین به طراحی برنامه، شناسه‌ها، ذخیره نتیجه و آزمون سناریوهای قطع ارتباط وابسته است.

طراحی رویداد پیش از انتخاب گزینه‌های جریان

یک پیام خوب باید بدون وابستگی به حافظه موقت ناشر قابل فهم باشد. برای رویداد سفارش، شناسه رویداد، شناسه سفارش، نوع رخداد و نسخه قالب را تعریف کنید. زمان رخداد با زمان دریافت پیام فرق دارد و هر دو می‌توانند در بررسی تأخیر مفید باشند. از قرار دادن همه اطلاعات مشتری در هر پیام خودداری کنید؛ مصرف‌کننده باید داده لازم برای کار خودش را دریافت کند. کوچک بودن پیام فقط مسئله سرعت نیست، بلکه دامنه انتشار داده حساس و هزینه نگهداری را نیز کاهش می‌دهد.

نام subject را بر اساس نیاز مسیریابی طراحی کنید. اگر بخش‌های نام به ترتیب حوزه، نوع موجودیت و رخداد باشند، فهم مشترک میان تیم‌ها آسان‌تر می‌شود. با این حال افزودن شناسه‌های بسیار متنوع به نام‌ها باید با الگوی اشتراک و مدیریت مجوز سازگار باشد. قبل از تثبیت طرح، چند نمونه واقعی از پیام‌های موفق، ناموفق و اصلاحی بنویسید. مشخص کنید مصرف‌کننده به کدام گروه از رخدادها نیاز دارد و آیا این نیاز با نام subject قابل بیان است یا باید محتوا را نیز بررسی کند.

تأیید انتشار با تأیید پردازش فرق دارد

ناشر می‌خواهد بداند پیام به لایه ماندگار پذیرفته شده است؛ مصرف‌کننده می‌خواهد اعلام کند کار خود را تا نقطه مشخصی انجام داده است. این دو تأیید در دو سمت متفاوت جریان قرار دارند. اگر ناشر پاسخ انتشار را نگیرد، ممکن است نداند پیام ذخیره شده یا نه. تکرار انتشار بدون شناسه مناسب می‌تواند پیام تکراری ایجاد کند. اگر مصرف‌کننده پیش از ثبت نتیجه تأیید بفرستد و سپس از کار بیفتد، سامانه پیام ممکن است کار را انجام‌شده تلقی کند در حالی که اثر تجاری کامل نشده است.

برای تمرین، مصرف‌کننده‌ای بسازید که نتیجه را در یک جدول کوچک با کلید یکتای شناسه رویداد ثبت می‌کند. وقتی همان شناسه دوباره رسید، برنامه باید نتیجه قبلی را تشخیص دهد و اثر را تکرار نکند. این الگو را با عملیات ساده مانند افزایش اعتبار مقایسه کنید؛ افزایش دوباره عدد بدون کنترل شناسه می‌تواند خطای مالی بسازد. حتی اگر سامانه پیام امکانات حذف انتشار تکراری داشته باشد، مرز پایگاه داده برنامه و سامانه پیام همچنان نیازمند طراحی است. هیچ گزینه واحدی همه اثرهای بیرونی را خودکار اتمی نمی‌کند.

انتخاب مدل مصرف متناسب با بار

در مدل دریافت کششی، برنامه می‌تواند سرعت درخواست پیام را با ظرفیت پردازش خود هماهنگ کند. این ویژگی برای کاری که زمان اجرای متغیر دارد مفید است، اما باید تعداد پیام‌های در حال پردازش و زمان انتظار را کنترل کنید. درخواست دسته‌های بزرگ بدون حافظه کافی، فقط صف را از سرور به برنامه منتقل می‌کند. برای شروع، تعداد کمی پیام بگیرید، زمان پردازش را اندازه بگیرید و سپس اندازه دسته را با مشاهده رفتار افزایش دهید. عدد مناسب برای کار محاسباتی با ارسال ایمیل یا نوشتن فایل یکسان نیست.

اگر چند نمونه از یک برنامه یک مصرف‌کننده کاری را شریک می‌شوند، هدف تقسیم کار است. اگر دو تیم به تاریخچه مستقل نیاز دارند، معمولاً باید وضعیت مصرف مستقل داشته باشند. اشتراک اشتباهی یک وضعیت مصرف می‌تواند باعث شود گزارش‌ساز فقط بخشی از پیام‌هایی را ببیند که پردازشگر سفارش گرفته است. قبل از استقرار، بنویسید کدام نمونه‌ها یک کار منطقی مشترک انجام می‌دهند و کدام‌ها باید هر رویداد را مستقل دریافت کنند. این تصمیم از تعداد فرایندها مهم‌تر است.

زمان انتظار، تلاش دوباره و پیام مسئله‌دار

زمان انتظار تأیید باید با زمان واقعی انجام کار هماهنگ باشد. مقدار بسیار کوتاه می‌تواند پیام را در حالی دوباره تحویل دهد که پردازش اول هنوز ادامه دارد. مقدار بسیار بلند نیز تشخیص مصرف‌کننده ازکارافتاده را عقب می‌اندازد. زمان‌های معمول و کندترین حالت قابل انتظار را اندازه بگیرید و برای کارهای طولانی، سازوکار مناسب تمدید یا اعلام پیشرفت را مطابق کلاینت مورد استفاده بررسی کنید. در آزمایش، یک پیام عمداً کند ایجاد کنید تا رفتار دوباره‌تحویل را ببینید.

پیامی که به دلیل قالب نامعتبر همیشه شکست می‌خورد نباید بی‌پایان ظرفیت کارهای سالم را اشغال کند. برای این حالت، تعداد تلاش، تأخیر میان تلاش‌ها و مسیر رسیدگی انسانی یا خودکار را تعریف کنید. اصطلاح صف مرده به تنهایی طرح عملیاتی نیست؛ باید معلوم باشد پیام ناموفق کجا نگهداری می‌شود، چه اطلاعاتی همراه آن است و چه کسی اجازه بازپخش دارد. هنگام بازپخش نیز شناسه اصلی و علت اصلاح را حفظ کنید تا رویداد جدید با تکرار تصادفی اشتباه نشود.

نگهداری داده و عقب‌ماندگی مصرف‌کننده

مدت نگهداری را از نیاز کسب‌وکار استخراج کنید. اگر گزارش ماهانه به بازخوانی داده یک ماه نیاز دارد، نگهداری کوتاه‌تر می‌تواند حتی با مصرف‌کننده سالم گزارش را غیرممکن کند. از طرف دیگر، نگهداری بی‌حد هزینه و دامنه داده حساس را افزایش می‌دهد. محدودیت سن، حجم و تعداد پیام را با هم بررسی کنید و بدانید در برخورد با سقف ظرفیت چه رفتاری انتخاب شده است. موفق بودن انتشار امروز تضمین نمی‌کند پیام تا هر زمان دلخواه باقی بماند.

عقب‌ماندگی را تنها با تعداد پیام نسنجید. صد پیام با پردازش چنددقیقه‌ای ممکن است مهم‌تر از هزار پیام بسیار سبک باشد. سن قدیمی‌ترین کار، نرخ ورود، نرخ تکمیل و تعداد تلاش مجدد تصویر بهتری می‌دهند. اگر نرخ ورود برای مدت طولانی از ظرفیت پردازش بیشتر است، افزودن مصرف‌کننده فقط وقتی کمک می‌کند که گلوگاه قابل موازی‌سازی باشد. پایگاه داده مشترک یا محدودیت سرویس بیرونی ممکن است ظرفیت نهایی را تعیین کند و افزایش هم‌زمانی تنها خطا را بیشتر کند.

آزمایش توقف و بازیابی با داده ساختگی

آزمایش را با مجموعه‌ای محدود و قابل شمارش از رویدادها انجام دهید. شناسه همه رویدادهای منتشرشده را در یک فایل نگه دارید و پس از پایان، آنها را با نتایج برنامه مقایسه کنید. یک بار مصرف‌کننده را قبل از ثبت نتیجه متوقف کنید و بار دیگر پس از ثبت نتیجه ولی پیش از تأیید. این دو نقطه باید رفتار متفاوتی در برنامه ایجاد کنند، اما هیچ‌کدام نباید اثر تجاری گم‌شده یا تکراری غیرقابل تشخیص بسازند. نتیجه را با شمارش شناسه‌های یکتا بسنجید، نه صرف تعداد خطوط لاگ.

سپس قطع کوتاه ارتباط ناشر را آزمایش کنید. مشخص کنید برنامه هنگام نرسیدن پاسخ چه می‌کند: پیام را در حافظه نگه می‌دارد، در دیسک صف می‌کند یا شکست را به درخواست‌کننده برمی‌گرداند. اگر پیام فقط در حافظه باشد، توقف فرایند می‌تواند آن را از بین ببرد. این تصمیم بخشی از معماری برنامه است و با فعال کردن JetStream به طور خودکار حل نمی‌شود. در پایان، تنظیمات جریان و مصرف‌کننده را همراه نسخه کلاینت ثبت کنید تا آزمایش قابل تکرار باشد.

مجوز و تغییر قالب در طول عمر سامانه

ناشر سفارش الزاماً نباید بتواند جریان را حذف کند یا پیام‌های همه حوزه‌ها را بخواند. دسترسی انتشار، مصرف و مدیریت را جدا طراحی کنید. برای توسعه‌دهنده، محیط آزمایشی با داده ساختگی فراهم کنید تا بررسی قالب نیازمند خواندن داده مشتری نباشد. همچنین تغییر قالب پیام باید با مصرف‌کنندگان قدیمی سازگار یا دارای مسیر مهاجرت باشد. یک فیلد جدید اختیاری معمولاً رفتار متفاوتی از حذف یا تغییر معنای فیلد موجود دارد. پیش از انتشار تغییر، نمونه پیام جدید را با نسخه فعلی مصرف‌کنندگان آزمایش کنید و فقط به موفق بودن ناشر اکتفا نکنید.

تمایز ترتیب پیام با ترتیب اثر

حتی وقتی پیام‌ها به ترتیب مشخصی خوانده می‌شوند، پردازش هم‌زمان ممکن است ترتیب تکمیل را تغییر دهد. فرض کنید رویداد ایجاد سفارش سریع تمام شود ولی رویداد به‌روزرسانی همان سفارش به دلیل تماس بیرونی کند باشد. اگر رویداد بعدی زودتر اثر بگذارد، وضعیت نهایی باید همچنان معتبر بماند. برای موجودیت‌هایی که ترتیب در آنها مهم است، نسخه یا شماره توالی منطقی را در طراحی داده در نظر بگیرید و برخورد با رویداد قدیمی را مشخص کنید. تکیه بر زمان دیواری به تنهایی همیشه برای حل تعارض کافی نیست.

در تمرین، دو رویداد وابسته برای یک شناسه بسازید و یکی را عمداً کند کنید. سپس مشاهده کنید آیا نتیجه مطابق ترتیب کسب‌وکار باقی می‌ماند. اگر نه، انتخاب‌ها شامل محدود کردن هم‌زمانی برای همان موجودیت، بررسی نسخه در پایگاه داده یا طراحی عملیاتی است که جابه‌جایی ترتیب در آن بی‌خطر باشد. این تصمیم باید بر اساس معنای کار گرفته شود. سامانه پیام ابزار انتقال و نگهداری است؛ تعریف اینکه کدام تغییر معتبر است همچنان به مدل داده و قواعد برنامه مربوط می‌شود.

TRACEABLE KNOWLEDGE

منابع و مطالعهٔ بیشتر

01
NATS — منبع اصلیhttps://docs.nats.io/concepts/jetstream
02
NATS — آموزش عمیق JetStreamhttps://docs.nats.io/learn/jetstream
03
تصویر اصلی همین مطلب — NATShttps://docs.nats.io/img/nats-social-card.png

آخرین بررسی تحریریه:

IROSG / EDITORIAL

خبرها و معرفی مشاهیر با نگارش مستقل و ذکر منبع تهیه شده‌اند. اعتبار و مجوز تصاویر در بخش منابع همین صفحه نگه‌داری می‌شود تا متن زیر عکس‌ها شلوغ نشود. داده‌های مرجع CVE با اعتباردهی به منابع اصلی ارائه می‌شوند.

سیاست تألیف و حقوق تصاویر ↗

ادامهٔ کشف.

مقاله‌ها ↗