Node Interactive: Node.js Performance and Highly Scalable Micro-Services

70
Highly Scalable Node.js Microservices Chris Bailey (@Chris__Bailey) Node.js and Swift Runtimes Chris Vignola (@ChrisVignola) Cloud Native Node.js

Transcript of Node Interactive: Node.js Performance and Highly Scalable Micro-Services

Page 1: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

Highly Scalable Node.js Microservices

Chris Bailey (@Chris__Bailey)

Node.js and Swift Runtimes

Chris Vignola (@ChrisVignola)

Cloud Native Node.js

Page 2: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

: Key Technologies

Page 3: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

: Key Technologies

Container

Page 4: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

: Key Technologies

Container Orchestration

Page 5: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

: Key Technologies

Container Orchestration

Package and Deploy

Page 6: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

: Key Technologies

Container Orchestration

MonitoringPackage and Deploy

Page 7: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

: Key Technologies

Container Orchestration

Monitoring Distributed TracingPackage and Deploy

Page 8: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

MICROSERVICES: Key Performance Characteristics

IO Speed • Performance • Scale

Page 9: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

0300600900

1200

0

1,150

IO Speed • Performance • Scale

MICROSERVICES: Key Performance Characteristics

Page 10: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

0300600900

1200

0

1,150

IO Speed • Performance • Scale

MICROSERVICES: Key Performance Characteristics

Page 11: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

0300600900

1200897

1,150

MICROSERVICES: Key Performance Characteristics

IO Speed • Performance • Scale

Page 12: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

0300600900

1200897

1,150

Startup • Availability • Scaling

MICROSERVICES: Key Performance Characteristics

IO Speed • Performance • Scale

Page 13: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

0300600900

1200897

1,150

00.9

Startup • Availability • Scaling

MICROSERVICES: Key Performance Characteristics

IO Speed • Performance • Scale

Page 14: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

0300600900

1200897

1,150 13.7

0.9

Startup • Availability • Scaling

MICROSERVICES: Key Performance Characteristics

IO Speed • Performance • Scale

Page 15: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

0300600900

1200897

1,150 13.7

0.9

Startup • Availability • Scaling

Memory • Efficiency • Cost

MICROSERVICES: Key Performance Characteristics

IO Speed • Performance • Scale

Page 16: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

0300600900

1200897

1,150 13.7

0.9 023.6

Startup • Availability • Scaling

Memory • Efficiency • Cost

MICROSERVICES: Key Performance Characteristics

IO Speed • Performance • Scale

Page 17: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

0300600900

1200897

1,150 13.7

0.9

422

23.6

Startup • Availability • Scaling

Memory • Efficiency • Cost

MICROSERVICES: Key Performance Characteristics

IO Speed • Performance • Scale

Page 18: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

Startup • Availability • Scaling

Memory • Efficiency • Cost

Benchmarking WG: Performance Gains

IO Speed • Performance • Scale

Page 19: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

Startup • Availability • Scaling

Memory • Efficiency • Cost

3,0492,914

2,0761,866

4.x master6.x 8.x

Benchmarking WG: Performance Gains

IO Speed • Performance • Scale

Page 20: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

Startup • Availability • Scaling

Memory • Efficiency • Cost

50,42052,64042,500

71,0003,0492,914

2,0761,866

4.x master6.x 8.x 4.x master6.x 8.x

Benchmarking WG: Performance Gains

IO Speed • Performance • Scale

Page 21: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

Startup • Availability • Scaling

Memory • Efficiency • Cost

50,42052,64042,500

71,00089,02492,84091,47688,9603,0492,914

2,0761,866

4.x master6.x 8.x 4.x master6.x 8.x 4.x master6.x 8.x

Benchmarking WG: Performance Gains

IO Speed • Performance • Scale

Page 22: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

Building Scalable Microservices

Page 23: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

Page 24: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

const appName = require('./../package').name;const express = require('express');const log4js = require(‘log4js');

const logger = log4js.getLogger(appName);const app = express();

app.get('/', function (req, res) { res.send('Hello World!')})

const port = process.env.PORT || 3000;app.listen(port, function(){ logger.info(`Express listening on: ` + port);});

Page 25: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

DockerfileDockerfile-tools.dockerignore

Page 26: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

DockerfileDockerfile-tools.dockerignore

FROM ibmcom/ibmnode

ENV NODE_ENV productionENV PORT 3000

WORKDIR "/app"

# Install app dependenciesCOPY package.json /app/RUN cd /app; npm install

# Bundle app sourceCOPY . /app

EXPOSE 3000CMD ["npm", "start"]

Page 27: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

DockerfileDockerfile-tools.dockerignore

node_modules/npm-debug.log

Page 28: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

$ docker build -t <your username>/node-app .

Page 29: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

$ docker build -t <your username>/node-app . $ docker run -p 49160:3000 -d <your username>/node-app

Page 30: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

$ docker build -t <your username>/node-app . $ docker run -p 49160:3000 -d <your username>/node-app

Page 31: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

$ docker build -t <your username>/node-app . $ docker run -p 49160:3000 -d <your username>/node-app

Page 32: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

DockerfileDockerfile-tools.dockerignore

chart/node-app/Chart.yamlchart/node-app/templates/deployment.yamlchart/node-app/templates/hpa.yamlchart/node-app/templates/service.yamlchart/node-app/values.yaml

HELM CHARTS

Page 33: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

DockerfileDockerfile-tools.dockerignore

chart/node-app/Chart.yamlchart/node-app/templates/deployment.yamlchart/node-app/templates/hpa.yamlchart/node-app/templates/service.yamlchart/node-app/values.yaml

HELM CHARTS

apiVersion: v1description: A Helm chart for Kubernetesname: node-appversion: 1.0.0

Page 34: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

DockerfileDockerfile-tools.dockerignore

chart/node-app/Chart.yamlchart/node-app/templates/deployment.yamlchart/node-app/templates/hpa.yamlchart/node-app/templates/service.yamlchart/node-app/values.yaml

HELM CHARTS

apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: “node-app-deployment" labels: chart: “node-app-1.0.0”spec: replicas: “5” revisionHistoryLimit: “1” template: metadata: labels: app: “node-app-selector" version: “1.0.0” spec: containers: - name: “node-app” image: “repository:1.0.0” imagePullPolicy: Always livenessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 3000 periodSeconds: 1000 resources: requests: cpu: "200m"

memory: "300Mi" env: - name: PORT value : “3000”

Page 35: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

DockerfileDockerfile-tools.dockerignore

chart/node-app/Chart.yamlchart/node-app/templates/deployment.yamlchart/node-app/templates/hpa.yamlchart/node-app/templates/service.yamlchart/node-app/values.yaml

HELM CHARTS

apiVersion: autoscaling/v2alpha1kind: HorizontalPodAutoscalermetadata: name: “node-app-hpa-policy" namespace: defaultspec: scaleTargetRef: apiVersion: apps/v1beta1 kind: Deployment name: “node-app-deployment" minReplicas: 5 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 70 - type: Resource resource: name: memory targetAverageUtilization: 70

Page 36: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

func add(_ a: Int, to b: Int) -> Void { print(a + b) }

let a = ”5” let b = 3

public/*test/*server/server.jspackage.jsonREADME.md.gitignore

DockerfileDockerfile-tools.dockerignore

chart/node-app/Chart.yamlchart/node-app/templates/deployment.yamlchart/node-app/templates/hpa.yamlchart/node-app/templates/service.yamlchart/node-app/values.yaml

HELM CHARTS

apiVersion: v1kind: Servicemetadata: name: “node-app“ labels: chart: “node-app-1.0.0”spec: type: NodePort ports: - port: 3000 selector: app: “node-app-selector"

Page 37: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

$ helm package ./chart/node-app

Page 38: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

$ helm package ./chart/node-app$ helm install ./node-app-1.0.0.tgz

Page 39: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

$ helm package ./chart/node-app$ helm install ./node-app-1.0.0.tgz

Page 40: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

$ helm package ./chart/node-app$ helm install ./node-app-1.0.0.tgz

Page 41: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

Understanding Microservices Performance

Page 42: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

PUBLIC NETWORK CLOUD NETWORK

CATALOG

ORDER

INVENTORY

USER

MySQL

MongoDB

SPARK

ELASTICSEARCH

BACKEND FOR FRONTEND MICROSERVICES SERVICES

LOAD BALANCER

Page 43: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

PUBLIC NETWORK CLOUD NETWORK

CATALOG

ORDER

INVENTORY

USER

MySQL

MongoDB

SPARK

ELASTICSEARCH

BACKEND FOR FRONTEND MICROSERVICES SERVICES

LOAD BALANCER

Page 44: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

PUBLIC NETWORK CLOUD NETWORK

CATALOG

ORDER

INVENTORY

USER

MySQL

MongoDB

SPARK

ELASTICSEARCH

BACKEND FOR FRONTEND MICROSERVICES SERVICES

LOAD BALANCER

Page 45: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

PUBLIC NETWORK CLOUD NETWORK

CATALOG

ORDER

INVENTORY

USER

MySQL

MongoDB

SPARK

ELASTICSEARCH

BACKEND FOR FRONTEND MICROSERVICES SERVICES

LOAD BALANCER

Page 46: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

PUBLIC NETWORK CLOUD NETWORK

CATALOG

ORDER

INVENTORY

USER

MySQL

MongoDB

SPARK

ELASTICSEARCH

BACKEND FOR FRONTEND MICROSERVICES SERVICES

LOAD BALANCER

Page 47: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

PUBLIC NETWORK CLOUD NETWORK

CATALOG

ORDER

INVENTORY

USER

MySQL

MongoDB

SPARK

ELASTICSEARCH

BACKEND FOR FRONTEND MICROSERVICES SERVICES

LOAD BALANCER

Page 48: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

PUBLIC NETWORK CLOUD NETWORK

CATALOG

ORDER

INVENTORY

USER

MySQL

MongoDB

SPARK

ELASTICSEARCH

BACKEND FOR FRONTEND MICROSERVICES SERVICES

LOAD BALANCER

Page 49: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

BROWSER

TIME

Page 50: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

BROWSER

LOAD BALANCER

TIME

Page 51: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

BROWSER

LOAD BALANCER

WEB BFF

TIME

Page 52: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

BROWSER

LOAD BALANCER

WEB BFF

ORDER SERVICE

TIME

Page 53: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

BROWSER

LOAD BALANCER

WEB BFF

ORDER SERVICE

MongoDB

TIME

Page 54: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

BROWSER

LOAD BALANCER

WEB BFF

ORDER SERVICE

MongoDB

INVENTORY SERVICE

TIME

Page 55: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

MySQL

BROWSER

LOAD BALANCER

WEB BFF

ORDER SERVICE

MongoDB

INVENTORY SERVICE

TIME

Page 56: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

MySQL

BROWSER

LOAD BALANCER

WEB BFF

ORDER SERVICE

MongoDB

INVENTORY SERVICE

MongoDB

TIME

Page 57: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

• Collects data from each enabled service

• Propagates correlation ID using HTTP headers

• Provides sampling, tracing, and debug capabilities

• Collects microsecond timestamps

• Correlates data in Zipkin server

• Presents data in Zipkin dashboard

Request Tracking: OpenTracing and Zipkin

Page 58: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

const zipkin = require(‘appmetrics-zipkin’);const rest = require(‘rest');const express = require('express');

const app = express();

app.get('/', (req, res) => { rest('http://localhost:9000/api') .then(response => res.send(response.entity)) .catch(err => console.error('Error', err.stack));});

const port = process.env.PORT || 3000;app.listen(port, function(){ logger.info(`Express listening on: ` + port);});

Page 59: Node Interactive: Node.js Performance and Highly Scalable Micro-Services
Page 60: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

• Collects data from each enabled service

• Requires /metrics endpoint providing data

• Provides storage and correlation capabilities

• Provide customisable dashboard

• Integrates with Graphana, Graphite, etc

Microservice Metrics: Prometheus

Page 61: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

const zipkin = require(‘appmetrics-zipkin’);const prometheus = require(‘appmetrics-prometheus’).attach();const rest = require(‘rest');const express = require('express');

const app = express();

app.get('/', (req, res) => { rest('http://localhost:9000/api') .then(response => res.send(response.entity)) .catch(err => console.error('Error', err.stack));});

const port = process.env.PORT || 3000;app.listen(port, function(){ logger.info(`Express listening on: ` + port);});

Page 62: Node Interactive: Node.js Performance and Highly Scalable Micro-Services
Page 63: Node Interactive: Node.js Performance and Highly Scalable Micro-Services
Page 64: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

• ‘appmetrics-dash’ provides self-hosted monitoring

• Inbound and Outbound request performance

• Resource and event loop monitoring

• Request a node-report

• Enable profiling and flame graphs

Deep Analysis: ‘appmetrics-dash’ and Flame Graphs

Page 65: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

const zipkin = require(‘appmetrics-zipkin’);const prometheus = require(‘appmetrics-prometheus’).attach();const dash = require(‘appmetrics-dash’).attach();const rest = require(‘rest');const express = require('express');

const app = express();

app.get('/', (req, res) => { rest('http://localhost:9000/api') .then(response => res.send(response.entity)) .catch(err => console.error('Error', err.stack));});

const port = process.env.PORT || 3000;app.listen(port, function(){ logger.info(`Express listening on: ` + port);});

‘appmetrics-dash’

Page 66: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

‘appmetrics-dash’

Page 67: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

‘appmetrics-dash’

Page 68: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

$ yo nodeserver$ yo nodeserver

Page 69: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

developer.ibm.com/node

Page 70: Node Interactive: Node.js Performance and Highly Scalable Micro-Services

const rest = require(‘rest');const express = require('express');const CLSContext = require('zipkin-context-cls');const {Tracer} = require('zipkin');const {recorder} = require('./recorder');

const ctxImpl = new CLSContext('zipkin');const tracer = new Tracer({ctxImpl, recorder});

const app = express();

const zipkinMiddleware = require('zipkin-instrumentation-express').expressMiddleware;app.use(zipkinMiddleware({tracer, serviceName: 'frontend'}));

const {restInterceptor} = require('zipkin-instrumentation-cujojs-rest');const zipkinRest = rest.wrap(restInterceptor, {tracer, remoteServiceName: ‘backend'});

app.get('/', (req, res) => { zipkinRest('http://localhost:9000/api') .then(response => res.send(response.entity)) .catch(err => console.error('Error', err.stack));});