https://github.com/vitorsalgado/rinha-2024-q1-nodejs
Rinha de Backend 2024 Q1 - Node.js
https://github.com/vitorsalgado/rinha-2024-q1-nodejs
docker node nodejs postgres rinha-de-backend rinha-de-backend-2024-q1
Last synced: about 1 month ago
JSON representation
Rinha de Backend 2024 Q1 - Node.js
- Host: GitHub
- URL: https://github.com/vitorsalgado/rinha-2024-q1-nodejs
- Owner: vitorsalgado
- License: mit
- Created: 2024-03-03T14:35:00.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-03-10T14:15:44.000Z (about 1 year ago)
- Last Synced: 2025-01-30T04:41:39.856Z (3 months ago)
- Topics: docker, node, nodejs, postgres, rinha-de-backend, rinha-de-backend-2024-q1
- Language: JavaScript
- Homepage: https://vitorsalgado.github.io/rinha-2024-q1-nodejs/
- Size: 149 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Rinha de Backend 2024 Q1 · Node.js · [](https://github.com/vitorsalgado/rinha-2024-q1-nodejs/actions/workflows/ci.yml) · 
Proposta de implementação da **[Rinha de Backend 2024 Q1](https://github.com/zanfranceschi/rinha-de-backend-2024-q1)**.
Os resultados dos testes são publicados automaticamente neste **[site](https://vitorsalgado.github.io/rinha-2024-q1-nodejs/)**.
Submissão: [aqui](https://github.com/zanfranceschi/rinha-de-backend-2024-q1/tree/main/participantes/vitorsalgado-nodejs)## Tech
- Node.js (Javascript)
- Postgres
- Envoy
- PgBouncer## Sobre
A idéia era criar um projeto bem simples, com o mínimo possível de libs e frameworks e que também fosse fácil de replicar em outras linguagens.
Em relação a **performance**, aqui algumas idéias que guiaram o projeto:- menos **round trips** possíveis ao banco de dados. para isso, usei uma **function** no Postgres para as transações e uma query única para o obter o extrato bancário.
- gestão eficiente de conexões com o banco. esse ponto é um complemente do anterior, conexões com o banco de dados são "caras" e aqui demorei para achar o setup ideal. desde o início a solução contava com um **pool** de conexões e no começo esse pool girou em torno de ~100 - ~300 de máx. conexões. depois de vários experimentos, encontrei uma ferramente interessante para o pool de conexões, **PgBouncer**. com o PgBouncer integrado, o setup ideal acabou sendo: __pool=5__ nas apis e __pool=20__ no PgBouncer, um número muito menor do que os experimentos inicias sem esse componente.
- experimentei usar o **nginx** como load balancer inicialmente, mas após alguns experimentos com **envoy**, acabei optando pelo último.
- **threads**: dadas as limitações do ambiente em relação a CPU e memória, experimentei diferentes setups de threads para as aplicações.
após vários testes, o "sweet spot" para as apis foi definir **UV_THREADPOOL_SIZE=1** para fazer o **libuv** usar uma thread apenas.- usar _pg_ e _pg-native_ para conexão com o Postgres. parecia ser a opção mais rápida, mas não cheguei a testar outras formas.
- _fast-json-stringify_ para serialização rápida de JSON.
- busquei pré-alocar memória sempre que possível no caso de arrays e buffers. para a leitura do request _body_, usei um _Buffer_ pré-alocado com o _content-length_ da requisição, ao invés de concatenar strings ou arrays com Buffer.concat. essa forma me pareceu mais eficiente e se saiu melhor em alguns benchmarks locais. implementação [aqui](./src/index.js#L258).
## Executando
Para executar o projeto completo em um **docker compose** local, execute no seu terminal:
```
make up
```## Testes de Carga
Para executar os testes de carga contidos no repositório original da rinha,
primeiro execute o comando de preparação:
```
make prepare
```O comando `make prepare` clona o repositório da rinha e instala a ferramente Gatling.
**Ele deve ser executado apenas uma vez.**
Para rodar os testes, execute o comando:
```
make test
```