System Design
Għaliex l-Iskala Timporta Anki Qabel l-Applikazzjoni Tikber
L-iskala mhix dwar traffiku li għad m'għandekx. Ftit drawwiet ta' .NET, żomm l-app stateless, async sal-aħħar, u tissejjaħx id-database f'loop, ma jiswew xejn kmieni u huma ta' wġigħ biex iżżidhom aktar tard.
"M'għandekx bżonn tinkwieta dwar l-iskala għadu" huwa parir li smajt ħafna, u fil-biċċa l-kbira huwa korrett. Li tiddisinja għal miljuni ta' utenti meta m'għandek l-ebda wieħed huwa kif proġetti qatt ma jiġu ppubblikati.
Iżda hemm kategorija ta' deċiżjoni li ma tiswa xejn meta tagħmilha kmieni u hija verament ta' wġigħ biex iżżidha aktar tard, u bħala junior developer dawk huma dawk li ta' min jaf dwarhom. Mhux għax il-proġetti tiegħi għandhom traffiku, iżda għax uħud minn dawn huma d-differenza bejn li żżid it-tieni server tkun bidla ta' konfigurazzjoni jew rewrite.
Żomm l-istat barra mill-applikazzjoni
Din hija l-waħda l-kbira. Jekk l-API tiegħi taħżen xi ħaġa importanti fil-memorja tagħha stess, allura talba trid tirritorna lejn l-istess istanza biex taħdem sew, u dan ifisser li qatt ma nista' nħaddem żewġ kopji.
Dejta ta' sessjoni fil-memorja, lista cached f'qasam statiku, fajl uploaded miktub fuq disk lokali. Kull waħda minn dawk kwietament torbot utent ma' istanza speċifika waħda. Iċċaqlaqhom barra, ġo database, cache distribwit, blob storage, u f'daqqa waħda ma jimportax liema istanza twieġeb talba.
Niltaqa' ma' dan konkretament mal-URL shortener li bnejt. Tliet kopji tal-app wara load balancer jaħdmu biss għax l-ebda waħda minnhom iżżomm xejn lokalment. Kull kopja tara l-istess dejta għax id-dejta tgħix f'Cassandra u Redis, mhux fl-app. Dak ma kienx ottimizzazzjoni ta' skala, kien sempliċiment kif l-app kellha tinkiteb biex load balancing ikun possibbli fl-ewwel lok.
Async sal-aħħar
F'ASP.NET Core, thread imblukkat jistenna sejħa ta' database huwa thread li ma jistax iservi talba oħra. B'utent wieħed dan huwa inviżibbli. B'mitt talba konkurrenti huwa d-differenza bejn li tittrattahom u li tqegħedhom fuq lista ta' stennija.
// blocks a thread while waiting
var product = _context.Products.Find(id);
// releases the thread back to the pool
var product = await _context.Products.FindAsync(id);
Il-verżjoni async mhix aktar mgħaġġla għal talba waħda. Sempliċiment tfisser li t-thread jerġa' lura fil-pool minflok joqgħod hemm ma jagħmel xejn, li huwa dak li jħalli server żgħir jittratta ħafna aktar xogħol konkurrenti milli għandu threads.
Li tikteb await mill-bidu ma jiswa xejn. Li tikkonverti codebase sinkronu għal async aktar tard tfisser tmiss kull metodu fil-katina tas-sejħiet, għax async irid imur sal-aħħar.
Tissejjaħx id-database f'loop
L-iżball klassiku, u wieħed li għamilt:
var orders = await _context.Orders.ToListAsync();
foreach (var order in orders)
{
// one extra query per order
order.Customer = await _context.Customers.FindAsync(order.CustomerId);
}
B'għaxar ordnijiet dak huwa ħdax-il query u ħadd ma jinnota. B'elf ordni huwa elf u wieħed, u l-endpoint jieħu wisq żmien u jieqaf. Is-soluzzjoni hija titlob dak li teħtieġ minn qabel:
var orders = await _context.Orders
.Include(o => o.Customer)
.ToListAsync();
Dak li jagħmel dan ta' min jaqbdu kmieni huwa li jaħdem tajjeb fl-iżvilupp. Id-database tat-test tiegħi għandha ħames rows fiha. Il-problema tidher biss b'dejta reali, li huwa l-agħar ħin biex issibha.
Ġib biss dak li teħtieġ
Drawwa relatata: AsNoTracking() fuq queries li huma read-only biss, u tagħżel il-kolonni speċifiċi minflok entitajiet sħaħ meta teħtieġ biss ftit oqsma.
var names = await _context.Products
.AsNoTracking()
.Select(p => new { p.Id, p.Name })
.ToListAsync();
Il-change tracker ta' EF Core jeżisti biex ikun jista' jinnota x'immodifikajt u jiġġenera aġġornamenti. Fuq query fejn xejn ma jiġi mmodifikat, dik hija kontabilità mingħajr raġuni.
Poġġi l-indexes kmieni
Jekk naf li kolonna se ssir query fuqha, l-index jappartjeni fil-migration li toħloq it-tabella. Li żżid index fuq tabella vojta huwa immedjat. Li żżid wieħed fuq tabella kbira fil-produzzjoni hija operazzjoni li trid tippjana madwarha.
X'kont xorta ninjora
Saffi ta' caching, message queues, read replicas, sharding, kwalunkwe minn dawn. Dawk isolvu problemi li nista' nkejjel, u għadni ma nistax inkejjilhom. Li żżid cache lil proġett mingħajr traffiku sempliċiment ifisser aktar kodiċi u klassi ġdida ta' bug fejn il-cache u d-database ma jaqblux.
Il-linja attwali li nagħmel
Il-mistoqsija li nistaqsi mhix "dan se jiskala." Hija "jekk dan jeħtieġ jinbidel aktar tard, hija bidla ta' konfigurazzjoni jew rewrite?"
Stateless, async, ebda queries f'loops, indexes sensibbli — dawk kollha huma "iktibhom hekk mill-bidu u huma b'xejn." Caching, queues, u replicas kollha huma "żidhom meta jkollok kejl li jgħid li teħtieġhom." Li ġġib l-ewwel lista tajba kmieni huwa dak li jagħmel it-tieni lista għażla minflok emerġenza.