პირდაპირი თავსებადობა
რა არის პირდაპირი თავსებადობა
პირდაპირი თავსებადობა არის სისტემის უნარი სწორად იმუშაოს ახალ მომხმარებლებთან ან მონაცემებთან, ვიდრე ის, რისთვისაც იგი თავდაპირველად შეიქმნა. უფრო ადვილია: ძველი სერვერი არ იშლება, როდესაც მასთან ახალი კლიენტი მოდის; ძველი მომხმარებელი არ ეცემა, როდესაც ის ახალ შეტყობინებას ხვდება.
საპირისპირო თავსებადობისგან (როდესაც ახალი სისტემა მხარს უჭერს ძველ მომხმარებლებს), ფორვარდი განსხვავდება პასუხისმგებლობის მიმართულებით: ჩვენ ვქმნით ოქმებს და მომხმარებლებს, რათა „გადარჩეს“ მომავალი გაფართოებები მთლიანი ეკოსისტემის გარეშე.
ძირითადი პრინციპები
1. Tolerant reader & tolerant writer
Reader უგულებელყოფს უცნობ ველებს/სათაურებს და საშუალებას აძლევს ახალ ენობრივ მნიშვნელობებს სწორი fallback.
Writer არ უგზავნის არაფერს, რაც სერვერმა აშკარად არ გამოაცხადა, როგორც მხარდაჭერილი (კაპიტალები).
2. Capability negotiation
შესაძლებლობების აშკარა გაცვლა (ფიჩები/ვერსიები/მედია ტიპები) handshake ეტაპზე. კლიენტი ადაპტირებს თავის ქცევას სერვერის პასუხზე.
3. ნაგულისხმევი დეგრადაცია
ახალი შესაძლებლობები სურვილისამებრ ითვლება: თუ სერვერი/კონსუმერი არ უჭერს მხარს მათ, სცენარი მაინც დასრულდება სასარგებლო მინიმუმით (MGC).
4. სტაბილური ბირთვი (MGC)
მინიმალური საგარანტიო ხელშეკრულება უცვლელია; ინოვაციები ცხოვრობენ, როგორც გაფართოება.
5. შეცდომის კონტრაქტები, როგორც ოქმის ნაწილი
პროგნოზირებადი კოდები/მიზეზები („fich არ არის მხარდაჭერილი“, „მედია ტიპი უცნობია“) საშუალებას აძლევს კლიენტს ავტომატურად დაუბრუნდეს მხარდაჭერილ რეჟიმს.
6. ვერსიები სიურპრიზების გარეშე
მთავარი ხაზები გამოყოფილია; მცირე გაფართოებები არ საჭიროებს სერვერის/კონსუტერის განახლებას.
სად არის ეს განსაკუთრებით მნიშვნელოვანი
საზოგადოებრივი API გრძელი ინტეგრაციით (პარტნიორები, SDK მობილური აპლიკაციებით).
ღონისძიების პლატფორმები მრავალი დამოუკიდებელი კონსიუმერით.
მობილური მომხმარებლები, რომლებიც განახლებულია უფრო ნელა, ვიდრე უკანა პლანზე.
Edge/IoT, სადაც მოწყობილობების პარკის ნაწილი იშვიათად გადის.
განხორციელების ნიმუშები სტილში
REST/HTTP
Negotiation:- 'Accept '/მედია პარამეტრებით (' განაცხადი/vnd. example. order+json; v=1; profile=risk`).
- 'prefer: include =...' არჩევითი ბლოკებისთვის.
- სათაური 'X-Capabilities: risk _ score, item _ details _ v2'.
- იგი აგზავნის თხოვნას ძირითადი ფორმატით, გაფართოებით - მხოლოდ იმ შემთხვევაში, თუ სერვერმა დაადასტურა capability (OPTIONS/desc/lid endpoint- ის საშუალებით).
- „415/406/501“ -ზე ავტომატურად ბრუნდება მხარდაჭერილი ფორმატი/მეთოდი.
- სერვერის პასუხი: უცნობი პარამეტრები - უგულებელყოფა; დამატებითი ველები ნებადართულია; შეცდომის სტაბილური ფორმატი ('ტიპი/კოდი/detail/trace _ id').
gRPC / Protobuf
სტაბილური სერვისები: ახალი მეთოდები/ველები - დანამატი; ძველი სერვერი მშვიდად უგულებელყოფს უცნობი მოთხოვნის ველებს.
Feature discovery: მეთოდი 'GetCapabilities () "უბრუნდება ფიგურების/ლიმიტების სიებს. კლიენტი არ იწვევს „v2 მეთოდს“, თუ სერვერმა არ გამოაცხადა იგი.
ნაკადი: ჩაწერეთ შეტყობინებების მინიმალური ნაკრები; ახალი „ჩარჩოები“ შეაფასეთ გაფართოებები/ტიპები, რომლებსაც ძველი კლიენტი უგულებელყოფს.
GraphQL
Forward friendly: სერვერზე ჩნდება ახალი ველები/ტიპები - ძველი მომხმარებლები უბრალოდ არ ითხოვენ მათ.
ვარაუდები აკრძალულია: კლიენტმა უნდა შეინარჩუნოს სქემა (ინტროსპექცია/კოდოგენი) და არ გაუგზავნოს უცნობი დირექტივები/ცვლადები.
დეგრადაცია: თუ სერვერმა არ იცის კასტომის დირექტივა/feature - კლიენტი აშენებს თხოვნას მის გარეშე.
Event-driven (Kafka/NATS/Pulsar, Avro/JSON/Proto)
FORWARD- ის თავსებადობა რეესტრში: ძველ კონსიუმერებს შეუძლიათ წაიკითხონ ახალი სქემით ჩაწერილი შეტყობინებები.
დანამატის ველები ნაგულისხმევი: ახალი მწარმოებლები არ არღვევენ ძველ კონსიუმერებს.
Core vs Enriched: ბირთვი იგივე რჩება, ახალი ინფორმაცია ქვეყნდება '.enriched' ან როგორც არჩევითი ველები.
დიზაინის პრაქტიკა
1. მინიმალური მოთხოვნის ხელშეკრულება (MGC)
ოპერაციას უნდა ჰქონდეს „ვიწრო კისერი“, რომელსაც ყველა სერვერი მრავალი წლის განმავლობაში დაუჭერს მხარს.
2. Fich დროშები ხელშეკრულების დონეზე
აღწერეთ ფიჩები, როგორც დასახელებული შესაძლებლობები: 'risk _ score', 'pricing _ v2', 'strong _ idempotence'. კლიენტი მათ აშკარად მოიცავს.
3. შეცდომების აშკარა კოდები არ არის მხარდაჭერილი
HTTP: `501 Not Implemented`, `415 Unsupported Media Type`, детальные `problem+json`.
gRPC: `UNIMPLEMENTED`/`FAILED_PRECONDITION`.
Events: მარშრუტი DLQ- ით 'reason = unsuported _ feature'.
4. ნუ დაეყრდნობით წესრიგს/სრულ სიებს
კლიენტი უნდა იყოს მზად enum- ის ახალი მნიშვნელობებისთვის, ახალი ველების არარსებობისთვის და „დამატებითი“ თვისებებისთვის.
5. სტაბილური იდენტიფიკატორები და ფორმატები
არ შეცვალოთ ID/კონვერტაციის ღილაკები ხაზის ფარგლებში - ეს არღვევს ფორვარდს მკითხველთა მხარეზე.
6. დოკუმენტაცია
ჰოსტიტის აღწერილობები: OpenAPI/AsyncAPI/Proto descriptors/GraphQL SDL. კლიენტებს შეუძლიათ შეამოწმონ თავიანთი მხარდაჭერა.
ფორვარდის თავსებადობის ტესტირება
Schema-diff FORWARD/FULL რეჟიმში: ახალი სქემა უხელმძღვანელებს ძველ მომხმარებელს/სერვერს.
კლიენტის საკონტრაქტო ტესტები: ახალი კლიენტი ხორციელდება ძველი სერვერის წინააღმდეგ, რომელიც ჩართულია/გამორთულია ფილიალებით.
Golden requests: „ახალი“ მოთხოვნების ნაკრები გამოიყოფა „ძველი“ სერვერის გასწვრივ; მოსალოდნელია დეგრადაცია კრიტიკული შეცდომების გარეშე.
Chaos/latency: Taimauts/retray- ის შემოწმება - ახალი კლიენტი სწორად უნდა გადარჩეს ძველი სერვერის ყველაზე უარესი SLA.
Canary: ზოგიერთი ახალი მომხმარებელი მუშაობს წინა სერვერის ვერსიასთან - ჩვენ აგროვებს შეცდომების/დეგრადაციის ტელემეტრიას.
დაკვირვება და ოპერაციული მეტრიკა
მოთხოვნის/შეტყობინებების წილი შეუსაბამო ლეიბებით და მათი ავტომატური გამოტოვებით.
განაწილება მომხმარებელთა ვერსიების მიხედვით (მომხმარებელი-აგენტი/მეტამონაცემები/კლასები).
შეცდომები 'UNIMPLEMENTED/501/415' და მარშრუტები DLQ- ით 'unsupported _ feature ".
დეგრადაციის დრო: p95/p99 MGC- სთვის „გაფართოებული“ პასუხის წინააღმდეგ.
თავსებადობის რეჟიმები სქემების რეესტრში
FORWARD: ახალი ჩანაწერი შეესაბამება ძველ მკითხველს (საჭიროა ნაგულისხმევი, მიზანშეწონილობა).
FULL: и FORWARD, и BACKWARD; მოსახერხებელია საჯარო კონტრაქტებისთვის.
რეკომენდაცია: მოვლენებისთვის - BACKWARD პროდიუსერისა და FORWARD- ისთვის საკონსულტაციო (tolerant reader- ის საშუალებით), გარე API- სთვის - FULL.
მაგალითები
REST (კაპიტები + დეგრადაცია)
1. კლიენტი აკეთებს 'GET/meta/capilities' „{“ risk _ score „: false,“ price _ v2 „: ნამდვილი“.
2. 'POST/orders' - ზე იგი აგზავნის საბაზო ველებს; 'risk _ score' არ ითხოვს, რადგან სერვერმა არ იცის როგორ.
3. თუ მან შემთხვევით გაგზავნა 'Prefer: include = risk _ score', სერვერი პასუხობს 200 ველის გარეშე 'risk _ score' (ან 'Preference-Applied: none') - კლიენტი არ ეცემა.
gRPC (discovery)
'GetCapabilities () "დაუბრუნა მეთოდების/ფიგურების ჩამონათვალს. კლიენტი არ იწვევს 'CaptureV2', თუ ის არ არის - ამის ნაცვლად იყენებს „კაპიტულს“ და ადგილობრივად გარდაქმნის შეყვანის მონაცემებს მხარდაჭერილ სახეობად.
Events (FORWARD რეესტრში)
პროდიუსერმა დაამატა ველი 'risk _ score' (nullable ნაგულისხმევი). ძველი კონსუმერი უგულებელყოფს მას; მისი ლოგიკა იყენებს მხოლოდ ბირთვების სტაბილურ ველებს.
ანტიპატერები
მკაცრი კლიენტი: ფილტრავს პასუხს whitelist მინდვრებზე და ეცემა უცნობ საკუთრებაში.
აშკარა ფიჩები: კლიენტი იწყებს ახალი პარამეტრის გაგზავნას კაპიტალის შემოწმების გარეშე.
ID/კლავიშების ფორმატის შეცვლა ხაზის შიგნით, ძველი სერვერები/კონსუტერები წყვეტენ ახალი მოთხოვნების/შეტყობინებების გაგებას.
ნაქსოვი ვარაუდები სრული ჩამონათვალის შესახებ (switch გარეშე default).
ლოგიკა, როგორც ნაკადის კონტროლი: შეცდომის სტრიქონების დარტყმა ხელშეკრულების კოდების ნაცვლად.
ჩეკის განხორციელების სია
- განსაზღვრულია MGC; ახალი შესაძლებლობები აღინიშნება, როგორც სურვილისამებრ.
- აღწერილია და ხორციელდება კაპიტალური ნეგოტია (ენდოინტი/მეტამონაცემები/ჰანდშაკი).
- მომხმარებლები უგულებელყოფენ უცნობ მინდვრებს და სწორად ამუშავებენ ახალ ენას (fallback).
- შეცდომის კონტრაქტები „არ არის მხარდაჭერილი“ პროგნოზირებადი (HTTP/gRPC/Event).
- სქემების რეესტრი განთავსებულია FORWARD/FULL შესაბამისი არტეფაქტებისთვის.
- Autostests: schema-diff (FORWARD), კლიენტის საკონტრაქტო ტესტები ძველი სერვერის წინააღმდეგ, კანარი.
- მეტრიკი: კლიენტის ვერსია, ფიჩის უკმარისობა, დეგრადაციის წილი, p95 MGC.
- დოკუმენტაცია/SDK აქვეყნებს ფიგურების ჩამონათვალს და დეგრადაციის მაგალითებს.
FAQ
როგორ განსხვავდება forward backward- დან პრაქტიკაში?
Backward: ახალი სერვერი არ არღვევს ძველ მომხმარებლებს. ფორვარდი: ძველი სერვერი არ იშლება ახალი მომხმარებლებისგან (ან ძველი კონსიუმერი - ახალი შეტყობინებებიდან). იდეალურ შემთხვევაში, full- ს მიაღწევთ.
ყოველთვის აუცილებელია კაპიტალების შემოღება?
თუ თქვენ მოელით აქტიურ ევოლუციას სინქრონიზებული გამოშვებების გარეშე - დიახ. ეს იაფია, ვიდრე ათობით მთავარი ხაზის შენარჩუნება.
რა შეიძლება ითქვას უსაფრთხოებაზე?
ახალმა ხრიკებმა უნდა მოითხოვოს ინდივიდუალური scopes/claims. თუ სერვერი მათ არ უჭერს მხარს, კლიენტმა არ უნდა შეამციროს უსაფრთხოება, მაგრამ უნდა უარი თქვას ფიჩზე.
შესაძლებელია თუ არა სერვერის მიხედვით მხარდაჭერის „გამოცნობა“?
არასასურველია. უმჯობესია იკითხოთ აშკარად (capabilities) ან გადახედოთ მედია/სქემას.
შედეგი
უშუალო თავსებადობა არის დისციპლინა შეთანხმდნენ შესაძლებლობებზე და უსაფრთხოდ დეგრადაცია. სტაბილური ბირთვი, კაპიტალური ნეგოტაცია, დანამატის გაფართოებები და პროგნოზირებადი შეცდომები საშუალებას აძლევს ახალ მომხმარებლებს და მონაცემებს გაუმკლავდნენ ძველ სერვერებსა და მომხმარებლებს - მასობრივი გამოშვებებისა და ღამის მიგრაციის გარეშე.