Prinsipper for utvikling av moderne applikasjoner fra NGINX. Del 1

Hei venner. I påvente av lansering av kurset PHP backend-utvikler, tradisjonelt dele med deg oversettelsen av nyttig materiale.

Programvare løser stadig flere hverdagslige oppgaver, samtidig som den blir mer og mer kompleks. Som Marc Andressen sa en gang, den fortærer verden.

Prinsipper for utvikling av moderne applikasjoner fra NGINX. Del 1

Som et resultat har måten applikasjoner utvikles og leveres på endret seg dramatisk de siste årene. Dette var forskyvninger av tektonisk skala som resulterte i et sett med prinsipper. Disse prinsippene har vist seg å være nyttige i teambygging, design, utvikling og levering av applikasjonen din til sluttbrukere.

Prinsippene kan oppsummeres som følger: applikasjonen skal være liten, nettbasert og ha en utviklersentrisk arkitektur. Med disse tre prinsippene i tankene kan du lage en robust, ende-til-ende-applikasjon som raskt og sikkert kan leveres til sluttbrukeren, og som enkelt kan skaleres og utvides.

Prinsipper for utvikling av moderne applikasjoner fra NGINX. Del 1

Hvert av de foreslåtte prinsippene har en rekke aspekter som vi vil diskutere for å vise hvordan hvert prinsipp bidrar til det endelige målet, som er rask levering av pålitelige applikasjoner som er enkle å vedlikeholde og bruke. Vi vil se på prinsippene i forhold til deres motsetninger for å klargjøre hva det betyr, si: "Sørg for at du bruker litenhetsprinsippet'.

Vi håper at denne artikkelen vil oppmuntre deg til å bruke de foreslåtte prinsippene for å bygge moderne applikasjoner, som vil gi en enhetlig tilnærming til design i sammenheng med en stadig voksende teknologistabel.

Ved å bruke disse prinsippene vil du finne deg selv å dra nytte av de siste trendene innen programvareutvikling, inkludert DevOps til utvikling og levering av applikasjoner, bruk av containere (f.eks. Docker) og containerorkestreringsrammer (f.eks. Kubernetes), bruken av mikrotjenester (inkludert Microservice Architecture Nginx и nettverkskommunikasjonsarkitektur for mikrotjenesteapplikasjoner.

Hva er en moderne applikasjon?

Moderne applikasjoner? Moderne stabel? Hva betyr egentlig "moderne"?

De fleste utviklere har bare en generell ide om hva en moderne applikasjon består av, så det er nødvendig å tydelig definere dette konseptet.

En moderne app støtter flere klienter, enten det er et React JavaScript-biblioteks brukergrensesnitt, en Android- eller iOS-mobilapp, eller en app som kobles til et annet API. En moderne applikasjon innebærer et ubestemt antall klienter som den leverer data eller tjenester for.

En moderne applikasjon gir en API for å få tilgang til de forespurte dataene og tjenestene. API-en skal være uforanderlig og konstant, og ikke skrevet spesifikt for en spesifikk forespørsel fra en spesifikk klient. API-en er tilgjengelig over HTTP(S) og gir tilgang til all funksjonalitet som er tilgjengelig i GUI eller CLI.

Dataene må være tilgjengelige i et allment akseptert, interoperabelt format som JSON. En API eksponerer objekter og tjenester på en ren, organisert måte, som RESTful API eller GraphQL gir et anstendig grensesnitt.

Moderne applikasjoner er bygget på den moderne stacken, og den moderne stacken er stabelen som støtter slike applikasjoner, henholdsvis. Denne stabelen lar en utvikler enkelt lage en applikasjon med et HTTP-grensesnitt og klare API-endepunkter. Den valgte tilnærmingen lar applikasjonen din enkelt motta og sende data i JSON-format. Med andre ord tilsvarer den moderne stabelen elementene i Tolv-Factor Application for mikrotjenester.

Populære versjoner av denne typen stabel er basert på Java, Python, Node, Rubin, PHP и Go. Mikrotjenestearkitektur Nginx representerer et eksempel på en moderne stabel implementert på hvert av de nevnte språkene.

Vær oppmerksom på at vi ikke tar til orde for en eksklusiv mikrotjenestetilnærming. Mange av dere jobber med monolitter som trenger å utvikle seg, mens andre har å gjøre med SOA-applikasjoner som utvides og utvikler seg til å bli mikrotjenesteapplikasjoner. Atter andre beveger seg mot serverløse applikasjoner, og noen implementerer kombinasjoner av det ovennevnte. Prinsippene som er skissert i artikkelen gjelder for hvert av disse systemene med bare noen få mindre modifikasjoner.

Prinsipper

Nå som vi har en felles forståelse av hva en moderne applikasjon og moderne stack er, er det på tide å dykke ned i arkitekturen og utviklingsprinsippene som vil tjene deg godt i å utvikle, implementere og vedlikeholde en moderne applikasjon.

Et av prinsippene høres ut som «lag små søknader», la oss bare kalle det litenhetsprinsippet. Det er utrolig komplekse applikasjoner som består av mange bevegelige deler. Å bygge en applikasjon fra små, diskrete komponenter gjør det i sin tur enklere å designe, vedlikeholde og jobbe med det som helhet. (Merk at vi sa "forenkler" ikke "gjør enkelt").

Det andre prinsippet er at vi kan øke utviklerproduktiviteten ved å hjelpe dem med å fokusere på funksjonene de utvikler, samtidig som vi frigjør dem fra infrastruktur og CI/CD-problemer under implementering. Så, i et nøtteskall, vår tilnærming fokusert på utviklere.

Til slutt må alt om applikasjonen din være koblet til nettverket. I løpet av de siste 20 årene har vi tatt store fremskritt mot en nettverksbasert fremtid ettersom nettverk blir raskere og applikasjoner mer komplekse. Som vi allerede har sett, må en moderne applikasjon brukes over et nettverk av mange forskjellige klienter. Å bruke nettverkstenkning på arkitektur har betydelige fordeler som passer godt med litenhetsprinsippet og konseptet med tilnærmingen, utviklerorientert.

Hvis du har disse prinsippene i bakhodet når du designer og implementerer en applikasjon, vil du ha en ubestridelig fordel i utviklingen og leveringen av produktet ditt.

La oss se på disse tre prinsippene mer detaljert.

Litenhetsprinsippet

Det er vanskelig for den menneskelige hjernen å oppfatte en stor mengde informasjon samtidig. I psykologi refererer begrepet kognitiv belastning til den totale mengden mental innsats som kreves for å beholde informasjon i minnet. Å redusere den kognitive belastningen på utviklere er en prioritet fordi det lar dem fokusere på å løse problemet i stedet for å beholde den nåværende komplekse modellen av hele applikasjonen og funksjonene som utvikles i hodet.

Prinsipper for utvikling av moderne applikasjoner fra NGINX. Del 1

Applikasjoner dekomponeres av følgende årsaker:

  • Redusert kognitiv belastning på utviklere;
  • Akselerasjon og forenkling av testing;
  • Rask levering av endringer i applikasjonen.


Det er flere måter å redusere den kognitive belastningen på utviklere, og det er her prinsippet om litenhet spiller inn.

Så her er tre måter å redusere kognitiv belastning på:

  1. Reduser tidsrammen de må vurdere når de utvikler en ny funksjon – jo kortere tidsrammen, desto lavere er kognitiv belastning.
  2. Reduser mengden kode som det utføres engangsarbeid på - mindre kode - mindre belastning.
  3. Forenkle prosessen med å gjøre trinnvise endringer i en applikasjon.

Redusere tidsrammen for utvikling

La oss gå tilbake til tiden da metodikken waterfall var standarden for utviklingsprosessen, og tidsrammer på seks måneder til to år for å utvikle eller oppdatere en applikasjon var vanlig praksis. Vanligvis vil ingeniører først lese relevante dokumenter som produktkravene (PRD), systemreferansedokumentet (SRD), arkitekturplanen, og begynne å kombinere alle disse tingene sammen til én kognitiv modell, som de kodet i henhold til. Ettersom kravene og følgelig arkitekturen endret seg, måtte det gjøres en seriøs innsats for å informere hele teamet om oppdateringer av den kognitive modellen. En slik tilnærming kan i verste fall rett og slett lamme arbeidet.

Den største endringen i applikasjonsutviklingsprosessen var introduksjonen av den smidige metodikken. En av hovedtrekkene i metodikken agile er en iterativ utvikling. Dette fører igjen til en reduksjon i den kognitive belastningen på ingeniører. I stedet for å kreve at utviklingsteamet implementerer applikasjonen i en lang syklus, agile tilnærming lar deg fokusere på små mengder kode som raskt kan testes og distribueres, samtidig som du får tilbakemelding. Appens kognitive belastning har endret seg fra en seks måneders til to-års tidsramme med en enorm mengde spesifikasjoner for en to-ukers tillegg eller funksjonsendring rettet mot en mer uskarp forståelse av en stor app.

Å skifte fokus fra en massiv applikasjon til spesifikke små funksjoner som kan fullføres i en to-ukers sprint, med ikke mer enn én funksjon foran neste sprint i tankene, er en betydelig endring. Dette tillot oss å øke utviklingsproduktiviteten samtidig som vi reduserte den kognitive belastningen, som stadig svingte.

I metodikk agile den endelige applikasjonen forventes å være en litt modifisert versjon av det opprinnelige konseptet, så sluttpunktet for utviklingen er nødvendigvis tvetydig. Bare resultatene av hver spesifikke sprint kan være klare og presise.

Små kodebaser

Det neste trinnet i å redusere kognitiv belastning er å redusere kodebasen. Som regel er moderne applikasjoner massive - en robust bedriftsapplikasjon kan bestå av tusenvis av filer og hundretusenvis av kodelinjer. Avhengig av hvordan filene er organisert, kan koblinger og avhengigheter mellom kode og filer være åpenbare, eller omvendt. Selv kjøring av feilsøkingskode kan være problematisk, avhengig av bibliotekene som brukes og hvor godt feilsøkingsverktøyene skiller mellom biblioteker/pakker/moduler og tilpasset kode.

Å bygge en fungerende mental modell av en applikasjons kode kan ta imponerende lang tid, og igjen legge en stor kognitiv belastning på utvikleren. Dette gjelder spesielt for monolittiske kodebaser, der det er en stor mengde kode, hvor interaksjonen mellom funksjonskomponentene ikke er klart definert, og separasjonen av oppmerksomhetsobjekter er ofte uskarp fordi funksjonelle grenser ikke respekteres.

En av de effektive måtene å redusere den kognitive belastningen på ingeniører er å gå over til en mikrotjenestearkitektur. I en mikroservice-tilnærming fokuserer hver tjeneste på ett sett med funksjoner; mens betydningen av tjenesten vanligvis er definert og forståelig. Grensene til en tjeneste er også klare – husk at kommunikasjon med en tjeneste skjer via et API, slik at data generert av en tjeneste enkelt kan overføres til en annen.

Interaksjon med andre tjenester er vanligvis begrenset til noen få brukertjenester og noen få leverandørtjenester som bruker enkle og rene API-kall, for eksempel bruk av REST. Dette betyr at den kognitive belastningen på ingeniøren reduseres alvorlig. Den største utfordringen er fortsatt å forstå tjenesteinteraksjonsmodellen og hvordan ting som transaksjoner skjer på tvers av flere tjenester. Som et resultat reduserer bruken av mikrotjenester kognitiv belastning ved å redusere mengden kode, definere klare tjenestegrenser og gi en forståelse av forholdet mellom brukere og leverandører.

Små inkrementelle endringer

Det siste elementet i prinsippet litenhet er endringsledelse. Det er en spesiell fristelse for utviklere å se på kodebasen (til og med kanskje deres egen, eldre kode) og si: "Dette er dritt, vi må skrive om alt." Noen ganger er dette den riktige avgjørelsen, og noen ganger ikke. Det legger byrden med global modellendring på utviklingsteamet, noe som igjen fører til massiv kognitiv belastning. Det er bedre for ingeniører å fokusere på endringene de kan gjøre i løpet av sprinten, slik at de kan rulle ut den nødvendige funksjonaliteten i tide, om enn gradvis. Sluttproduktet skal ligne det forhåndsplanlagte, men med noen modifikasjoner og testing for å passe kundens behov.

Når du skriver om store deler av koden, er det noen ganger ikke mulig å raskt levere endringen fordi andre systemavhengigheter spiller inn. For å kontrollere flyten av endringer, kan du bruke funksjonsskjuling. I prinsippet betyr dette at funksjonaliteten er i produksjon, men den er ikke tilgjengelig ved bruk av miljøvariabelinnstillingene (env-var) eller en annen konfigurasjonsmekanisme. Hvis koden har bestått alle kvalitetskontrollprosessene, kan den havne i produksjon i latent tilstand. Denne strategien fungerer imidlertid bare hvis funksjonen til slutt blir aktivert. Ellers vil det bare rote opp koden og legge til en kognitiv belastning som utvikleren må håndtere for å være produktiv. Endringshåndtering og trinnvise endringer bidrar i seg selv til å holde utviklernes kognitive belastning på et rimelig nivå.

Ingeniører må overvinne mange vanskeligheter selv med den enkle introduksjonen av tilleggsfunksjonalitet. Fra ledelsens side vil det være fornuftig å redusere den unødvendige belastningen på teamet slik at det kan fokusere på sentrale funksjonelle elementer. Det er tre ting du kan gjøre for å hjelpe utviklingsteamet ditt:

  1. Bruk metodikk agileå begrense tidsrammen der teamet må fokusere på nøkkelfunksjoner.
  2. Implementer applikasjonen din som flere mikrotjenester. Dette vil begrense antallet funksjoner som kan implementeres og forsterke grensene som holder den kognitive belastningen i arbeid.
  3. Foretrekk inkrementelle endringer fremfor store og uhåndterlige, endre små biter av kode. Bruk funksjonsskjul for å implementere endringer selv om de ikke vil være synlige umiddelbart etter at de er lagt til.

Hvis du bruker prinsippet om litenhet i arbeidet ditt, vil teamet ditt bli mye lykkeligere, bedre fokusert på å implementere de nødvendige funksjonene og mer sannsynlig å rulle ut kvalitative endringer raskere. Men dette betyr ikke at arbeidet ikke kan bli mer komplisert, noen ganger, tvert imot, krever introduksjonen av ny funksjonalitet modifikasjon av flere tjenester, og denne prosessen kan være vanskeligere enn tilsvarende i en monolitisk arkitektur. I alle fall er fordelene ved å ta småhetstilnærmingen verdt det.

Slutt på første del.

Snart vil vi publisere den andre delen av oversettelsen, og nå venter vi på dine kommentarer og inviterer deg til Åpen dag, som finner sted i dag kl 20.00.

Kilde: www.habr.com

Legg til en kommentar