რა დგას თითქმის ყველა ვებ-სერვისის წინ
კეთილი იყოს თქვენი მობრძანება
თუ ბრაუზერში ჩაწერთ example.com, თითქმის არასდროს აღწევთ იმ მანქანამდე, რომელიც რეალურად აწარმოებს აპლიკაციას. თქვენ აღწევთ იმ მანქანამდე, რომელიც გადაუგზავნის მოთხოვნას იმ მანქანას, რომელიც ამას აკეთებს. ამ გადამისამართებულ მანქანას აქვს სახელი: რევერსული პროქსი.
ეს გაკვეთილი გასწავლით, რას აკეთებს რევერსული პროქსი, რატომ იმალება თითქმის ყველა საჯარო ვებ-სერვისი მის უკან და რა სამ სამუშაოს ასრულებს ერთდროულად ეჯ-ფენა.
გაკვეთილის ბოლოს თქვენ გაიგებთ:
- კლიენტს, პროქსის და ორიჯინის შორის სხვაობა
- რატომ იცავს, მასშტაბირებს და გაძლევს საშუალებას შეცვალო ნაწილები ისე, რომ არავინ შეამჩნიოს, პროქსი ორიჯინის წინ
- რევერს პროქსის სამი ამოცანა, რომელსაც ერთდროულად ასრულებს: ორიჯინის დამალვა, TLS-ის ტერმინაცია და დატვირთვის განაწილება რეპლიკებზე
- როგორ მოგზაურობს მოთხოვნა ბრაუზერიდან პროქსამდე, შემდეგ upstream-მდე და უკან — ჰოპ-ჰოპით
კურსის დასასრულს თავდაჯერებულად შეძლებთ მსჯელობას პროქსის განთავსებაზე, edge-ზე პასუხისმგებლობების გამიჯვნაზე და იმაზე, თუ რატომ მრავლდება იაფად სტეიტლეს პროქსის ტირი, ხოლო ერთი ორიჯინი — არა.
წინა პროქსი თუ უკუ პროქსი
პროქსის ორი მიმართულება
ორივე სახის პროქსი ორ მხარეს შორის დგას და ტრაფიკს აწვდის. ისინი განსხვავდებიან იმით, თუ რომელ მხარეს წარმოადგენენ.
წინასწარი პროქსი (Forward proxy): დგას კლიენტების ჯგუფის წინ. კლიენტები იციან პროქსის შესახებ; გარე სერვერი ხედავს პროქსის მისამართს, და არა კლიენტის მისამართს. კორპორაციული egress პროქსიები, კონტენტის ფილტრები და SOCKS პროქსიები ამ ნიმუშს მიეკუთვნებიან.
უკუ პროქსი (Reverse proxy): დგას სერვერების ჯგუფის წინ. გარე სამყარო (კლიენტები) საუბრობს პროქსის მისამართთან; კლიენტებს არ აქვთ წარმოდგენა, რომ რეალური სერვერი მის უკან იმალება. თითქმის ყველა საჯარო ვებ-სერვისი იყენებს მას.
მნემონიკური წესი: წინასწარი პროქსი მალავს კლიენტებს სერვერებისგან. უკუ პროქსი მალავს სერვერებს კლიენტებისგან.
რატომ არის მნიშვნელოვანი, რომელი მიმართულებით? სამუშაო, წარუმატებლობის რეჟიმები და უსაფრთხოების საზღვარი განსხვავებულია. წინასწარი პროქსი ზრუნავს იმაზე, თუ ვისთან უკავშირდებიან მისი მომხმარებლები; უკუ პროქსი ზრუნავს იმაზე, თუ ვინ უკავშირდება მის სერვერებს.
კლიენტი, რომელიც ერთდროულად ორივე ტიპის პროქსის მეშვეობით აგზავნის ტრაფიკს, გადის შემდეგ გზას: client -> forward_proxy -> internet -> reverse_proxy -> origin.
რატომ ცხოვრობს იმდენი რამ კიდეზე
კიდური ფენა იმსახურებს თავის ადგილს
Reverse proxy ერთდროულად ასრულებს სამ სამუშაოს. მათგან რომელიმე ერთი საკმარისია ამ ფენის გასამართლებლად; სამივეს ერთი და იგივე მისამართით შესრულება კი ხსნის, რატომ აქვს თითქმის ყველა პროდაქშენ ვებ-არქიტექტურას ერთნაირი ფორმა წინა მხარეს.
სამუშაო 1: დაიმალე წყარო. პროქსი პასუხობს საჯარო IP-ზე. ბეკენდები იჯდებიან კერძო IP-ებზე, რომლებსაც ინტერნეტი ვერ მიაღწევს. თავდამსხმელს, რომელიც წყაროს დარტყმას უნდა, ჯერ უნდა გატეხოს პროქსი.
სამუშაო 2: TLS-ის დასრულება. პროქსი ფლობს example.com-ის სერტიფიკატს და გაშიფრავს შემოსული HTTPS მოთხოვნებს. ბეკენდები პროქსისთვის უგზავნიან ჩვეულებრივ HTTP-ს (ან უფრო მარტივ შიდა TLS-ს) სანდო ქსელის სეგმენტზე. სერტიფიკატის როტაცია, განახლება და შიფრების პოლიტიკა — ყველაფერი ერთ ადგილასაა.
სამუშაო 3: დატვირთვის განაწილება. პროქსი წყვეტს, რომელი ბეკენდი უნდა დაამუშაოს თითოეული მოთხოვნა. ერთი პროქსის მიღმა მყოფი ბეკენდები ქმნიან პულს; პროქსი თითოეული მოთხოვნისთვის ირჩევს ერთ-ერთს სტრატეგიის მიხედვით (round-robin, least-connections, ჰეში ჰედერზე). სიმძლავრის დამატება ნიშნავს პულში ახალი ბეკენდის დამატებას, და არა ყველა კლიენტისთვის ახალი მისამართის გაცნობას.
თითოეული სამუშაო არის მცირე პროგრამა. ერთად ისინი ხსნიან, რატომ აქვს ისეთ მარტივ ტიერს, როგორიცაა „Caddy Python აპის წინ“, უფრო მეტი დიზაინის წონა, ვიდრე თავად Python აპლიკაციას.
სამივესთვის დიზაინი
თქვენი გუნდი მართავს მცირე API-ს ერთ პითონის პროცესზე, რომელიც უსმენს პორტ 8000-ს ერთ VM-ზე. ტრაფიკი იმდენად გაიზარდა, რომ ერთი VM აღარ საკმარისია, ხოლო უსაფრთხოების შემოწმებამ აღნიშნა, რომ VM-ს აქვს საჯარო IP და თავად ატარებს TLS სერტიფიკატს.
თქვენ გადაწყვიტეთ, რომ წინ დააყენოთ რევერს პროქსი. დახაზეთ სქემა: სად მიუთითებს DNS, სად ცხოვრობს სერტიფიკატი, როგორ აღწევს დატვირთვა ბეკენდებამდე და რა იცვლება საწყის VM-თან დაკავშირებით?
შეცვალე კომპონენტი ისე, რომ არავინ შეამჩნიოს
ინდირექცია გაძლევს თავისუფლებას
ძველი კომპიუტერული მეცნიერების გამოთქმა ამბობს: ყველა პრობლემის გადაჭრა შესაძლებელია ინდირექციის (indirection) კიდევ ერთი ფენის დამატებით (გარდა იმ პრობლემისა, რომელიც გამოწვეულია ძალიან ბევრი ინდირექციის ფენით). Reverse proxy ერთ-ერთი ყველაზე სასარგებლო ინდირექციაა განაწილებულ სისტემებში.
რას გაძლევთ:
- გაცვლადი ბეკენდები. გადაიყვანთ აპლიკაციას Python-იდან Go-ზე? გადაიტანთ ერთი დატაცენტრიდან მეორეში? გაუშვებთ ახალ ვერსიას ნულოვანი downtime-ით? ყველაფერი ხდება სტაბილური საჯარო მისამართის მიღმა. მომხმარებლებისთვის არაფერი იცვლება.
- დამოუკიდებელი სკალირება. პროქსის ფენა სკალირდება გამტარუნარიანობასა და CPU-ზე TLS ფენაზე. ბეკენდის ფენა სკალირდება აპლიკაციის მუშაობაზე. თითოეული იზრდება საკუთარ ღერძზე, რადგან ისინი სხვადასხვა მანქანებზე ცხოვრობენ.
- გაუმართაობის კონტეინმენტი. ბეკენდზე ცუდი დეპლოი არ აკოტრავს საჯარო მისამართს. პროქსი რჩება ცოცხალი; თქვენ აგზავნით ფიქსს ან აბრუნებთ წინა ვერსიას; მსოფლიო კვლავ უკავშირდება, როგორც კი ბეკენდი გამოჯანმრთელდება.
- კროს-კატინგ საზრუნავები ერთ ადგილას. რეიტ ლიმიტი, გეობლოკირება, მოთხოვნების ლოგირება, ჰედერების გადაწერა, ქეშირება, პასუხის კომპრესია — ყველაფერი პროქსიზე ცხოვრობს. ბეკენდის კოდი რჩება ფოკუსირებული აპლიკაციაზე.
პროქსის გარეშე ყველა ეს პრობლემა უნდა იცხოვროს აპლიკაციის პროცესის შიგნით. პროქსით ისინი ცხოვრობენ ერთ ფენაში, რომელსაც ერთი გუნდი ფლობს.
ფასი: კიდევ ერთი ფენა, რომლის მართვაც საჭიროა. მწიფე გუნდები იღებენ ამ ხარჯს, რადგან პროქსის ფენა თავად არის სტეისლესი და ჰორიზონტალურად სკალირდება; ერთი პროქსის ორით ჩანაცვლება არ საჭიროებს კოორდინაციას.
ბლუ/გრინ დეპლოი პროქსის მეშვეობით
თქვენი გუნდი აწარმოებს API-ის პირველ ვერსიას სამ ბეკენდ VM-ზე (blue pool), რომლებიც reverse proxy-ის მიღმაა. გსურთ განათავსოთ მეორე ვერსია ისე, რომ შეძლოთ როლბეკი 30 წამში, თუ რამე არასწორედ წავა.
თქვენ აწყობთ სამ ახალ ბეკენდ VM-ს (green pool) მეორე ვერსიით, ლურჯ 풀თან ერთად, მაგრამ ჯერ არ აწვდით მათ ტრაფიკს.
ბრაუზერიდან ბეკენდამდე და უკან
გა просვლეთ ერთი მოთხოვნა დასაწყისიდან ბოლომდე
გ просვლეთ ერთი HTTPS GET მოთხოვნა https://api.example.com/users/42-ზე, რომელიც გადის რევერსულ პროქსის გავლით ბეკენდის პულის წინ.
Hop 1: DNS რეზოლუცია. ბრაუზერი სთხოვს რეზოლვერს api.example.com-ს. რეზოლვერი აბრუნებს პროქსის საჯარო IP-ს (მაგ. 203.0.113.10). ბრაუზერი ხსნის TCP კავშირს 203.0.113.10:443-ზე.
Hop 2: TLS ჰენდშეიკი. პროქსი წარმოადგენს თავის სერტიფიკატს api.example.com-სთვის. ბრაუზერი ამოწმებს სერტიფიკატს, ორივე მხარე თანხმდება სესიის გასაღებზე და იხსნება დაშიფრული არხი.
Hop 3: HTTP მოთხოვნა TLS-ის შიგნით. ბრაუზერი აგზავნის GET /users/42 HTTP/1.1\nHost: api.example.com\n.... პროქსი ახდენს მოთხოვნის ბაიტების დეშიფრაციას.
Hop 4: ბэкენდის არჩევა. პროქსი კონსულტაციას უწევს თავის upstream 풀ს api.example.com-სთვის და ირჩევს ერთ ბэкენდს (მაგ. 10.0.0.21:8000) თავისი load-balancing სტრატეგიის მიხედვით.
Hop 5: Upstream მოთხოვნა. პროქსი ხსნის (ან ხელახლა იყენებს) ჩვეულებრივ HTTP კავშირს 10.0.0.21:8000-თან და გადაგზავნის მოთხოვნას. პროქსიმ შეიძლება გადაწეროს ჰედერები გზაში: დაამატოს X-Forwarded-For: <client-ip>, სწორად დააყენოს Host:, ამოიღოს hop-by-hop ჰედერები, როგორიცაა Connection.
Hop 6: ბэкენდის დამუშავება. ბэкენდის აპლიკაცია კითხულობს მოთხოვნას, აკეთებს მოთხოვნას მონაცემთა ბაზაში და აგებს JSON პასუხს.
Hop 7: Upstream პასუხი. ბэкენდი უბრუნებს პასუხს პროქსისთვის ჩვეულებრივი HTTP-ით.
Hop 8: Edge პასუხი. პროქსიმ შეიძლება გადაწეროს ან შეკუმშოს პასუხი, დაშიფროს იგი TLS სესიაში და გაუგზავნოს ბრაუზერს.
Hop 9: კავშირის სასიცოცხლო ციკლი. TLS სესია, როგორც წესი, ღია რჩება შემდეგი მოთხოვნისთვის (HTTP/2 მრავალ მოთხოვნას მულტიპლექსირებს ერთ კავშირზე). პროქსი-ბэкენდის კავშირი ხშირად იყენებს პულს გამოყენებისთვის.
ყველა საჯარო ვებ-სერვისი ამ ფორმის რომელიმე ვარიანტს მიჰყვება. ჰოპების ცოდნა გაძლევთ საშუალებას გაანალიზოთ, სად გროვდება ლატენცია, სად უნდა იყოს ლოგირება და სად შეიძლება დაიმალოს შეცდომა.
სად წავიდა დრო?
მომხმარებელი უჩივის, რომ API ნელია. თქვენ ზომავთ და ხედავთ, რომ მოთხოვნას საერთო ჯამში 850 მწმ სჭირდება. ბეკენდის ლოგები აჩვენებს, რომ აპლიკაციამ მოთხოვნას მოემსახურა 40 მწმ-ში. პროქსის ლოგები კი აჩვენებს, რომ პროქსიმ თავის მხარეს 50 მწმ დახარჯა (TLS handshake + რაუტინგი + პასუხის გაგზავნა).
შეიმუშავეთ მინიმალური Edge ახალი სერვისისთვის
სინთეზი
თქვენ ისწავლეთ განსხვავება forward და reverse proxy-ს შორის, რა სამი ამოცანა აქვს reverse proxy-ს ერთდროულად, რატომ იძლევა origin-ის დამალვა დივიდენდებს ყოველ ჯერზე, როდესაც რაღაცას ცვლით, და როგორ მოგზაურობს მოთხოვნა hop-ით hop-ამდე edge-ის გავლით.
ახლა გამოიყენეთ ეს ცოდნა.
პატარა გუნდი გეგმავს გამოუშვას ახალი სერვისი სახელად notes.example.com. მომხმარებლები წაიკითხავენ და ჩაწერენ პირად ჩანაწერებს. გაშვებისას გუნდი გამოიყენებს ორ backend VM-ს და მომავალი წლის განმავლობაში გეგმავს გაზრდას ათამდე. მათ სურთ HTTPS მომხმარებლებისთვის, ახალი ვერსიების თანდათანობითი გაშვება და backend-ების IP მისამართების საჯაროდ არ გამოჩენა.
სად გაგრძელდება ეს კურსი შემდეგ
სად გაგრძელდება ეს კურსი შემდეგ
ამ გაკვეთილმა დაადგინა edge layer-ის ფორმა. ამ კურსში კიდევ ოთხი გაკვეთილი დაეყრდნობა მას:
- Stateless Horizontal Scaling: რატომ მრავლდება იაფად proxy tier (და მის უკან მყოფი backends), და მათემატიკა რეპლიკების რაოდენობის გამოსათვლელად დატვირთვის მატებისას.
- Ingress / Egress Separation: რატომ ვერ მუშაობს საბოლოოდ ერთი proxy კომპიუტერი, რომელიც ერთდროულად ამუშავებს შემომავალ და გამავალ ტრაფიკს, და როგორ გავყოთ ეს ფენები.
- წარუმატებლობის რეჟიმები და დაზიანების რადიუსი: როგორ იწვევს ერთი კონფიგურაციის ცვლილება სისტემურ გაუმართაობას და როგორ დავწეროთ უდანაშაულო სამოქმედო გეგმები, რომლებიც ხელს შეუშლიან პრობლემის გამეორებას.
- დაკვირვებადობა და ტევადობა: რა უნდა გავზომოთ კიდეზე, რომ მომხმარებლებამდე აღმოაჩინოთ, რომ რაღაც გაფუჭდა.
თითოეული გაკვეთილი თავისთავად დამოუკიდებელია. ერთად კი ისინი გაძლევენ მუშა მენტალურ მოდელს ვებ-მასშტაბის ფლოტის შესახებ.
თანმხვედრი გაკვეთილი: geometry_of_proxies_and_origins ამ გაკვეთილში ყველაფერს გადააქცევს მიმართული გრაფად და იკვლევს, რას გვეუბნება გრაფთეორია მოთხოვნის მარშრუტზე.
კარგად შეასრულეთ. წინ გავაგრძელოთ.