![Search icon](https://hackernoon.imgix.net/search-new.png?w=19&h=19)
Programmatūras noturība attiecas uz lietojumprogrammas spēju turpināt darboties nevainojami un uzticami pat neparedzētu problēmu vai kļūmju gadījumā. Fintech projektos noturība ir īpaši svarīga vairāku iemeslu dēļ. Pirmkārt, uzņēmumiem ir pienākums izpildīt normatīvās prasības, un finanšu regulatori uzsver darbības noturību, lai saglabātu sistēmas stabilitāti. Turklāt digitālo rīku izplatība un paļaušanās uz trešo pušu pakalpojumu sniedzējiem pakļauj Fintech uzņēmumus paaugstinātiem drošības apdraudējumiem. Noturība palīdz arī mazināt atslēgumu riskus, ko izraisa dažādi faktori, piemēram, kiberdraudi, pandēmijas vai ģeopolitiski notikumi, aizsargājot pamatdarbības un kritiskos līdzekļus.
Ar noturības modeļiem mēs saprotam paraugprakses un stratēģiju kopumu, kas izstrādāts, lai nodrošinātu, ka programmatūra var izturēt traucējumus un uzturēt savu darbību. Šie modeļi darbojas kā drošības tīkli, nodrošinot mehānismus kļūdu novēršanai, slodzes pārvaldībai un atkopšanai no kļūmēm, tādējādi nodrošinot, ka lietojumprogrammas joprojām ir izturīgas un uzticamas nelabvēlīgos apstākļos.
Visizplatītākās noturības stratēģijas ietver starpsienu, kešatmiņu, atkāpšanos, atkārtotu mēģinājumu un ķēdes pārtraucēju. Šajā rakstā es tos aplūkošu sīkāk, sniedzot piemērus problēmām, kuras tās var palīdzēt atrisināt.
Apskatīsim iepriekš minēto iestatījumu. Mums ir ļoti parasta lietojumprogramma ar vairākām aizmugurprogrammām, no kurām iegūt dažus datus. Šīm aizmugursistēmām ir pievienoti vairāki HTTP klienti. Izrādās, ka visiem tiem ir viens un tas pats savienojumu baseins! Un arī citi resursi, piemēram, CPU un RAM.
Kas notiks, ja vienā no aizmugursistēmām radīsies problēmas, kuru rezultātā palielinās pieprasījuma latentums? Lielā atbildes laika dēļ viss savienojumu pūls tiks pilnībā aizņemts ar pieprasījumiem, kas gaida atbildes no backend1. Rezultātā pieprasījumus, kas paredzēti veselīgam aizmugursistēmai2 un aizmugursistēmai3, nevarēs turpināt, jo pūls ir izsmelts. Tas nozīmē, ka kļūme kādā no mūsu aizmugursistēmām var izraisīt kļūmi visā lietojumprogrammā. Ideālā gadījumā mēs vēlamies, lai pasliktinātos tikai funkcionalitāte, kas saistīta ar neveiksmīgo aizmugursistēmu, bet pārējā lietojumprogramma turpina darboties kā parasti.
Kas ir starpsienu modelis?
Termins starpsienu modelis cēlies no kuģu būves, tas ietver vairāku izolētu nodalījumu izveidi kuģī. Ja vienā nodalījumā rodas noplūde, tas piepildās ar ūdeni, bet pārējie nodalījumi paliek neskarti. Šī izolācija neļauj visam kuģim nogrimt viena pārkāpuma dēļ.
Starpsienu modeli var izmantot, lai lietojumprogrammā izolētu dažāda veida resursus, neļaujot atteicei vienā daļā ietekmēt visu sistēmu. Lūk, kā mēs to varam pielietot savai problēmai:
Pieņemsim, ka mūsu aizmugursistēmām ir maza iespējamība, ka atsevišķi tiks konstatētas kļūdas. Tomēr, ja operācija ietver visu šo aizmugursistēmu paralēlu vaicājumu, katra var neatkarīgi atgriezt kļūdu. Tā kā šīs kļūdas rodas neatkarīgi, kopējā kļūdas iespējamība mūsu lietojumprogrammā ir lielāka nekā jebkura atsevišķa aizmugursistēmas kļūdas iespējamība. Kumulatīvo kļūdu iespējamību var aprēķināt, izmantojot formulu P_total=1−(1−p)^n, kur n ir aizmugursistēmu skaits.
Piemēram, ja mums ir desmit aizmugursistēmas, katra ar kļūdas iespējamību p=0,001 (atbilst SLA 99,9%), iegūtā kļūdu iespējamība ir:
P_kopā=1–(1–0,001)^10=0,009955
Tas nozīmē, ka mūsu apvienotais SLA samazinās līdz aptuveni 99%, kas parāda, kā samazinās kopējā uzticamība, ja tiek vaicājumi vairākās aizmugurprogrammās paralēli. Lai mazinātu šo problēmu, mēs varam ieviest kešatmiņu atmiņā.
Atmiņā esošā kešatmiņa kalpo kā ātrgaitas datu buferis, kurā tiek glabāti bieži pieejamie dati un katru reizi nav nepieciešams tos ienest no potenciāli lēniem avotiem. Tā kā atmiņā saglabātajām kešatmiņām kļūdu iespējamība ir 0%, salīdzinot ar datu ienešanu tīklā, tās ievērojami palielina mūsu lietojumprogrammas uzticamību. Turklāt kešatmiņa samazina tīkla trafiku, vēl vairāk samazinot kļūdu iespējamību. Līdz ar to, izmantojot atmiņā esošo kešatmiņu, mēs varam sasniegt vēl zemāku kļūdu līmeni mūsu lietojumprogrammā, salīdzinot ar mūsu aizmugursistēmām. Turklāt atmiņā esošās kešatmiņas nodrošina ātrāku datu izgūšanu nekā tīklā balstīta ielāde, tādējādi samazinot lietojumprogrammu latentumu — tā ir ievērojama priekšrocība.
Personalizētiem datiem, piemēram, lietotāju profiliem vai ieteikumiem, ļoti efektīva var būt arī kešatmiņas izmantošana atmiņā. Taču mums ir jānodrošina, ka visi lietotāja pieprasījumi konsekventi tiek nosūtīti uz vienu un to pašu lietojumprogrammas gadījumu, lai izmantotu tiem kešatmiņā saglabātos datus, kam nepieciešamas lipīgās sesijas. Lipīgo sesiju ieviešana var būt sarežģīta, taču šim scenārijam mums nav nepieciešami sarežģīti mehānismi. Ir pieļaujama neliela trafika līdzsvarošana, tāpēc pietiks ar stabilu slodzes līdzsvarošanas algoritmu, piemēram, konsekventu jaukšanu.
Turklāt mezgla kļūmes gadījumā konsekventa jaukšana nodrošina, ka līdzsvarošana tiek veikta tikai ar neveiksmīgo mezglu saistītajiem lietotājiem, tādējādi samazinot sistēmas traucējumus. Šī pieeja vienkāršo personalizēto kešatmiņu pārvaldību un uzlabo mūsu lietojumprogrammas vispārējo stabilitāti un veiktspēju.
Ja dati, kurus plānojam saglabāt kešatmiņā, ir kritiski un tiek izmantoti visos mūsu sistēmas apstrādātajos pieprasījumos, piemēram, piekļuves politikās, abonēšanas plānos vai citās mūsu domēnā svarīgās entītijās, šo datu avots var radīt nopietnu mūsu sistēmas kļūmes punktu. Lai risinātu šo problēmu, viena pieeja ir pilnībā replicēt šos datus tieši mūsu lietojumprogrammas atmiņā.
Šādā gadījumā, ja datu apjoms avotā ir pārvaldāms, mēs varam sākt procesu, lejupielādējot šo datu momentuzņēmumu mūsu lietojumprogrammas sākumā. Pēc tam mēs varam saņemt atjauninājumu notikumus, lai nodrošinātu, ka kešatmiņā saglabātie dati paliek sinhronizēti ar avotu. Izmantojot šo metodi, mēs uzlabojam uzticamību piekļūt šiem svarīgajiem datiem, jo katra izguve notiek tieši no atmiņas ar 0% kļūdas iespējamību. Turklāt datu izgūšana no atmiņas ir ārkārtīgi ātra, tādējādi optimizējot mūsu lietojumprogrammas veiktspēju. Šī stratēģija efektīvi mazina risku, kas saistīts ar paļaušanos uz ārēju datu avotu, nodrošinot konsekventu un uzticamu piekļuvi mūsu lietojumprogrammas darbībai svarīgai informācijai.
Tomēr nepieciešamība lejupielādēt datus par lietojumprogrammas palaišanu, tādējādi aizkavējot startēšanas procesu, pārkāpj vienu no “12 faktoru lietojumprogrammas” principiem, kas atbalsta ātru lietojumprogrammas palaišanu. Taču mēs nevēlamies zaudēt kešatmiņas izmantošanas priekšrocības. Lai risinātu šo dilemmu, izpētīsim iespējamos risinājumus.
Ātra palaišana ir ļoti svarīga, jo īpaši tādām platformām kā Kubernetes, kas paļaujas uz ātru lietojumprogrammu migrāciju uz dažādiem fiziskiem mezgliem. Par laimi, Kubernetes var pārvaldīt lēni startējošas lietojumprogrammas, izmantojot tādas funkcijas kā startēšanas zondes.
Vēl viens izaicinājums, ar kuru mēs varam saskarties, ir konfigurāciju atjaunināšana lietojumprogrammas darbības laikā. Bieži vien ir jāpielāgo kešatmiņas laiki vai pieprasījuma noildzes, lai atrisinātu ražošanas problēmas. Pat ja mēs varam ātri izvietot atjauninātos konfigurācijas failus savā lietojumprogrammā, šo izmaiņu piemērošanai parasti ir nepieciešama restartēšana. Pagarinot katras lietojumprogrammas palaišanas laiku, nepārtraukta restartēšana var ievērojami aizkavēt labojumu izvietošanu mūsu lietotājiem.
Lai to novērstu, viens no risinājumiem ir saglabāt konfigurācijas vienlaicīgā mainīgajā un periodiski to atjaunināt fona pavedienam. Tomēr noteiktiem parametriem, piemēram, HTTP pieprasījuma noildzei, var būt nepieciešams atkārtoti inicializēt HTTP vai datu bāzes klientus, kad mainās atbilstošā konfigurācija, radot potenciālu izaicinājumu. Tomēr daži klienti, piemēram, Java draiveris Cassandra, atbalsta automātisku konfigurāciju pārlādēšanu, vienkāršojot šo procesu.
Atkārtoti ielādējamu konfigurāciju ieviešana var mazināt ilgā lietojumprogrammas palaišanas laika negatīvo ietekmi un piedāvāt papildu priekšrocības, piemēram, atvieglot funkciju karoga ieviešanu. Šī pieeja ļauj mums saglabāt lietojumprogrammu uzticamību un atsaucību, vienlaikus efektīvi pārvaldot konfigurācijas atjauninājumus.
Tagad apskatīsim citu problēmu: mūsu sistēmā, kad tiek saņemts un apstrādāts lietotāja pieprasījums, nosūtot vaicājumu uz aizmugursistēmu vai datu bāzi, reizēm gaidīto datu vietā tiek saņemta kļūdas atbilde. Pēc tam mūsu sistēma lietotājam atbild ar “kļūdu”.
Tomēr daudzos gadījumos var būt labāk parādīt nedaudz novecojušus datus kopā ar ziņojumu, kas norāda uz datu atsvaidzināšanas aizkavi, nevis atstāt lietotājam lielu sarkanu kļūdas ziņojumu.
Lai atrisinātu šo problēmu un uzlabotu mūsu sistēmas darbību, mēs varam ieviest atkāpšanās modeli. Šī modeļa pamatā ir sekundāra datu avota izveide, kurā var būt zemākas kvalitātes vai jaunākas kvalitātes dati, salīdzinot ar primāro avotu. Ja primārais datu avots nav pieejams vai atgriež kļūdu, sistēma var atgriezties pie datu izgūšanas no šī sekundārā avota, nodrošinot, ka lietotājam tiek parādīta kāda veida informācija, nevis tiek parādīts kļūdas ziņojums.
Ja skatāties uz iepriekš redzamo attēlu, pamanīsit līdzību starp problēmu, ar kuru pašlaik saskaramies, un problēmu, ar kuru mēs saskārāmies ar kešatmiņas piemēru.
Lai to atrisinātu, mēs varam apsvērt modeļa ieviešanu, kas pazīstams kā atkārtots mēģinājums. Tā vietā, lai paļautos uz kešatmiņām, sistēmu var izveidot tā, lai kļūdas gadījumā automātiski atkārtoti nosūtītu pieprasījumu. Šis atkārtotā mēģinājuma modelis piedāvā vienkāršāku alternatīvu un var efektīvi samazināt kļūdu iespējamību mūsu lietojumprogrammā. Atšķirībā no kešatmiņas, kurā bieži ir nepieciešami sarežģīti kešatmiņas nederīguma mehānismi, lai apstrādātu datu izmaiņas, neveiksmīgu pieprasījumu atkārtota mēģinājuma ieviešana ir samērā vienkārša. Tā kā kešatmiņas anulēšana tiek plaši uzskatīta par vienu no sarežģītākajiem programmatūras inženierijas uzdevumiem, atkārtotas mēģinājuma stratēģijas pieņemšana var racionalizēt kļūdu apstrādi un uzlabot sistēmas noturību.
Tomēr atkārtotas mēģinājuma stratēģijas pieņemšana, neņemot vērā iespējamās sekas, var radīt papildu sarežģījumus.
Iedomāsimies, ka kāds no mūsu aizmugure piedzīvo neveiksmi. Šādā gadījumā, uzsākot atkārtotus mēģinājumus uz neveiksmīgo aizmugursistēmu, var ievērojami palielināties trafika apjoms. Šis pēkšņais trafika pieaugums var nomākt aizmugursistēmu, saasinot kļūmi un, iespējams, izraisot kaskādes efektu visā sistēmā.
Lai tiktu galā ar šo izaicinājumu, ir svarīgi papildināt atkārtotā mēģinājuma shēmu ar ķēdes pārtraucēja shēmu. Strāvas slēdzis kalpo kā drošības mehānisms, kas uzrauga pakārtoto pakalpojumu kļūdu līmeni. Kad kļūdu līmenis pārsniedz iepriekš noteiktu slieksni, ķēdes pārtraucējs uz noteiktu laiku pārtrauc pieprasījumus ietekmētajam pakalpojumam. Šajā periodā sistēma atturas no papildu pieprasījumu sūtīšanas, lai ļautu atjaunoties neveiksmīgajam pakalpojumam. Pēc noteiktā intervāla ķēdes pārtraucējs piesardzīgi pieļauj ierobežotu pieprasījumu skaitu, pārbaudot, vai pakalpojums ir stabilizējies. Ja pakalpojums ir atjaunojies, pamazām tiek atjaunota normāla satiksme; pretējā gadījumā ķēde paliek atvērta, turpinot bloķēt pieprasījumus, līdz pakalpojums atsāk normālu darbību. Integrējot ķēdes pārtraucēju modeli kopā ar atkārtota mēģinājuma loģiku, mēs varam efektīvi pārvaldīt kļūdu situācijas un novērst sistēmas pārslodzi aizmugursistēmas kļūmju laikā.
Visbeidzot, ieviešot šos noturības modeļus, mēs varam stiprināt savas lietojumprogrammas pret ārkārtas situācijām, uzturēt augstu pieejamību un nodrošināt lietotājiem nevainojamu pieredzi. Turklāt es vēlos uzsvērt, ka telemetrija ir vēl viens rīks, kuru nevajadzētu aizmirst, nodrošinot projekta noturību. Labi žurnāli un metrika var ievērojami uzlabot pakalpojumu kvalitāti un sniegt vērtīgu ieskatu to darbībā, palīdzot pieņemt pārdomātus lēmumus, lai tos vēl vairāk uzlabotu.