$30 off During Our Annual Pro Sale. View Details »

Melhores práticas de desempenho com NodeJs em produção

Melhores práticas de desempenho com NodeJs em produção

Como fazemos quando nossa aplicação não está colaborando? Esta é uma série de explicações e dicas para resolver esse problema!

Lucas Santos

April 08, 2019
Tweet

More Decks by Lucas Santos

Other Decks in Programming

Transcript

  1. Melhor Desempenho
    Utilizando Node.js em produção

    View Slide

  2. Lucas Santos
    /khaosdoctor @_staticvoid
    lsantos.dev
    @khaosdoctor
    Lead Solutions Architect

    View Slide

  3. trainingcenter.io
    abcdevelopers.org
    obarra.co

    View Slide

  4. Node.js production

    View Slide

  5. Node.js production?

    View Slide

  6. O que pode acontecer?

    View Slide

  7. 1
    Sua máquina se transforma
    (Em um fogão, por exemplo)

    View Slide

  8. 2
    Você se transforma
    #pas

    View Slide

  9. 3
    Tudo vai bem

    View Slide

  10. “Na minha máquina funciona” starter pack

    View Slide

  11. Afinal o que é o Node?

    View Slide

  12. View Slide

  13. O Node é:
    Assíncrono (event Loop)
    Non Blocking
    Single Thread

    View Slide

  14. View Slide

  15. Sim! Eu pesquisei

    View Slide

  16. View Slide

  17. API’s de alta performance

    View Slide

  18. A anatomia de uma API

    View Slide

  19. A anatomia de uma API
    Começa assim

    View Slide

  20. A anatomia de uma API
    Começa assim
    Termina assim
    “Ajeita ali só”

    View Slide

  21. Maiores causas de problemas
    - Muito processamento desnecessário
    - Má codificação
    - Conteúdo estático
    - Uso indevido do Node
    - Aumento de tráfego repentino

    View Slide

  22. Maiores causas de problemas
    - Muito processamento desnecessário
    - Má codificação
    - Conteúdo estático
    - Uso indevido do Node
    - Aumento de tráfego repentino (Event Loop)

    View Slide

  23. Maiores causas de problemas
    - Muito processamento desnecessário
    - Má codificação
    - Conteúdo estático
    - Uso indevido do Node
    - Aumento de tráfego repentino (C10K)

    View Slide

  24. Por que não os dois?

    View Slide

  25. NGINX to the rescue!
    Melhorando a API através da infraestrutura

    View Slide

  26. Cache is the key

    View Slide

  27. Se der, cacheia, senão,
    também
    ● Cachear arquivos estáticos
    ● Cachear chamadas de API
    ○ Por rota
    ○ Por hash de IP
    ● Cachear retornos de DB
    ● Cachear arquivos gerados por SSR
    ● Pode ser implementado via Infra (NGINX)
    ou via código (Ex: Catbox-redis)

    View Slide

  28. Proxy reverso

    View Slide

  29. Um proxy, só que
    ao contrário
    Remove a carga de
    conexões do node
    Permite escalabilidade de
    aplicações
    Debounce de conexões

    View Slide

  30. Load Balancing

    View Slide

  31. Balanceando carga
    - Escalabilidade
    próxima de infinita
    - Três tipos de
    roteamento
    - Round Robin
    - Least Conn
    - IP Hash

    View Slide

  32. Simples assim
    Servidores disponíveis
    Load Balancer
    Proxy Reverso

    View Slide

  33. HTTP/2

    View Slide

  34. The good, the bad
    and the /1.1
    Chamadas síncronas uma
    a uma
    O mesmo domínio só
    pode responder a uma
    request por vez
    Bloqueio HOL (Head of
    Line)

    View Slide

  35. The good, the bad
    and the /2
    Multiplexing
    Menos conexões
    simultâneas
    Mais performance
    Compressão
    Server push
    Keep Alive

    View Slide

  36. Simplificação

    View Slide

  37. Simplificação

    View Slide

  38. Show me the code

    View Slide

  39. Código performático
    Quando o problema é a peça entre a cadeira e o monitor

    View Slide

  40. Você FAZ
    diferença
    - Código mais leve roda
    melhor
    - Tomar cuidado com
    consumo de memória
    - Evitar funções complexas
    (principalmente loops)
    - Regra das 80 colunas
    - Use menos libs

    View Slide

  41. Map vs For

    View Slide

  42. A guerra dos loops
    Loops são as funções mais custosas
    que se pode ter
    Adição de complexidade
    Muitas vezes contornáveis

    View Slide

  43. A guerra dos loops
    Loops são as funções mais custosas que
    se pode ter
    Adição de complexidade
    Muitas vezes contornáveis
    CodeMetrics

    View Slide

  44. Nem sempre o built-in é o melhor...
    Sem filter + reduce Com filter + reduce

    View Slide

  45. Mas, as vezes loops são melhores...

    View Slide

  46. Hashmap vs Case

    View Slide

  47. Voltando às
    origens
    - Execução paralela de todos
    os caminhos possíveis
    (cuidado!)
    - Menos complexidade
    - Menos linhas de código
    - Repetição de keywords
    - Dinâmico

    View Slide

  48. Async

    View Slide

  49. Quando você usa funções síncronas no Node...

    View Slide

  50. Segura aí que já
    volto
    - Não bloqueia o
    processamento
    - Impacto em tempo é
    pequeno
    - Otimiza o uso de recursos

    View Slide

  51. Loops Assíncronos!
    - Asynchronous Iteration

    View Slide

  52. Parallel

    View Slide

  53. Tudo junto!
    Executa múltiplas ações ao mesmo tempo
    Simula um “multi-core”
    Ações independentes

    View Slide

  54. Tudo junto!
    Executa múltiplas ações ao mesmo tempo
    Simula um “multi-core”
    Ações independentes
    Evite promise-chaining
    Não é paralelo!

    View Slide

  55. Cache is the key²

    View Slide

  56. Se der, cacheia, senão,
    também²
    ● Cachear arquivos estáticos
    ● Cachear chamadas de API
    ○ Por rota
    ○ Por hash
    ● Cachear retornos de DB
    ● Cachear arquivos gerados por SSR
    ● Service Workers
    ● Pode ser implementado via Infra (NGINX) ou via
    código (Ex: Catbox-redis)

    View Slide

  57. SSR?

    View Slide

  58. Será que vale?
    Processamento muito intenso do
    lado do servidor
    Bom para páginas pequenas
    Distribua o processamento no
    cliente
    É uma boa prática dependendo
    do caso

    View Slide

  59. Node Cluster API
    Porque sim! Node pode ser multi-core

    View Slide

  60. Clusters
    - Utilizam o processamento
    multi núcleo
    - Nativo do Node!
    - Simples e fácil

    View Slide

  61. Clusters
    - Utilizam o processamento
    multi núcleo
    - Nativo do Node!
    - Simples e fácil
    - Estável
    https://nodejs.org/api/cluster.html

    View Slide

  62. Use mais o V8!

    View Slide

  63. Use mais o V8!
    Não use Lodash
    Não use Lodash
    Não use Lodash
    Não
    use
    Lodash
    Não use Lodash
    Não use Lodash
    Não use Underscore
    Não use Underscore
    Não
    use
    Underscore
    Não
    use
    Underscore
    Não use jQuery
    Não
    use
    jQuery
    Não use jQuery
    Não use Underscore
    Não
    use
    jQuery

    View Slide

  64. Use mais o V8!
    Não use LoDash(e derivados)

    View Slide

  65. POR… QUE?
    - Libs são úteis em casos
    específicos, use nesses
    casos…
    - Pensadas para o
    browser (muito código
    inútil)

    View Slide

  66. Agora sim
    - Quando a lógica é
    complexa
    - ...ou não intuitiva
    - Tipo:

    View Slide

  67. Outros pontos

    View Slide

  68. Outras coisinhas
    - Gerenciamento de
    sessões ocupa
    memória
    - Utilize projeção no
    banco de dados
    - Use plataformas de
    monitoramento

    View Slide

  69. Workers/Jobs de alta performance

    View Slide

  70. O que é um e o que é outro?
    Worker
    - Sempre ativo na máquina
    - Roda por eventos disparados de
    fora
    - Consome mais memória (fica
    ligado direto)
    - Mais propenso a memory leak
    Job
    - Fica inativo
    - Roda apenas em horários ou
    intervalos determinados
    (CronJob)
    - Consome memória em picos

    View Slide

  71. Coletando o lixo

    View Slide

  72. Yes, we have GC
    - Node tem um garbage
    collector
    - Funciona após 1.4Gb de
    memória ocupada (Heap
    Limit do V8)
    - Dividido em Old Space e
    New Space (???)
    https://blog.risingstack.com/finding-a-memory-leak-in-node-js/

    View Slide

  73. Garbage Collection in depth
    Deletamos um obj. GC Roda
    Perdeu Root = Memória não usada
    New Space Old Space

    View Slide

  74. Garbage Collection in depth
    Deletamos um obj. GC Roda
    Perdeu Root = Memória não usada
    New Space Old Space
    MUITO CUIDADO

    View Slide

  75. Coletando o lixo
    (Manualmente)

    View Slide

  76. Profiling
    - Utilização de libs de
    profiling
    - Usar profiler nativo do
    node:

    View Slide

  77. FlameGraph

    View Slide

  78. Node.js production!

    View Slide

  79. Perguntas?

    View Slide


  80. - https://github.com/khaosdoctor/palestra-performance-nodejs
    - https://github.com/khaosdoctor/my-notes/blob/master/node/V8.md
    - https://medium.com/trainingcenter/entendendo-promises-de-uma-vez-por-toda
    s-32442ec725c2

    View Slide

  81. Obrigado!
    /khaosdoctor @_staticvoid
    lsantos.dev
    @khaosdoctor

    View Slide