real-life node.js troubleshooting - damian schenkelman, auth0

48
Real-Life Node.js Troubleshooting Damian Schenkelman, Auth0

Upload: nodejsfoundation

Post on 15-Apr-2017

154 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Real-Life Node.js TroubleshootingDamian Schenkelman, Auth0

Page 2: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

4 years

Page 3: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Usual suspects

Page 4: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Memory Leaks

Page 5: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

–Sebastian Peyrott (a co-worker)

“The main cause for leaks in garbage collected languages are unwanted references”

Page 6: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Memory Modelhttps://developers.google.com/web/tools/chrome-

devtools/memory-problems/memory-101

A

B

C

F

E

D

GGC

H I

Page 7: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

b.d=null

A

B

C

F

E

D

GGC

H I

Page 8: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

D not referenced

A

B

C

F

E

D

GGC

H I

Page 9: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

D is GCed

A

B

C

F

E GGC

H I

Page 10: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Sawtooth

Page 11: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Memory Leak

A

B

C

F

E

D

G

Things we don’t need and are taking up a LOT of space

GC

Page 12: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Memory Leak

A

B

C

F

E

D

G

Things we don’t need and are taking up a LOT of space

GC

More things we don’t need

Page 13: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Crashes

Page 14: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Memory leak busting

Page 15: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Take Control

Page 16: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

--max-old-space-sizeis your friend

Page 17: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Drain connections

Page 18: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Restarts

Page 19: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Heap Snapshot

Page 20: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

v8-profilerhttps://github.com/node-inspector/v8-profiler

varprofiler=require('v8-profiler');

varsnapshot=profiler.takeSnapshot();

snapshot.export(function(error,result){fs.writeFileSync('snapshot.json',result);snapshot.delete();});

Page 21: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Demo

Page 22: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Mental Picture

{'kinesis.us-west-1.amazonaws.co:443':}

{sockets:}

[…,…,…,…,…,…,…,…,…,TLSSocket

]

Something related to logging…

Page 23: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Not Easyhttps://github.com/auth0/kinesis-writable/pull/6/files

Page 24: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

forever-agenthttps://github.com/request/forever-agent/blob/

ece900a6e8dfac734186db3080c00875c0300450/index.js#L70

if(this.freeSockets[name]&&this.freeSockets[name].length>0&&!req.useChunkedEncodingByDefault){varidleSocket=this.freeSockets[name].pop()idleSocket.removeListener('error',idleSocket._onIdleError)deleteidleSocket._onIdleErrorreq._reusedSocket=truereq.onSocket(idleSocket)}else{this.addRequestNoreuse(req,host,port)}

Page 25: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Fixed

Page 26: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

CPU bottlenecks

Page 27: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Auth Service

DB

Scenario

Client

Page 28: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Expected response times

Page 29: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Actual response times

Page 30: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Flame graphsa()

b()

c()

d()

h()

i()

e() f()

g()

Page 31: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Flame graphs

Page 32: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Demo

Page 33: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

The problem

Page 34: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Scale

Page 35: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Faster Hash

Page 36: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Caching

Page 37: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Scale up

Page 38: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Multiple Auth Services

LB

Auth Service

Auth Service

Auth Service

Auth Service

Page 39: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

BaaShttps://github.com/auth0/node-baas

//comparebcryptforreq.passwordtodbhashbaas.compare(req.body.password,user.passwordHash,(err,success)=>{res.send(err||!success?401:200);});

Page 40: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Auto Scaling

Auth Service LB

BaaS

BaaS

BaaS

BaaS

Page 41: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Cost comparison

Price / (1M req) #req per sec / vCPU

t2-micro $0.36 10.00

t2-medium $0.76 9.50

c4-large $1.53 10.00

c3-8xlarge $1.64 8.88

Page 42: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Fail gracefully

Page 43: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Cat picture

Page 44: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Memory Leaks• Memory terminology: https://developers.google.com/web/tools/

chrome-devtools/memory-problems/memory-101

• Memory leaks in JS: https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/

• Roots: https://stackoverflow.com/questions/9748358/when-does-the-js-engine-create-a-garbage-collection-root

• Increase heap size: https://twitter.com/tjholowaychuk/status/480753206301966336

• v8 GC logs speaking to you: https://github.com/joyeecheung/v8-gc-talk

Page 45: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Memory Leaks (2)• Connection draining: https://cloud.google.com/

compute/docs/load-balancing/enabling-connection-draining

• master-process: https://github.com/jfromaniello/master-process

• Express connection draining: https://github.com/expressjs/express/issues/1366

• v8-profiler: https://github.com/node-inspector/v8-profiler

Page 46: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Memory Leaks (3)• AWS SDK issues: https://github.com/aws/aws-sdk-js/issues/329,

https://github.com/aws/aws-sdk-js/issues/855

• Kinesis event fix: https://github.com/auth0/kinesis-writable/pull/6/files

• Forever agent: https://github.com/request/forever-agent/blob/ece900a6e8dfac734186db3080c00875c0300450/index.js#L70

• Memory profiling for mere mortals: http://thlorenz.com/talks/memory-profiling/book/memory_profiling_for_mere_mortals_/memory_profiling_for_mere_mortals__0.html

• @thlorenz notes on mem profiling: https://github.com/thlorenz/v8-perf/blob/master/memory-profiling.md

Page 47: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Performance• http://security.stackexchange.com/a/83382

• http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html

• https://github.com/davidmarkclements/0x

• https://github.com/thlorenz/v8-perf/issues/4

• https://github.com/auth0/node-baas

• http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/US_SetUpASLBApp.html

• https://gist.github.com/trevnorris/9616784

• https://github.com/dschenkelman/bcrypt-sample

Page 48: Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0

Thankshttps://github.com/dschenkelman/node-troubleshooting

@dschenkelman npmidschenkelman