RE:NODE

რესურსები13 წუთის საკითხავი

Web აპლიკაციის დაგეგმვა გაშვების დღისთვის: cache, მოთხოვნები, რეზერვი

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

განახლებულია

0 მკითხველი

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

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

ტრაფიკის შეფასება გადააქციე მოთხოვნებად წამში#

"ველოდებით ოცი ათას ვიზიტორს" ის რიცხვი არ არის, რომლის მიხედვითაც გეგმავ. გადააქციე მოთხოვნებად წამში და გახდება.

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

code
20,000 visits, 60% in the launch hour   = 12,000 visitshalf of those in the busiest 10 minutes =  6,000 visits6,000 / 600 seconds                     =    10 page views per second

შემდეგ გაამრავლე მოთხოვნების რაოდენობაზე ერთ page view-ზე. Page view ერთი მოთხოვნა არ არის: ეს არის დოკუმენტი და მისი stylesheet-ები, სკრიპტები, შრიფტები, სურათები და ყველაფერი, რასაც analytics მიამატე. თხუთმეტიდან ორმოცამდე დამატებითი მოთხოვნა ნორმალურია. წამში ათ page view-ზე და ოც დამატებით მოთხოვნაზე სულ 200 მოთხოვნას ემსახურები წამში, რომელთაგან ათი შენს აპლიკაციას ეხება და 190 სტატიკური ფაილია.

ეს განაწილება მთელი ამბავია. წამში ათი დინამიკური მოთხოვნა ნებისმიერი framework-ისთვის ნებისმიერ გეგმაზე წვრილმანია. წამში ორასი სტატიკური ფაილის მოთხოვნა წვრილმანია ნებისმიერი web სერვერისთვის. გაშვებას კლავს ის, როცა განაწილება არასწორია - როცა სურათები ფრენაზე იცვლის ზომას, ან "სტატიკური" მარკეტინგული გვერდი ყოველ ჯერზე ბაზიდან იგება.

მოსალოდნელი ვიზიტები პიკურ საათშიPage view/წმდინამიკური მოთხ./წმ (cache-ის გარეშე)დინამიკური მოთხ./წმ (60 წმ cache)
1,0000.50.50.1-ზე ნაკლები
10,000550.1-ზე ნაკლები
50,00025250.1-ზე ნაკლები
200,0001001000.1-ზე ნაკლები

ბოლო სვეტი დამრგვალების ხრიკი არ არის. სამოცი წამით cache-ირებული გვერდი წუთში მაქსიმუმ ერთხელ იგება, რამდენი ადამიანიც არ უნდა ითხოვდეს. ეს არის სხვაობა იმას შორის, რომ გეგმა გჭირდება, და იმას შორის, რომ ერთი დირექტივა გჭირდება.

რამდენი worker სჭირდება რეალურად#

ფორმულა არის Little-ის კანონი და ეს ერთადერთი რიგების თეორიის ნაწილია, რომელიც web დეველოპერს სჭირდება:

code
concurrency = requests per second x average response time

წამში ათი დინამიკური მოთხოვნა 200 ms-ით თითოეული ნიშნავს, რომ ნებისმიერ მომენტში ორი worker მუშაობს. წამში ათი 2 წამით თითოეული - ოცი. პასუხის დრო და არა ტრაფიკი ადგენს worker-ების რაოდენობას, ამიტომაც ნელი endpoint-ის გასწორება გეგმის გაორმაგებაზე მეტად ღირს.

დაამატე რეზერვი, რადგან საშუალო მაჩვენებლები კუდს მალავს. გათვალე 95-ე პროცენტილის პასუხის დროზე და დაამატე 50 პროცენტი. ზემოთ მოცემულ მაგალითში, თუ p95 200 ms-ის ნაცვლად 600 ms-ია, გჭირდება ექვსი worker, ამიტომ გამოყავი ცხრა ან ათი.

PHP-FPM-ისთვის ეს რიცხვი არის pm.max_children, და მას მეხსიერების შეზღუდვაც აქვს:

/etc/php/8.3/fpm/pool.d/www.conf
pm = dynamicpm.max_children = 12pm.start_servers = 4pm.min_spare_servers = 2pm.max_spare_servers = 6pm.max_requests = 500pm.status_path = /fpm-status

pm.max_children გაუტოლე იმ მეხსიერებას, რომლის გამოყოფაც შეგიძლია, გაყოფილს worker-ის რეალურ resident ზომაზე. გაზომე ps-ით და ნუ გამოიცნობ: WordPress-ის worker ტიპური plugin-ების დატვირთვით 60-120 MB-ზეა, ამიტომ 2 GB გეგმაზე, სადაც PHP-სთვის 1.2 GB არის თავისუფალი, ათიდან თორმეტამდე child გამოგივა და არა ორმოცდაათი. მაღალი მნიშვნელობა მეტ გამტარუნარიანობას არ გაძლევს, გაძლევს swap-ს და მერე out-of-memory გაჩერებას.

pm.max_requests = 500 ყოველ worker-ს 500 მოთხოვნის მერე თავიდან ქმნის, რაც ფარავს იმ plugin-ების ნელ გაჟონვას, რომლებიც შენ არ დაგიწერია. ხოლო pm.status_path გაშვებამდე ჩასართავად ღირს: listen queue, რომელსაც ის აჩვენებს, ყველაზე სუფთა ნიშანია, რომ worker-ები გათავდა. ნულზე მეტი, ხანგრძლივად, ნიშნავს, რომ მოთხოვნები child-ს ელოდება და არა შენს კოდს.

Node და Python ერთი პრობლემის სხვა ფორმებია. ერთი Node პროცესი ერთ ბირთვს იყენებს, ამიტომ პარალელიზმი მოდის რამდენიმე ინსტანციის proxy-ს უკან გაშვებიდან, ან cluster-იდან. Gunicorn-ის ცერის წესი სინქრონული worker-ებისთვის არის (2 x cores) + 1, ხოლო async worker-ის კლასი გამოთვლას მთლიანად ცვლის. ყველა შემთხვევაში, worker-ები, რომლებსაც მეხსიერება არ ყოფნის, ნაკლებზე უარესია. რამდენი RAM სჭირდება WordPress-ს PHP-ის შემთხვევას დეტალურად განიხილავს, ხოლო Node-ის მეხსიერების ლიმიტები ფარავს ჭერს, რომელსაც Node პროცესი საკუთარ თავზე ადგენს.

Cache-ში ჩადე გვერდები, რომლებიც არ იცვლება#

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

უმეტესი აქ მთავრდებამხოლოდ uncached გვერდებიერთი cache-ის პერიოდზეqueriesVisitorCDN ან ბრაუზერიhash-იანი ფაილებიReverse proxy10 წმ page cacheაპლიკაციაიგება ერთხელბაზარეალური ჭერი
სად უნდა გაჩერდეს გაშვების დღის მოთხოვნა

სამი ფენა, ყველაზე იაფიდან. გამოიყენე სამივე.

ბრაუზერი და CDN, ყველაფრისთვის, რასაც სახელში hash აქვს. build, რომელიც გასცემს app.4f9c2b.js-ს, შეიძლება სამუდამოდ cache-ირდებოდეს, რადგან ახალი build ახალ სახელს გასცემს:

code
Cache-Control: public, max-age=31536000, immutable

მოკლე proxy cache HTML-ისთვის. ათი წამი საკმარისია, რომ მატება გაბრტყელდეს, და საკმარისად მოკლეა, რომ ძველი შინაარსი არავის შეამჩნიოს. nginx-ში:

nginx
proxy_cache_path /var/cache/nginx keys_zone=micro:10m max_size=1g inactive=10m;map $http_cookie $bypass_cache {    default                0;    ~*session|logged_in    1;}location / {    proxy_pass http://127.0.0.1:3000;    proxy_cache micro;    proxy_cache_valid 200 301 302 10s;    proxy_cache_lock on;    proxy_cache_use_stale updating error timeout http_500 http_502 http_503;    proxy_cache_background_update on;    proxy_cache_bypass $bypass_cache;    proxy_no_cache $bypass_cache;    add_header X-Cache-Status $upstream_cache_status;}

ამ დირექტივებიდან ორი დატვირთვისას გადამწყვეტია. proxy_cache_lock on ნიშნავს, რომ როცა cache-ირებული გვერდი ვადას გასდის, ერთი მოთხოვნა ხელახლა აგენერირებს მას, დანარჩენები ამ ასლს ელოდებიან, იმის ნაცვლად, რომ ათასმა მოთხოვნამ ერთსა და იმავე წამს აპლიკაცია გადათელოს. proxy_cache_use_stale ნიშნავს, რომ თუ აპლიკაცია დაეცა, ვიზიტორები 502-ის ნაცვლად ბოლო კარგ ასლს იღებენ. ერთად ისინი ცუდ ხუთ წუთს უხილავად აქცევენ. გაშვებამდე ბრაუზერის network tab-ში შეამოწმე X-Cache-Status: თუ ყოველ გადატვირთვაზე MISS წერია, პასუხში რაღაც cache-ირებას უშლის ხელს და ეს ჩვეულებრივ Set-Cookie header-ია გვერდზე, რომელსაც ის არ სჭირდება.

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

რისი cache-ირება არ შეიძლება: ყველაფრის, რაც ავტორიზებულია. ეს კარგია, რადგან ავტორიზებული გვერდები გაშვების ტრაფიკის ბევრად მცირე წილია, ვიდრე ელოდები. წესია, რომ cache-ირებადი და პერსონალიზებული მკაცრად გაყო და არასოდეს ჩადო მომხმარებლის მისალმება გვერდის ჩარჩოში, რადგან ერთი სტრიქონი მთელ დოკუმენტს cache-ის გარეშე დარჩენილს ხდის. HTTP caching header-ების ახსნა header-ების სემანტიკას სწორად ფარავს, stale-while-revalidate-ისა და იმის ჩათვლით, რატომ თიშავს არასწორად დაყენებული ETag ჩუმად ყველაფერს.

ბაზა არის ის, რაც ვარდება#

როცა გაშვება ვერ ხერხდება, აპლიკაცია ჩვეულებრივ კარგადაა და ელოდება. ბაზას გაუთავდა რესურსი და თითქმის ყოველთვის სამიდან ერთი გზით.

Query ინდექსის გარეშე. სწრაფია შენს ლეპტოპზე 200 ჩანაწერით, კატასტროფული 200,000-ით, რადგან ეს მიმდევრობითი სკანირებაა. იპოვე ისინი დღემდე. PostgreSQL-ში ჩაწერე ნელი ყველაფერი და მერე წაიკითხე გეგმა:

sql
-- postgresql.conflog_min_duration_statement = 200   -- millisecondsshared_preload_libraries = 'pg_stat_statements'
sql
SELECT calls, round(mean_exec_time::numeric, 1) AS avg_ms, queryFROM pg_stat_statementsORDER BY mean_exec_time * calls DESCLIMIT 10;

დაალაგე ჯამური დროით და არა საშუალოთი, რადგან query, რომელიც ათი ათასჯერ 40 ms-ით სრულდება, უფრო მეტს აზარალებს, ვიდრე ანგარიში, რომელიც ერთხელ 4 წამში სრულდება. სვეტი არის mean_exec_time PostgreSQL 13-ში და მის მერე, და mean_time მანამდე. შემდეგ გაუშვი EXPLAIN (ANALYZE, BUFFERS) უარეს დამნაშავეზე და მოძებნე მიმდევრობითი სკანირება დიდ ცხრილზე. EXPLAIN ANALYZE-ის კითხვა აჩვენებს, რას ნიშნავს გამოტანა.

კავშირების ამოწურვა. ყოველი framework ხსნის pool-ს, ყოველ worker-ს აქვს pool და max_connections სასრულია. ათი აპლიკაციის ინსტანცია 20-იანი pool-ით 200 კავშირს ითხოვს ნაგულისხმევის წინააღმდეგ, რომელიც ხშირად 100-ია, და თითოეული PostgreSQL backend რამდენიმე მეგაბაიტს ხარჯავს, სანამ რამეს გააკეთებს. სიმპტომია FATAL: sorry, too many clients already და აპლიკაცია, რომელიც თითქოს ჩაიკიდა. Pool-ები ბაზას მოარგე და არა აპლიკაციას: ყველა ინსტანციის ჯამური pool-ის ზომა max_connections-ზე კომფორტულად დაბლა უნდა იყოს, შენი psql სესიისთვის ადგილის დატოვებით. Connection pool-ები და ლიმიტები მთელი ამბავია, ხოლო PostgreSQL-ის დაყენება პატარა სერვერზე ფარავს პარამეტრებს, რომლებიც 1-8 GB-ზე მნიშვნელოვანია.

ჩაწერები, რომლებიც სერიულად სრულდება. მთვლელის სვეტი, რომელსაც ყოველი ვიზიტორი ზრდის, სესიის ჩანაწერი, რომელიც ყოველ მოთხოვნაზე ახლდება, analytics-ის insert მოთხოვნის გზაზე. ისინი ერთი მომხმარებლით ტესტირებისას არ ჩანს და ათასით ბლოკირების კონკურენციად იქცევა. გაიტანე მოთხოვნიდან ყველაფერი, რაც სინქრონული არ უნდა იყოს: რიგში, ფონურ worker-ში ან მხოლოდ დამატებად ჟურნალში, რომელსაც მოგვიანებით აგრეგირებ. ფონური სამუშაოები პატარა სერვერზე ამას ახალი ინფრასტრუქტურის გარეშე ფარავს.

ფაილები, სურათები და ბაიტები, რომლებსაც ვერავინ ითვლის#

ნელი გაშვების გვერდის ყველაზე გავრცელებული მიზეზი სერვერი არ არის. ეს არის 4 MB ზომის hero სურათი, შეუკუმშავი, სრული გარჩევადობით ტელეფონზე გაგზავნილი. ოცი ათასი ვიზიტორი გამრავლებული 4 MB-ზე არის 80 GB გადაცემა ერთი დეკორატიული ფოტოსთვის და თითოეულმა ვიზიტორმა ის დაელოდა.

დღემდე:

  • სურათებს ზომა შეუცვალე იმ უდიდეს ზომამდე, რომლითაც რეალურად ჩანს, და გასცემდე თანამედროვე ფორმატებს.
  • ჩართე Gzip ან Brotli ტექსტური პასუხებისთვის. ეს ერთი დირექტივაა და HTML-ს, CSS-სა და JavaScript-ს ჩვეულებრივ 70-80 პროცენტით ამცირებს.
  • ყოველ build ფაილს შინაარსის hash მიეცი სახელში, რომ სამუდამოდ cache-ირდებოდეს.
  • შრიფტები შენს origin-ზე დადე font-display: swap-ით, ნაცვლად იმისა, რომ რენდერი მესამე მხარეს დაელოდოს.
  • ამოიღე analytics და chat ვიჯეტები, რომლებსაც არ იყენებ. თითოეული არის DNS ძებნა, კავშირი და სკრიპტი კრიტიკულ გზაზე.

ამ ყველაფერს ჰოსტინგთან საქმე არ აქვს და სწორედ ამიტომ ღირს აქ თქმა: გეგმის განახლება 4 MB სურათს არ ამცირებს. TTFB, Core Web Vitals და ჰოსტინგი გულწრფელად ამბობს, რომელ რიცხვებს ამოძრავებს ჰოსტინგი და რომელს - არა.

გატესტე დატვირთვით დღემდე#

ნამდვილი ინსტრუმენტით ტესტირებას ოცი წუთი სჭირდება და ეს ერთადერთი გზაა, რომ გაიგო, იმუშავა თუ არა ყველაფერმა ზემოთ. ტესტი staging ასლზე გააკეთე production-ის ფორმის მონაცემებით და არა ცარიელ ბაზაზე, რადგან მთელი აზრი იმ query-ის პოვნაა, რომელსაც მხოლოდ მასშტაბზე სტკივა.

ერთი endpoint-ის სწრაფი შესამოწმებლად:

bash
$ oha -z 60s -c 50 https://staging.example.com/$ hey -z 60s -c 50 https://staging.example.com/

რეალისტური აღმავლობისთვის k6 დამატებით ფაილს ღირს:

javascript
import http from "k6/http";import { check, sleep } from "k6";export const options = {  stages: [    { duration: "1m", target: 50 },    { duration: "3m", target: 200 },    { duration: "1m", target: 0 },  ],  thresholds: { http_req_duration: ["p(95)<500"] },};export default function () {  const res = http.get("https://staging.example.com/");  check(res, { "status is 200": (r) => r.status === 200 });  sleep(1);}

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

გქონდეს განახლების გზა და არა თავად განახლება#

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

უკეთესი პოზიცია ისაა, რომ ზუსტად იცი, რას გააკეთებდი და რამდენ ხანს დასჭირდება. ჩაწერე დღემდე:

  1. რომელ დონეზე გადახვიდოდი და რა ღირს.
  2. რამდენ ხანს გრძელდება გადასვლა და თუ არა პროცესს ხელახლა რთავს. გეგმის შეცვლა სერვერს არ აშენებს თავიდან, ამიტომ ფაილები, ბაზის slot და დომენი ზუსტად იქ რჩება, სადაც იყო.
  3. რას გამორთავდი პირველად, თუ დატვირთვის მოხსნა მოგიწევდა: ძიების endpoint-ს, ცოცხალ მთვლელს, რეკომენდაციების ვიჯეტს. feature flag, რომლის გადართვაც ათ წამში შეგიძლია, მეტს ღირს, ვიდრე დონე, რომლის ყიდვაც ერთ წუთში ვერ ხერხდება.
  4. როგორ გამოიყურება შენი სტატიკური სარეზერვო გვერდი. error_page 502 503 504 /maintenance.html; ნამდვილი გვერდით უკეთესი შედეგია, ვიდრე nginx-ის ნაგულისხმევი.

აპლიკაციისა და web გეგმები მოიცავს reverse-proxy slot-ს, ამიტომ დომენი და მისი სერტიფიკატი უკვე სერვერზეა მიმართული და თავისით განახლდება; მომხმარებლის რეალური მისამართი მოდის X-Forwarded-For-ში, რაც მნიშვნელოვანია, თუ IP-ით rate limiting-ს აკეთებ. Express-ში ეს ნიშნავს app.set("trust proxy", 1)-ს ნებისმიერ rate limiter-მდე, თორემ ყველა ვიზიტორი proxy-ს დაემსგავსება. რას აკეთებს reverse proxy დანარჩენ header-ების დამუშავებას განმარტავს.

რას უყურო დღის განმავლობაში, თანმიმდევრობით#

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

სიგნალისადრას ნიშნავს, თუ იცვლება
შეცდომების წილიაპლიკაციის ლოგი, proxy ლოგიერთადერთი რიცხვი, რომელიც ყოველთვის ცუდია
p95 პასუხის დროProxy ლოგი ან შენი APMიზრდება შეცდომებამდე; შენი ადრეული გაფრთხილება
Worker-ების გაჯერებაpm.status_path listen queueმოთხოვნები პროცესს ელოდება და არა კოდს
ბაზის კავშირებიpg_stat_activity რაოდენობაmax_connections-თან მიახლოება ნიშნავს ჩაკიდებას
CPUპანელის გრაფიკიშენს წილზე მიჭერილი ნელია და არა გატეხილი
მეხსიერებაპანელის გრაფიკიგაფრთხილებაა იატაკის ზრდა და არა პიკი
დისკიპანელის გრაფიკილოგები და სურათების ატვირთვები ივსება მოსალოდნელზე სწრაფად

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

FAQ#

რამდენ ტრაფიკს გაუძლებს პატარა გეგმა?

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

გაშვებამდე განვაახლო გეგმა, ყოველი შემთხვევისთვის?

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

რატომ ნელდება საიტი შეცდომამდე?

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

აუცილებელია CDN გაშვებისთვის?

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

რა ტყდება პირველი, როცა web აპლიკაციას მეხსიერება ეწურება?

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

შემიძლია გაშვებისას შესწორების deploy?

შეგიძლია და proxy-ს უკან rolling restart მას უხილავს გახდის, მაგრამ ერთდროულად ერთი რამ შეცვალე და წინა ვერსია მზად გქონდეს დასაბრუნებლად. Zero-downtime deploy-ები პატარა სერვერზე ფარავს მექანიკას ერთ მანქანაზე.


კომენტარები

სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.

0/2000