NodeJS: Best Practices voor productie

Dit is een poging om de belangrijkste methoden in te schakelen voor het ontwikkelen en implementeren op NodeJ's.

Ik werk zelf al een tijdje aan deze technologie. Ik realiseer me zijn enorme potentieel en plaats in het ontwikkelingsproces. Met zware concurrentie van talen als Python en Golang heeft NodeJS zijn nut bewezen in geschikte gebruiksgevallen.

Voordat ik inga op de best practices , wil ik eerst een korte inleiding geven over wat een microservicepatroon is. Ga daarna verder met het gesprek.

Wat zijn microservices?

Microservices - ook bekend als de microservice-architectuur - is een architecturale stijl die een applicatie structureert als een verzameling services die zijn:

  • Zeer onderhoudbaar en testbaar
  • Los verbonden
  • Onafhankelijk inzetbaar
  • Georganiseerd rond zakelijke mogelijkheden.

De microservice-architectuur maakt de continue levering / implementatie van grote, complexe applicaties mogelijk. Het stelt een organisatie ook in staat zijn technologiestapel te evolueren.

Hoe te beslissen of u microservices nodig hebt

Aanvankelijk hoeft u, wanneer u net begint met werken aan uw MVP, geen microservices te gebruiken. De schaal van de Y-as is misschien niet je agenda op dit moment. Maar wanneer het product begint te rijpen en soms te vroeg waar u te maken krijgt met schaalvergroting, is de ontbinding in functionele modules logischer naarmate het bedrijf zelf ontbindt. Dit is het juiste punt om het architectuurpatroon van microservices te onderzoeken.

Een boek dat ik ten zeerste aanbeveel is van Chris Richardson hier: http://bit.ly/2EmJDYt.

Microservices worden meestal overwogen bij het vervangen van een monolithische applicatie die tot voor kort vrij gebruikelijk was toen containerisatie-oplossingen zoals Docker de DevOps-wereld begonnen te regeren. Maar daarover later meer.

Het zou oneerlijk zijn als ik doorga zonder Domain Driven Design (DDD) te vermelden. Het is een zeer populaire strategie voor het ontbinden van uw product in functionele modules. Daarom is het erg handig om microservices te maken.

Dus, wat is een domein volgens DDD?

Elk probleem dat u probeert op te lossen is een domein.

Elk domein is onderverdeeld in onderling exclusieve begrensde contexten. Deze contexten zijn niets anders dan afzonderlijke gebieden van dat specifieke probleem.

In een microservicepatroon correleert elke begrensde context met een microservice. DDD-patronen helpen u de complexiteit in het domein te begrijpen. Voor het domeinmodel voor elke Bounded Context identificeert en definieert u de
entiteiten, waardeobjecten en aggregaten die uw domein modelleren.

Afhankelijk van de complexiteit van uw software kunt u de DDD-principes kiezen of een eenvoudigere aanpak uitvoeren.

Het doel is om een ​​sterk samenhangend en losjes gekoppeld domeinmodel te bereiken. Volg daarvoor deze aanpak:

Dit was een korte introductie op de DDD. Om er meer over te weten, raad ik ten zeerste aan het uitstekende boek van Eric Evans te lezen http://bit.ly/2Eoy17l.

Verder gaan.

Ik hoop dat je me bijhoudt.

Dus vanaf nu zal ik meer praten over specifieke werkwijzen voor NodeJS. En wat ik bedoel is dat microservices en DDD u helpen om het ware potentieel van NodeJS toch te benchmarken. Het is op zichzelf compleet. Hoe? We zullen wel zien.

Welk ontwerppatroon te gebruiken tijdens het gebruik van NodeJ's

Ontwerppatronen gaan over het ontwerpen van software met behulp van bepaalde normen die bij een aantal ontwikkelaars bekend zijn.

Er zijn verschillende ontwerppatronen die we kunnen gebruiken. Ik wil graag introduceren en / of samenvatten voor ontwikkelaars die al op de hoogte zijn van een patroon dat het Repository-patroon wordt genoemd.

Dit patroon maakt het gemakkelijker om de MVC-logica te scheiden, terwijl het ook gemakkelijker wordt om de modeldefinitie en modelinteractie met de rest van de logica te verwerken.

Het bestaat uit:

  1. Controller: het behandelt alleen het verzoek en het antwoord en bijbehorende attributen. Het zal ook geen bedrijfslogica of modeldefinitie of modelassociaties hebben. (mapnaam: controllers)
  2. Service: het bevat bedrijfslogica voor uw microservice. De besturing gaat van controller naar een service. Het is een 1: 1-relatie tussen een controller en zijn service en een 1: veel-relaties tussen service en repositories. (mapnaam: services)
  3. Repository: het werkt samen met de modellen die deel uitmaken van de modelmap. Elke vraag naar de database via de modellaag wordt hier gevormd. Het zal geen zakelijke logica hebben. (mapnaam: repositories)
  4. Model: het bevat de modeldefinitie, associaties, virtuele functies (bijv. In mangoest)
  5. Hulpprogramma's: dit bevat helperklassen / functies die als services kunnen worden gebruikt. Bijv .: een Redis-hulpprogramma dat alle functies heeft die nodig zijn om met Redis te communiceren. (mapnaam: hulpprogramma's)
  6. Testcase: dit omvat unit-testgevallen tegen controller-methoden om maximale codedekking te garanderen. (mapnaam: spec)

Om hierover meer te lezen, kunt u verwijzen naar deze link: http://bit.ly/2TrSyRS

Ok, vertel me over clustermodules

Een enkele instantie van Node.js wordt uitgevoerd in een enkele thread. Om te profiteren van multi-core systemen, wil de gebruiker soms een cluster van Node.js-processen starten om de belasting af te handelen.

Met de clustermodule kunnen eenvoudig onderliggende processen worden gemaakt die allemaal serverpoorten delen.

Houd er rekening mee dat het ideaal is om één proces per container te gebruiken tijdens het gebruik van Docker-containerisatie voor implementatie via microservices. Daarom zijn clustermodules niet nuttig bij het gebruik van docker-ization.

Hoe om te gaan met de besturingsstroom in NodeJS

Terwijl u callbacks of beloften gebruikt, kunnen de volgende bibliotheken nuttig zijn:

  1. Async (https://www.npmjs.com/package/async)
  2. Vasync (met beter volgen van werking) https://www.npmjs.com/package/vasync
  3. Bluebird (beloften afhandelen bijv. Promise.all etc.) https://www.npmjs.com/package/bluebird

En lussen?

  • Series-lus: elke stap één voor één uitvoeren op volgorde
  • Vertraagde lus: lus met een time-out
  • Parallelle lus: alle beloften in een lus verzamelen en parallel uitvoeren

En wat zijn enkele handige linttools?

Linting-tools analyseren uw code statisch (zonder deze uit te voeren). Ze identificeren potentiële bugs of gevaarlijke patronen. Patronen zoals het gebruik van niet-aangegeven variabelen of "hoofdletters" in een schakelaar zonder een "break" -opdracht.

Als u de strikte modus op uw codebase inschakelt met 'gebruik streng', kan uw code snel mislukken als de JavaScript-parser een gelekt globaal of vergelijkbaar slecht gedrag kan identificeren.

Voorbeelden van linters zijn Javascript-lint en JS-lint.

Ok, hoe gaan we om met loggen?

Enkele veelgebruikte npm-pakketten zijn:

  • Winston (https://www.npmjs.com/package/winston)
  • Bunyan (https://www.npmjs.com/package/bunyan)

Mogelijk logformaat:

Voor gedistribueerde systemen zoals microservices, wilt u gedistribueerde tracering verkennen met behulp van ZipKin enz.

Een opmerking over NPM-pakketten: gebruik een pakket alleen als het een probleem voor u oplost dat u niet zelf kunt oplossen. Voer regelmatig npm-audits uit om kritieke problemen met uw npm-afhankelijkheden te vinden.

Niet-ingevangen uitzonderingen verwerken

Standaard verwerkt Node.js dergelijke uitzonderingen door de stack trace af te drukken naar stderr en af ​​te sluiten met code 1, waarbij een eerder ingesteld proces wordt vervangen. ExitCode

Opmerking: Het toevoegen van een handler voor de gebeurtenis 'uncaughtException' heeft voorrang op dit standaardgedrag.

U kunt ook de process.exitCode in de 'uncaughtException'-handler wijzigen, waardoor het proces wordt afgesloten met de opgegeven exitcode. Anders wordt het proces in aanwezigheid van een dergelijke handler afgesloten met 0.

process.exit (0) - succesvolle beëindiging
process.exit (1) - mislukte beëindiging

Niet-verwerkte afwijzingen verwerken

Beloften zijn alomtegenwoordig in de Node.js-code en soms gekoppeld aan een zeer lange lijst met functies die beloften opleveren, enzovoort.

Als u geen juiste .catch (...) -afwijzingshandler gebruikt, wordt een gebeurtenis UnhandledRejection uitgezonden. Als u niet op de juiste manier wordt betrapt en geïnspecteerd, kunt u uzelf beroven van uw enige kans om het probleem te detecteren en mogelijk op te lossen.

Extra Tip:

console.time () en console.timeEnd ()

Het console-object heeft methoden time () en timeEnd () die helpen bij het analyseren van de prestaties van delen van uw code.

Dit is geen oplossing voor productie, maar het kan worden gebruikt wanneer u geen betere tools hebt.

Heel erg bedankt voor je tijd.
Meld u aan voor mijn nieuwsbrief

Andere prachtige artikelen over vergelijkbare onderwerpen:

  1. https://microservices.io
  2. https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/ddd-oriented-microservice