Hvordan programmeres et modul, når vi skal foretage asynkrone opkald til et tredjepartssystem, som har hastighedsgrænser?

Introduktion:

Vores team har en løbende opgave med at regelmæssigt slette bulk-ID'er mellem 10 og 20 k fra systemet. Sletningen skal parse en csv-fil og kalde et IBM APIM-endepunkt, der igen sender en anmodning til et system, der sletter ID-filer. IBM APIm har en tærskelgrænse, at den kun kan acceptere 100 forbindelser ad gangen fra en bestemt brugeragent. Da nodejs er en asynkron hændelsesdrevet JavaScript-runtime og kører ikke-blokerende koder, vil en levering af x antal sletningsanmodninger sende x antal sletningsanmodninger på samme tid. Denne type asynkrone operationer blev afvist af IBM API-endepunktet på grund af overtrædelsen af ​​tærskelgrænsen. For at overvinde dette plejede vores team manuelt at gruppere / batche 100 id'er i hver csv-fil og derefter levere det til et SOAP UI-værktøj til at udføre bulk-sletninger. Dette lægger en masse manuel indsats med adskillelse og overvågning af individuelle batches.

Løsning:

Jeg fik til opgave at automatisere og finde en metode, der problemfrit kan sende sletningsanmodningen om 20.000 id'er og sikre, at vi ikke rammer tærskelgrænsen på grund af asynkron opførsel af nodeJS runtime. Jeg udforskede flere metoder, og jeg vil tale om fordele og ulemper ved hver metode.

  1. Kør alt synkront

Da vi har en grænse på 100 pr. Minut, kan vi blot bruge async og afvente, der kan starte hver sletning af opkald til IBM APIm på en synkron måde. Dette betyder, at appen starter et sletningsopkald, venter på, at det er afsluttet, og derefter sender det kun et nyt opkald til APIm igen. Dette sikrer, at der på et givet tidspunkt kun vil være 1 opkald, der når APIm. Dette kan forsinke den samlede køretid for sletningsaktiviteten enormt.

Som et eksempel analyserer nedenstående kode en matrix på 200 poster og sender hver post til sletning en efter en, efter at en er færdig.

Samlede poster: 200
Optaget tid: 05:59:11 (mm: ss: µs) Fem minutter og 59 sekunder

Den afventede metode, der bruges, vil sikre, at asynkornous opkald enten er vellykket eller mislykkedes, før den går til næste linje af den metode. På denne måde sikrer vi, at for loop-processen anmodningen sekventielt efter hinanden efter afslutning.

Fordele:

1. Vi formår at køre en anmodning ad gangen ved hjælp af afventningsmetode, og derfor blev vores ansøgning ikke afvist af 3. part på grund af satsgrænse.

ULEMPER:

1. Den tid det tager at færdiggøre batchet på 200 brugere tog omkring 6 minutter. Er dette noget, vi kan ordne for at gøre det hurtigere. Hvis ja, hvordan?

2. Kan vi gøre både asynkron og synkron:

Vi kender kursgrænsen for tredjepartssystemet, før vi bruger deres API-løsninger. For eksempel, hvis tredjepartssystemet kan tillade, at 100 anmodninger sendes til dem asynkront, er det muligt at batches hele anmodningen for at tillade x antal asynkrone opkald. Ved at gøre det på den måde overholder vi kursgrænsen og prøver også at få den fulde fordel ved knudepunkt asynkron kernemål for ikke-blokerende koder.

Hvordan gør man det?

Jeg har opdelt problemet i to hovedmål.

  • Oprettelse af en batch, der har x antal anmodninger.
  • Kør sekventielt en batch efter hinanden efter dens færdiggørelse.

1. Oprettelse af en batch:

Da jeg har et objekt på 20.000 poster, er jeg nødt til at oprette en matrix med arrays, der har en række x antal poster inde i hver af dem.

Lad mig for eksempel oprette en batch på 20 brugere hver.

Hver batch består af brugere, der sendes asynkront til et andet system.

2. At køre flere batches efter hinanden:

Når vi har oprettet flere batches med x antal anmodninger, er vi nødt til at sende hver batch sekventielt til den funktion, der indsendes asynkront, og vente på, at alle anmodninger på batchet bliver afsluttet. Til det er vi nødt til at oprette en matrix, der har succes for hver batchanmodning. Batcherne skal behandles en gang, arrayOfArrays er oprettet. Derfor bruger vi Promise.all (arrayOfArrays) til at bestemme gennemførelsen af ​​det.

Samlede poster: 200
Tid taget: 00:42:76 (mm: ss: µs)
Antal anmodninger pr. Batch: 10
Samlede poster: 200
Samlet tid taget: 00:21:69 (mm: ss: µs)
Antal anmodninger pr. Batch: 20

Fordele:

1. Som du ser, blev den tid, det tog at gennemføre, drastisk reduceret, når vi opdeler vores store brugerbase i flere batches, der er indstillet til asynkron drift. På denne måde sikrer vi, at vores applikation ikke overtræder tærskelgrænsen for tredjepartssystemet ved at bruge både synkrone og asynkrone operationer.

2. Som du ser, bliver færdiggørelsestiden reduceret, når du øger mængden af ​​asynkrone opkald til serveren ved at øge maxUserLimit i hver batch.

Jeg har også bemærket, at hvis du bruger for hver eller traditionel til loop til at analysere en matrix, tilføjer det et par sekunder til færdiggørelsen. Brug derfor altid array.map til at analysere en matrix, når du skal køre asynkron handling.

Github Kilde: Klik her!