Principes voor het ontwikkelen van moderne applicaties vanuit NGINX. Deel 1

Hallo vrienden. In afwachting van de lancering van de cursus PHP-backend-ontwikkelaar, traditioneel de vertaling van nuttig materiaal met u delen.

Software lost steeds meer alledaagse taken op, terwijl ze steeds complexer worden. Zoals Marc Andressen ooit zei, het verteert de wereld.

Principes voor het ontwikkelen van moderne applicaties vanuit NGINX. Deel 1

Als gevolg hiervan is de manier waarop applicaties worden ontwikkeld en geleverd de afgelopen jaren ingrijpend veranderd. Dit waren verschuivingen van tektonische schaal die resulteerden in een reeks principes. Deze principes hebben bewezen nuttig te zijn bij teambuilding, ontwerpen, ontwikkelen en leveren van uw applicatie aan eindgebruikers.

De principes kunnen als volgt worden samengevat: de applicatie moet klein zijn, webgebaseerd en een op ontwikkelaars gerichte architectuur hebben. Met deze drie principes in gedachten kunt u een robuuste, end-to-end-applicatie maken die snel en veilig aan de eindgebruiker kan worden geleverd en die eenvoudig schaalbaar en uitbreidbaar is.

Principes voor het ontwikkelen van moderne applicaties vanuit NGINX. Deel 1

Elk van de voorgestelde principes heeft een aantal aspecten die we zullen bespreken om te laten zien hoe elk principe bijdraagt ​​aan het uiteindelijke doel, namelijk de snelle levering van betrouwbare applicaties die gemakkelijk te onderhouden en te gebruiken zijn. We zullen de principes bekijken in relatie tot hun tegengestelden om te verduidelijken wat het betekent, zeg: "Zorg ervoor dat u kleinheidsprincipe.

We hopen dat dit artikel u zal aanmoedigen om de voorgestelde principes te gebruiken voor het bouwen van moderne applicaties, die een uniforme benadering van ontwerp zullen bieden in de context van een steeds groter wordende technologiestapel.

Door deze principes toe te passen, profiteert u van de nieuwste trends in softwareontwikkeling, waaronder de DevOps tot het ontwikkelen en opleveren van applicaties, het gebruik van containers (bijvoorbeeld havenarbeider) en containerorkestratieframeworks (bijvoorbeeld Kubernetes), het gebruik van microservices (waaronder de Microservice Architecture NGINX и architectuur voor netwerkcommunicatie voor microservice-applicaties.

Wat is een moderne applicatie?

Moderne toepassingen? Moderne stapel? Wat betekent 'modern' precies?

De meeste ontwikkelaars hebben slechts een algemeen idee van waar een moderne applicatie uit bestaat, dus het is noodzakelijk om dit concept duidelijk te definiëren.

Een moderne app ondersteunt meerdere clients, of het nu gaat om een ​​React JavaScript-bibliotheekgebruikersinterface, een mobiele Android- of iOS-app of een app die verbinding maakt met een andere API. Een moderne applicatie impliceert een onbepaald aantal klanten waarvoor het gegevens of diensten levert.

Een moderne applicatie biedt een API om toegang te krijgen tot de gevraagde gegevens en services. De API moet onveranderlijk en constant zijn en niet specifiek geschreven voor een specifiek verzoek van een specifieke klant. De API is beschikbaar via HTTP(S) en biedt toegang tot alle functionaliteit die beschikbaar is in de GUI of CLI.

De gegevens moeten beschikbaar zijn in een algemeen geaccepteerd, interoperabel formaat zoals JSON. Een API stelt objecten en services op een schone, georganiseerde manier bloot, zoals RESTful API of GraphQL een fatsoenlijke interface bieden.

Moderne applicaties zijn gebouwd op de moderne stack en de moderne stack is de stack die dergelijke applicaties ondersteunt. Met deze stack kan een ontwikkelaar eenvoudig een applicatie maken met een HTTP-interface en duidelijke API-eindpunten. Door de gekozen aanpak kan uw applicatie eenvoudig gegevens in JSON-formaat ontvangen en verzenden. Met andere woorden, de moderne stapel komt overeen met de elementen van de Twelve-Factor Application for microservices.

Populaire versies van dit type stapel zijn gebaseerd op Java, Python, Knooppunt, Ruby, PHP и Go. Microservice-architectuur NGINX vertegenwoordigt een voorbeeld van een moderne stapel geïmplementeerd in elk van de genoemde talen.

Houd er rekening mee dat we geen voorstander zijn van een uitsluitend microservicebenadering. Velen van jullie werken met monolieten die moeten evolueren, terwijl anderen te maken hebben met SOA-applicaties die zich uitbreiden en evolueren tot microservice-applicaties. Weer anderen evolueren naar serverloze applicaties, en sommigen implementeren combinaties van het bovenstaande. De principes die in het artikel worden beschreven, zijn van toepassing op elk van deze systemen met slechts een paar kleine aanpassingen.

Principes

Nu we een gemeenschappelijk begrip hebben van wat een moderne applicatie en moderne stack zijn, is het tijd om in de architectuur en ontwikkelingsprincipes te duiken die u goed van pas zullen komen bij het ontwikkelen, implementeren en onderhouden van een moderne applicatie.

Een van de principes klinkt als "maak kleine applicaties", laten we het maar noemen kleinheidsprincipe. Er zijn ongelooflijk complexe applicaties die uit veel bewegende delen bestaan. Op zijn beurt maakt het bouwen van een applicatie uit kleine, afzonderlijke componenten het gemakkelijker om het als geheel te ontwerpen, te onderhouden en ermee te werken. (Merk op dat we zeiden "vereenvoudigt" niet "maakt eenvoudig").

Het tweede principe is dat we de productiviteit van ontwikkelaars kunnen verhogen door hen te helpen zich te concentreren op de functies die ze aan het ontwikkelen zijn, terwijl ze tijdens de implementatie worden bevrijd van zorgen over infrastructuur en CI/CD. Dus in een notendop onze aanpak gericht op ontwikkelaars.

Tot slot moet alles aan uw applicatie verbonden zijn met het netwerk. In de afgelopen 20 jaar hebben we grote stappen gezet in de richting van een netwerktoekomst naarmate netwerken sneller worden en toepassingen complexer. Zoals we hebben gezien, moet een moderne applicatie door veel verschillende clients over een netwerk worden gebruikt. Het toepassen van netwerkdenken op architectuur heeft aanzienlijke voordelen die daar goed bij passen kleinheidsprincipe en het concept van de aanpak, ontwikkelaar gericht.

Als u deze principes in gedachten houdt bij het ontwerpen en implementeren van een applicatie, heeft u een onmiskenbaar voordeel bij de ontwikkeling en levering van uw product.

Laten we deze drie principes in meer detail bekijken.

Kleinheidsprincipe

Het is voor het menselijk brein moeilijk om een ​​grote hoeveelheid informatie tegelijkertijd waar te nemen. In de psychologie verwijst de term cognitieve belasting naar de totale hoeveelheid mentale inspanning die nodig is om informatie in het geheugen vast te houden. Het verminderen van de cognitieve belasting van ontwikkelaars is een prioriteit omdat ze zich hierdoor kunnen concentreren op het oplossen van het probleem in plaats van het huidige complexe model van de hele applicatie en de functies die worden ontwikkeld in hun hoofd te houden.

Principes voor het ontwikkelen van moderne applicaties vanuit NGINX. Deel 1

Toepassingen worden afgebroken om de volgende redenen:

  • Verminderde cognitieve belasting van ontwikkelaars;
  • Versnelling en vereenvoudiging van testen;
  • Snelle levering van wijzigingen in de applicatie.


Er zijn verschillende manieren om de cognitieve belasting van ontwikkelaars te verminderen, en hier komt het principe van kleinheid om de hoek kijken.

Dus hier zijn drie manieren om de cognitieve belasting te verminderen:

  1. Verminder het tijdsbestek waarmee ze rekening moeten houden bij het ontwikkelen van een nieuwe functie: hoe korter het tijdsbestek, hoe lager de cognitieve belasting.
  2. Verminder de hoeveelheid code waaraan eenmalig werk wordt uitgevoerd - minder code - minder belasting.
  3. Vereenvoudig het proces van het aanbrengen van incrementele wijzigingen in een applicatie.

Het verkorten van de ontwikkeltijd

Laten we teruggaan naar de tijd dat de methodologie waterfall was de standaard voor het ontwikkelingsproces en termijnen van zes maanden tot twee jaar voor het ontwikkelen of updaten van een applicatie waren gebruikelijk. Doorgaans lazen ingenieurs eerst relevante documenten, zoals de productvereisten (PRD), het systeemreferentiedocument (SRD), de architectuurblauwdruk, en begonnen al deze dingen samen te voegen tot één cognitief model, op basis waarvan ze codeerden. Naarmate de vereisten en bijgevolg de architectuur veranderden, moest er een serieuze inspanning worden geleverd om het hele team te informeren over updates van het cognitieve model. Een dergelijke aanpak zou in het slechtste geval het werk eenvoudig kunnen verlammen.

De grootste verandering in het applicatie-ontwikkelproces was de introductie van de agile-methodiek. Een van de belangrijkste kenmerken van de methodiek agile is een iteratieve ontwikkeling. Dit leidt op zijn beurt tot een vermindering van de cognitieve belasting van ingenieurs. In plaats van van het ontwikkelteam te eisen dat het de applicatie in één lange cyclus implementeert, agile aanpak stelt u in staat zich te concentreren op kleine hoeveelheden code die snel kunnen worden getest en geïmplementeerd, terwijl u ook feedback ontvangt. De cognitieve belasting van de app is verschoven van een tijdsbestek van zes maanden naar twee jaar met een enorm aantal specificaties voor een toevoeging of functiewijziging van twee weken, gericht op een waziger begrip van een grote app.

De focus verleggen van een enorme applicatie naar specifieke kleine functies die in een sprint van twee weken kunnen worden voltooid, met niet meer dan één functie voor de volgende sprint in gedachten, is een belangrijke verandering. Hierdoor konden we de ontwikkelingsproductiviteit verhogen en tegelijkertijd de cognitieve belasting, die voortdurend fluctueerde, verminderen.

Bij methodiek agile de uiteindelijke toepassing zal naar verwachting een enigszins gewijzigde versie van het oorspronkelijke concept zijn, dus het eindpunt van de ontwikkeling is noodzakelijkerwijs dubbelzinnig. Alleen de resultaten van elke specifieke sprint kunnen duidelijk en nauwkeurig zijn.

Kleine codebases

De volgende stap in het verminderen van de cognitieve belasting is het verkleinen van de codebasis. Moderne applicaties zijn over het algemeen enorm - een robuuste bedrijfsapplicatie kan uit duizenden bestanden en honderdduizenden regels code bestaan. Afhankelijk van hoe de bestanden zijn georganiseerd, kunnen koppelingen en afhankelijkheden tussen code en bestanden voor de hand liggen, of vice versa. Zelfs het uitvoeren van foutopsporingscode zelf kan problematisch zijn, afhankelijk van de gebruikte bibliotheken en hoe goed de hulpprogramma's voor foutopsporing onderscheid maken tussen bibliotheken/pakketten/modules en aangepaste code.

Het bouwen van een werkend mentaal model van de code van een applicatie kan een indrukwekkende hoeveelheid tijd in beslag nemen en opnieuw een grote cognitieve last op de ontwikkelaar leggen. Dit geldt met name voor monolithische codebases, waar een grote hoeveelheid code is, waarvan de interactie tussen de functionele componenten niet duidelijk is gedefinieerd, en de scheiding van aandachtsobjecten vaak vervaagd is omdat functionele grenzen niet worden gerespecteerd.

Een van de effectieve manieren om de cognitieve belasting van ingenieurs te verminderen, is door over te stappen op een microservice-architectuur. In een microservicebenadering richt elke service zich op één set functies; terwijl de betekenis van de service meestal gedefinieerd en begrijpelijk is. De grenzen van een service zijn ook duidelijk - onthoud dat de communicatie met een service via een API verloopt, dus gegevens die door de ene service worden gegenereerd, kunnen gemakkelijk worden doorgegeven aan een andere.

Interactie met andere services is meestal beperkt tot enkele gebruikersservices en enkele providerservices die gebruikmaken van eenvoudige en schone API-aanroepen, zoals het gebruik van REST. Dit betekent dat de cognitieve belasting van de ingenieur ernstig wordt verminderd. De grootste uitdaging blijft het begrijpen van het service-interactiemodel en hoe zaken als transacties tussen meerdere services plaatsvinden. Als gevolg hiervan vermindert het gebruik van microservices de cognitieve belasting door de hoeveelheid code te verminderen, duidelijke servicegrenzen te definiëren en inzicht te bieden in de relatie tussen gebruikers en providers.

Kleine stapsgewijze veranderingen

Het laatste element van het principe kleinheid is verandermanagement. Het is een bijzondere verleiding voor ontwikkelaars om naar de codebasis te kijken (misschien zelfs hun eigen, oudere code) en te zeggen: "Dit is onzin, we moeten het allemaal herschrijven." Soms is dit de juiste beslissing, en soms ook niet. Het legt de last van wereldwijde modelverandering op het ontwikkelingsteam, wat op zijn beurt leidt tot een enorme cognitieve belasting. Het is voor engineers beter om te focussen op de veranderingen die ze tijdens de sprint kunnen doorvoeren, zodat ze de benodigde functionaliteit tijdig, zij het geleidelijk, kunnen uitrollen. Het uiteindelijke product moet lijken op het vooraf geplande product, maar met enkele aanpassingen en testen om aan de behoeften van de klant te voldoen.

Bij het herschrijven van grote delen code is het soms niet mogelijk om de wijziging snel door te voeren omdat andere systeemafhankelijkheden een rol gaan spelen. Om de stroom van wijzigingen te beheersen, kunt u functies verbergen. In principe betekent dit dat de functionaliteit in productie is, maar niet beschikbaar is via de omgevingsvariabele-instellingen (env-var) of een ander configuratiemechanisme. Als de code alle kwaliteitscontroleprocessen heeft doorstaan, kan deze in latente toestand in productie terechtkomen. Deze strategie werkt echter alleen als de functie uiteindelijk wordt ingeschakeld. Anders zal het de code alleen maar rommeliger maken en een cognitieve belasting toevoegen waarmee de ontwikkelaar te maken krijgt om productief te zijn. Wijzigingsbeheer en incrementele wijzigingen zelf helpen de cognitieve belasting van ontwikkelaars op een betaalbaar niveau te houden.

Ingenieurs moeten veel moeilijkheden overwinnen, zelfs met de eenvoudige introductie van extra functionaliteit. Van de kant van het management zou het verstandig zijn om de onnodige belasting van het team te verminderen, zodat het zich kan concentreren op de belangrijkste functionele elementen. Er zijn drie dingen die u kunt doen om uw ontwikkelteam te helpen:

  1. Gebruik methodologie agileom het tijdsbestek te beperken waarin het team zich moet concentreren op de belangrijkste functies.
  2. Implementeer uw applicatie als meerdere microservices. Dit beperkt het aantal functies dat kan worden geïmplementeerd en versterkt de grenzen die de cognitieve belasting aan het werk houden.
  3. Geef de voorkeur aan incrementele wijzigingen boven grote en logge, verander kleine stukjes code. Gebruik het verbergen van functies om wijzigingen door te voeren, zelfs als ze niet direct zichtbaar zijn nadat ze zijn toegevoegd.

Als je het principe van kleinheid toepast in je werk, zal je team veel gelukkiger zijn, beter gefocust zijn op het implementeren van de noodzakelijke functies en is de kans groter dat kwalitatieve veranderingen sneller worden uitgerold. Maar dit betekent niet dat het werk niet ingewikkelder kan worden, integendeel, de introductie van nieuwe functionaliteit vereist de aanpassing van verschillende services, en dit proces kan moeilijker zijn dan vergelijkbaar in een monolithische architectuur. In ieder geval zijn de voordelen van de kleinschaligheidsbenadering de moeite waard.

Einde van het eerste deel.

Binnenkort zullen we het tweede deel van de vertaling publiceren, en nu wachten we op uw commentaar en nodigen u uit om dat te doen Open dag, die vandaag om 20.00 uur plaatsvindt.

Bron: www.habr.com

Voeg een reactie