Exponential backoff, Circuit breaker – ანუ ცადეთ მოგვიანებით

ჩვენი პროგრამები არასრულყოფილ სამყაროში ცხოვრობენ, არასტაბილური ქსელით ლაპარაკობენ და არაგარანტირებულ რესურსებს ეძახიან. ბოლო დროს განსაკუთრებით კიდევ უფრო მეტი ჩავარდნის შესაძლებლობა გაჩნდა, როცა ყველაფერი სერვისებად იქცა.
კოდში ზოგჯერ ძირითად ლოგიკაზე მეტი ადგილი ამ ჩავარდნებისგან დაზღვევას უჭირავს.
ერთ-ერთ ასეთ მათგანზე მინდა დავწერო, როცა სერვისის გამოძახება წარუმატებლად სრულდება.

პრობლემური შედეგი შეიძლება სხვადასხვა ხასიათის იყოს:
გარდამავალი – მაგალითად,
– 503 Service unavailable – როდესაც სერვისი გადატვირთულია ან დროებით გათიშულია;
– 504 Gateway Timeout – როდესაც ბექ სერვერიდან პასუხი დროულად არ მოდის პროქსისთან;
– ასევე ნებისმიერი timeout, როდესაც სერვერიდან საერთოდ არ მოდის პასუხი.
ეს გარდამავალი შეცდომებია და შეიძლება გამოსწორდეს რაღაც დროის შემდეგ

მუდმივი – არასწორი პაროლის შეცდომა თავისით არასოდეს გამოსწორდება, რამდენჯერაც არ უნდა გაიგზავნოს.

როდესაც დავადგენთ, რომ გარდამავალ შეცდომასთან გვაქვს საქმე, შეგვიძლია ავდგეთ და რამდენიმე წამში ერთხელ კვლავ გავიმეოროთ მოთხოვნა. ოღონდ ერთი მომენტია კიდევ: თუ სერვისი დიდი დატვირთვის გამო ვერ აბრუნებს პასუხს, მაშინ ჩვენი ასეთი მიმართვები კიდევ უფრო გაზრდის მოთხოვნების რიგს და ხელს შეუშლის სერვისს აღდგენაში. მდგომარეობის გამოსასწორებლად რამდენიმე დიზაინ პატერნია გავრცელებული:

 

Exponential backoff

ალბათ შეგიმჩნევიათ, როცა GMail არის გახსნილი და ინტერნეტი ითიშება, თავზე ეწერება შეტყობინება Connecting in 1s… ჯერ ერთ წამში ცდის, მერე 2 წამში, მერე 4 წამში, მერე 8-ში და ასე ექსპონენციალურად ზრდის დროს მცდელობებს შორის. საათებზეც კი ადის.
საუბარი არ არის მხოლოდ ბრაუზერს და სერვერს შორის ურთიერთობაზე. შეიძლება ასეთი პრობლემური კავშირები მთელიანად სერვერის მხარეს არსებულ სხვადასხვა კომპონენტს შორის იყოს. ზოგჯერ უკეთესი შედეგის მისაღებად ‘შემთხვევითობაც’ შემოაქვთ, მაგალითად Amazon AWS არქიტექტურაში ორივე ერთად გამოიყენება: Exponential Backoff and Jitter.
ანუ მეორე მცდელობა 4 წამის შემდეგ კი არა იყოს, არამედ 1-4 ფარგლებში შემთხვევითად შერჩეულ X წამის შემდეგ.

ეს რიცხვები ახსნის ხათრით შემოვიტანე. ცხადია, რამდენიმე კონსტანტა იქნება საჭირო:
საბაზო დაყოვნების დრო, ცდების მაქსიმალური რაოდენობა და დაყოვნების მაქსიმალური დრო.

ანალოგიურად, ჩვენც შეგვიძლია სერვისის წარუმატებელი გამოძახების შემდეგ ყოველ წამს კი არ გავიმეოროთ მოთხოვნა, არამედ უფრო და უფრო მეტი დაყოვნება გავაკეთოთ და სერვისს აღდგენის საშუალება მივცეთ.

Exponential backoff ალგორითმი Ethernet პროტოკოლშიც გამოიყენება. როცა ქსელში ორი მანქანა ერთდროულად ცდილობს პაკეტის გაგზავნას, კოლიზია ხდება. ზუსტად იგივე დაყოვნების შემდეგ რომ გაგზავნოს ორივემ, ისევ ისე დაემთხვევა და ასე უსასრულოდ. ამიტომ დაყოვნების ფორმულა ასეთია
0 ≤ r < 2^k სადაც k = min (n, 10)
n არის კოლიზიების რაოდენობა და r შემთხვევითად ირჩევა. ანუ რაც უფრო მეტი კოლიზია ხდება, ექსპონენციალურად იზრდება საზღვარი, და მერე ამ საზღვრიდან ხდება დაყოვნების დროის ამორჩევა შემთხვევითად.

 

Circuit breaker

ეს ალგორითმი ჰგავს ელექტრო ქსელის ავტომატურ ამომრთველს, რომელიც ყველას გვიყენია სახლში.
სერვისს და კლიენტს შორის დამატებით დგება ერთი შუალედური ობიექტი, რომელიც სერვისის მცველის როლს ასრულებს. როცა ხედავს რომ დროის გარკვეულ მონაკვეთში სერვერისგან ცუდი პასუხები მოდის ან საერთოდ არ მოდის, გადადის “Open” რეჟიმში, აღარ უშვებს მასთან კლიენტის მოთხოვნებს და თვითონვე პასუხობს ჩავარდნით.

როცა ელექტრო ამომრთველს მოსდის ასე, ხელით ვრთავთ უკან, მაგრამ აქ ხელით ვერ ჩავრთავთ, ამიტომ რაღაც ინტერვალის შემდეგ ეს მცველი ობიექტი გადაგვყავს “Half-Open” რეჟიმში და ის ერთ მოთხოვნას სერვისამდე გაატარებს საცდელად. პასუხის მიხედვით ან ისევ “Open” რეჟიმში დაბრუნდება, ან “Closed” გახდება და ყველა მომდევნო მოთხოვნას სერვერთან გაუშვებს ჩვეულებრივ.

რამდენიმე ტაიმაუტის შემდეგ მცველი ჩაირთვება და ის დაიწყებს პასუხის დაბრუნებას

სურათი აღებულია მარტინ ფოულერის ბლოგიდან

ზოგიერთ ფრეიმვორკში (განსაკუთრებით ბაზასთან ურთიერთობისას) უკვე იმპლემენტირებულია მსგავსი ალგორითმები.

თუ თქვენ public API გაქვთ და გსურთ რომ უცხო კლიენტებმა retry-ის სწორი მექანიზმი გამოიყენონ – სულ მთლად არ მოკლან თქვენი სერვისი გაჭირვების ჟამს, მაშინ შეგიძლიათ თქვენ თვითონ დაწეროთ რამდენიმე კლიენტი-ბიბლიოთეკა სხვადასხვა ენისთვის და მომხმარებლებიც მათ გამოიყენებენ.

გამოხმაურება

comments

კომენტარის დატოვება

თქვენი ელფოსტის მისამართი გამოქვეყნებული არ იყო. აუცილებელი ველები მონიშნულია *