A microservices-based calculator system built using Go (gRPC) and Node.js (REST). It uses Kafka for message communication with outbox pattern. also Observability and Moitoring using Prometheus and Grafana.
- Exposes calculator operations (Add, Subtract, Multiply, Divide) via gRPC.
- Stores requests in a PostgreSQL-backed outbox table.
- Polls the outbox table and publishes events to Kafka.
- Periodically reads events from the outbox table.
- Publishes events to a Kafka topic (
calculations).
- Consumes messages from the
calculationstopic. - Logs results to a file.
- Exposes Prometheus metrics:
messages_consumed_totalkafka_message_latency_seconds(histogram)
- Scrapes and stores time-series metrics.
- Accessed via
http://localhost:9090.
- Visualizes Prometheus metrics with custom dashboards.
- Accessed via
http://localhost:3000.
- Performance and stress testing on the gRPC API.
- Located in
k6_testing/test.js.
- Services are containerized using Docker.
docker-compose.ymlruns Kafka, PostgreSQL, Prometheus, and Grafana.Dockerfileprovided for both gRPC and REST applications.
- Docker + Docker Compose
- PostgreSQL, Kafka, Prometheus, and Grafana run in Docker Compose
- Node.js
- Go
โโโ calculator_grpc
โ โโโ calculator.proto
โ โโโ client
โ โ โโโ main.go
โ โโโ create_outbox_table.sql
โ โโโ go.mod
โ โโโ go.sum
โ โโโ pb
โ โ โโโ calculator.pb.go
โ โ โโโ calculator_grpc.pb.go
โ โโโ poller
โ โ โโโ poller.go
โ โโโ server.go
โโโ calculator_rest
โ โโโ calculations.log
โ โโโ index.js
โ โโโ package-lock.json
โ โโโ package.json
โโโ docker-compose.yml
โโโ k6_testing
โ โโโ test.js
โโโ prometheus.yml
โโโ readme
docker-compose up -dVerify services:
- Kafka:
localhost:9092 - PostgreSQL:
localhost:5431(user:postgres, password:mysecretpassword) - Prometheus:
http://localhost:9090 - Grafana:
http://localhost:3001(login: admin / admin)
cd calculator_grpc
go mod tidyDefault password:
mysecretpassword(used inserver.go)
go run server.goIn a separate terminal:
go run poller/poller.gocd calculator_rest
npm installnode index.js- Exposes
GET /last-record - Exposes Prometheus metrics at:
http://localhost:3000/metrics
You can use a gRPC client, or run the CLI client in calculator_grpc/client/main.go.
Example:
grpcurl -plaintext -d '{"num1": 3, "num2": 4}' localhost:50051 CalculatorService/Add๐ Prometheus (http://localhost:9090)
Try queries like:
messages_consumed_totalrate(messages_consumed_total[1m])histogram_quantile(0.95, rate(kafka_message_latency_seconds_bucket[1m]))
๐ Grafana (http://localhost:3001)
-
Add Prometheus data source (URL:
http://host.docker.internal:9090) -
Create dashboards with:
messages_consumed_totalkafka_message_latency_seconds
To run load tests on the gRPC API:
cd k6_testing
k6 run test.jsEnsure gRPC server is running locally or exposed on the target port.
- Outbox pattern ensures reliable delivery from DB to Kafka.
- Latency is calculated using production timestamp inside Kafka message and time of consumption.
- Prometheus scrapes metrics from REST container's
/metricsendpoint.
- Add retry mechanism and dead-letter queue
- Add persistent volume claims for stateful services
- Visualize latency per operation (add, subtract, etc.)
- full Kubernetes deployment
Abdelrahman Hedia
MIT License