سازگاری رو به جلو
سازگاری پیش رو چیست
سازگاری رو به جلو توانایی یک سیستم برای کار به درستی با مشتریان جدیدتر و یا داده ها از کسانی که برای آن در اصل طراحی شده بود. ساده تر: سرور قدیمی زمانی که یک مشتری جدید به آن می آید خراب نمی شود. مصرف کننده قدیمی سقوط نمی کند زمانی که آنها با یک پیام جدید روبرو می شوند.
به جلو از سازگاری با عقب (زمانی که سیستم جدید از مشتریان قدیمی پشتیبانی می کند) در جهت مسئولیت متفاوت است: ما پروتکل ها و مشتریان را به گونه ای طراحی می کنیم که «برنامه های آینده» را بدون ارتقاء کامل کل اکوسیستم.
اصول اساسی
1. خواننده تحمل و نویسنده تحمل
خواننده فیلدها/هدر های ناشناخته را نادیده می گیرد و اجازه می دهد تا مقادیر جدید enum با fallback صحیح.
نویسنده چیزی را که سرور به صراحت به عنوان پشتیبانی (قابلیت ها) اعلام نکرده است ارسال نمی کند.
2. مذاکره توانایی
تبادل صریح قابلیت ها (ویژگی ها/نسخه ها/انواع رسانه ها) در مرحله دست دادن. مشتری رفتار خود را با پاسخ سرور سازگار می کند.
3. تخریب پیش فرض
ویژگی های جدید اختیاری در نظر گرفته می شوند: اگر سرور/مصرف کننده از آنها پشتیبانی نکند، اسکریپت با حداقل مفید (MGC) پایان می یابد.
4. هسته پایدار (MGC)
حداقل قرارداد گارانتی بدون تغییر است. نوآوری ها به عنوان پسوند زندگی می کنند.
5. قراردادهای خطا به عنوان بخشی از پروتکل
کدهای/دلایل قابل پیش بینی («ویژگی پشتیبانی نمی شود»، «نوع رسانه ناشناخته») اجازه می دهد مشتری به طور خودکار به حالت پشتیبانی شده بازگردد.
6. نسخه های بدون شگفتی
خطوط اصلی از هم جدا ؛ افزونه های کوچک نیازی به ارتقاء سرور/مصرف کننده ندارند.
جایی که اهمیت دارد
API های عمومی با یکپارچگی طولانی مدت (شرکا، SDK ها در برنامه های تلفن همراه).
سیستم عامل رویداد با بسیاری از مصرف کنندگان مستقل.
مشتریان تلفن همراه که به روز رسانی آهسته تر از باطن.
Edge/IoT، جایی که بخشی از ناوگان دستگاه به ندرت چشمک می زند.
الگوهای پیاده سازی توسط سبک
استراحت/HTTP
مذاکره:- 'Accept '/انواع رسانه ها با پارامترها (' application/vnd. به عنوان مثال. سفارش + json ؛ v = 1 ؛ مشخصات = خطر ').
- 'ترجیح می دهم: شامل =... برای بلوک های اختیاری.
- قابلیت های X: risk_score,item_details_v2'
- یک درخواست را در فرمت پایه، برنامه های افزودنی ارسال می کند - فقط اگر سرور دارای قابلیت تایید شده (از طریق OPTIONS/desc/lead endpoint) باشد.
- هنگامی که «415/406/501» به طور خودکار به فرمت/روش پشتیبانی می شود.
- پاسخ سرور: پارامترهای ناشناخته - چشم پوشی; زمینه های اضافی مجاز است ؛ پایدار فرمت خطا ('نوع/کد/جزئیات/ردیابی _ id').
gRPC/Protobuf
خدمات پایدار: روش های جدید/زمینه ها - افزودنی ؛ سرور قدیمی به آرامی فیلدهای درخواست ناشناخته را نادیده میگیرد.
کشف ویژگی: متد 'GetCapabilities ()' لیستی از ویژگی ها/محدودیت ها را برمی گرداند. سرویس گیرنده روش v2 را فراخوانی نمی کند مگر اینکه سرور آن را اعلام کند.
جریان: رفع منظور از حداقل مجموعه ای از پیام ها ؛ علامت گذاری به عنوان «فریم» جدید با پسوند/انواع که مشتری قدیمی نادیده می گیرد.
GraphQL
Forward-friendly: فیلدها/انواع جدید بر روی سرور ظاهر می شوند - مشتریان قدیمی به سادگی آنها را درخواست نمی کنند.
حدس زدن ممنوع است: مشتری باید طرح (introspection/codogen) را حفظ کند و دستورالعمل ها/متغیرهای ناشناخته را ارسال نکند.
تخریب: اگر سرور دستورالعمل سفارشی/ویژگی را نمی داند، مشتری یک درخواست بدون آن ایجاد می کند.
رویداد محور (کافکا/NATS/پولسار، آورو/JSON/پروتو)
سازگاری پیش از طرح در رجیستری: مصرف کنندگان قدیمی می توانند پیام های نوشته شده توسط طرح جدید را بخوانند.
زمینه های افزودنی با پیش فرض: تولید کنندگان جدید مصرف کنندگان قدیمی را شکست نمی دهند.
هسته در مقابل غنی شده: هسته یکسان باقی می ماند، اطلاعات جدید در «.enriched» یا به عنوان زمینه های اختیاری منتشر می شود.
شیوه های طراحی
1. حداقل قرارداد درخواست (MGC)
این عملیات باید یک «گردن باریک» داشته باشد که تمام سرورها برای سالها پشتیبانی می کنند.
2. پرچم های برجسته در سطح قرارداد
ویژگی ها را به عنوان ویژگی های نامگذاری شده توصیف کنید: «ریسک _ نمره»، «قیمت گذاری _ v2»، «قوی _ idempotency». مشتری آنها را به طور صریح تعریف می کند.
3. کدهای خطای صریح برای «پشتیبانی نمی شود»
HTTP: «501 اجرا نشده»، «415 نوع رسانه پشتیبانی نشده»، детальные «مشکل + json».
gRPC: 'UNIMPLEMENTED '/' شکست خورده _ پیش شرط'.
رویدادها: مسیر در DLQ با 'reason = unsupported _ feature'.
4. به لیست های سفارش/کامل اعتماد نکنید
مشتری باید برای مقادیر جدید enum، بدون زمینه های جدید و خواص «اضافی» آماده باشد.
5. شناسه ها و فرمت های پایدار
فرمت کلیدهای ID/پارتیشن بندی را در خط تغییر ندهید - این در کنار خوانندگان به جلو می رود.
6. مستندات «ماشین قابل خواندن»
توصیفگرهای میزبان: توصیفگرهای OpenAPI/AsyncAPI/Proto/GraphQL SDL. مشتریان می توانند پشتیبانی از این ویژگی را بررسی کنند.
تست سازگاری به جلو
Schema-diff در حالت FORWARD/FULL: طرح جدید اعتبار مصرف کننده/سرور قدیمی را تأیید می کند.
تست قرارداد مشتری: یک مشتری جدید در برابر یک سرور قدیمی با ویژگی های فعال/غیرفعال اجرا می شود.
درخواست های طلایی: مجموعه ای از درخواست های «جدید» از طریق سرور «قدیمی» اجرا می شود ؛ تخریب مورد انتظار بدون اشتباهات بحرانی.
Chaos/latency: چک کردن timeout/retray - مشتری جدید باید به درستی از بدترین SLA های سرور قدیمی جان سالم به در ببرد.
Canary: برخی از مشتریان جدید با نسخه سرور قبلی کار می کنند - ما تله متری خطاها/تخریب را جمع آوری می کنیم.
قابلیت مشاهده و معیارهای عملیاتی
درصد درخواست ها/پیام ها با ویژگی های پشتیبانی نشده و بازگشت خودکار آنها.
توزیع توسط نسخه های مشتری (کاربر عامل/ابرداده/ادعا).
'UNIMPLEMENTED/501/415' errors و مسیرها در DLQ با 'unsupported _ feature'.
زمان تخریب: p95/p99 برای MGC در مقابل پاسخ «گسترده».
حالت های سازگاری در رجیستری طرح
FORWARD: ورودی جدید سازگار با خواننده قدیمی است (پیش فرض ها مورد نیاز است، اختیاری).
کامل: и به جلو، и به عقب ؛ مناسب برای قراردادهای عمومی
توصیه: برای رویدادها - BACKWARD برای تولید کننده و FORWARD برای مصرف کننده (از طریق یک خواننده تحمل)، برای API های خارجی - FULL.
مثال ها
REST (قابلیت + تخریب)
1. کلاینت «GET/meta/capabilities» → {«risk _ score»: false, «price_v2": true}» را میسازد.
2. در 'POST/orders' زمینه های پایه را ارسال می کند ؛ 'risk _ score' درخواست نمی کند، زیرا سرور نمی تواند این کار را انجام دهد.
3. اگر به طور تصادفی «Prefer: include = risk _ score» ارسال شود، سرور با 200 بدون فیلد «risk _ score» (یا «Preference-Applied: none») پاسخ می دهد - مشتری سقوط نمی کند.
gRPC (کشف)
'GetCapabilities ()' بازگشت لیست روش/ویژگی. مشتری «CaptureV2» را در صورت عدم وجود صدا نمی زند - به جای آن از «Capture» استفاده می کند و به صورت محلی ورودی را به نمای پشتیبانی شده تبدیل می کند.
رویدادها (به جلو در رجیستری)
تولید کننده فیلد «risk _ score» را اضافه کرد (قابل حذف با پیش فرض). مصرف کننده قدیمی او را نادیده می گیرد ؛ منطق آن فقط از فیلدهای پایدار هسته استفاده می کند.
ضد ضربه
مشتری سخت: پاسخ را با فیلدهای لیست سفید فیلتر می کند و در یک ویژگی نا آشنا قرار می گیرد.
ویژگی های ضمنی: مشتری شروع به ارسال یک پارامتر جدید بدون بررسی قابلیت ها می کند.
تغییر فرمت های شناسه/کلید در خط → سرورها/مصرف کنندگان قدیمی دیگر درخواست ها/پیام های جدید را درک نمی کنند.
فرضیه های سخت افزاری در مورد لیست کامل enum (سوئیچ بدون پیش فرض).
ورود به سیستم به عنوان کنترل جریان: تجزیه رشته خطا به جای کدهای قرارداد.
چک لیست پیاده سازی
- MGC تعریف شده است ؛ ویژگی های جدید به عنوان اختیاری مشخص شده اند.
- مذاکره قابلیت (نقطه پایانی/ابرداده/دست دادن) شرح داده شده و اجرا شده است.
- مشتریان زمینه های ناآشنا را نادیده می گیرند و به درستی enum جدید (fallback) را اداره می کنند.
- قراردادهای خطا به صورت قابل پیش بینی «پشتیبانی نمی شوند» (HTTP/gRPC/Event).
- رجیستری طرح به FORWARD/FULL برای مصنوعات مربوطه تنظیم شده است.
- Autotests: schema-diff (FORWARD)، مشتری در مقابل تست های قرارداد سرور قدیمی، canary.
- معیارها: نسخه مشتری، خرابی ویژگی، میزان تخریب، P95 MGC.
- مستندات/SDK ها لیستی از ویژگی ها و نمونه های تخریب را منتشر می کنند.
سوالات متداول
تفاوت جلو با عقب در عمل چیست ؟
Backward: سرور جدید مشتریان قدیمی را خراب نمی کند. به جلو: سرور قدیمی از مشتریان جدید (یا مصرف کننده قدیمی از پیام های جدید) شکسته نمی شود. در حالت ایده آل، شما کامل می شوید.
آیا همیشه باید امکانات را وارد کنم ؟
اگر انتظار تکامل فعال بدون انتشار همزمان را دارید، بله. این ارزان تر از نگه داشتن ده ها خط اصلی است.
در مورد امنیت چطور ؟
ویژگی های جدید باید دامنه/ادعاهای جداگانه ای داشته باشند. اگر سرور از آنها پشتیبانی نکند، مشتری نباید امنیت را کاهش دهد، بلکه باید ویژگی را رها کند.
آیا امکان پشتیبانی «حدس» توسط نسخه سرور وجود دارد ؟
ناخواسته. بهتر است به صراحت (قابلیت ها) بپرسید یا به نوع رسانه/طرح نگاه کنید.
مجموع
قابلیت همکاری رو به جلو نظم و انضباط از فرصت های مذاکره و با خیال راحت تحقیر است. هسته پایدار، مذاکره قابلیت، پسوند افزودنی و اشکالات قابل پیش بینی اجازه می دهد مشتریان و داده های جدید به همراه سرورهای قدیمی و مصرف کنندگان - بدون انتشار انبوه و مهاجرت شبانه.