Dobrodošli u peti deo serijala na ITNetwork.rs! Do sada smo prošli kroz monolit i mikroservise, frontend (SPA/SSR/SSG), API-je (REST/GraphQL/gRPC) i baze podataka (polyglot, CQRS, Event Sourcing). Sada ulazimo u srž mikroservisne arhitekture – kako pravilno podeliti sistem na servise, kako oni komuniciraju, i kako upravljati haosom distribuiranog sistema.
Šta su mikroservisi – podsetnik
„Mikroservis je nezavisna, samostalno deploy-ovana jedinica koja rešava jedan poslovni problem i komunicira preko jasno definisanih interfejsa.“ — Sam Newman, „Building Microservices“
| Karakteristika | Objašnjenje |
|---|---|
| Jedan domen | „Korisnici“, „Porudžbine“, „Plaćanje“ |
| Vlasništvo tima | „You build it, you run it“ |
| Nezavisni deploy | Bez koordinacije sa drugim timovima |
| Sopstvena baza | Nema deljene tabele |
Loš pristup: Podela po tehnologiji
Frontend servis → React
Backend servis → Node.js
Baza servis → PostgreSQL
Pravi pristup: Domain-Driven Design (DDD)
Bounded Context
„Jasno definisana granica unutar koje model ima smisao.“
| Bounded Context | Servis |
|---|---|
| Korisničko upravljanje | user-service |
| Katalog proizvoda | catalog-service |
| Proces naručivanja | order-service |
| Plaćanje | payment-service |
2. Komunikacija između servisa
| Tip | Protokol | Kada koristiti |
|---|---|---|
| Sinhrona | HTTP/REST, gRPC | Brzi odgovor, zahteva rezultat |
| Asinhrona | Message Queue (RabbitMQ, Kafka) | Eventual consistency, skalabilnost |
Sinhrona komunikacija (Request/Response)

Problem: Ako PaymentService padne → OrderService čeka → kaskadni pad
Asinhrona komunikacija (Event-Driven)

Prednost: Servisi su otporni na pad drugih
3. Ključni obrasci u komunikaciji
| Obrazac | Alat | Primer |
|---|---|---|
| Service Discovery | Consul, Eureka, Kubernetes DNS | payment-service.svc.cluster.local |
| Circuit Breaker | Resilience4j, Polly, Istio | „Ne zovi servis ako je 5x pao“ |
| Retry & Timeout | Axios-retry, gRPC retry | Pokušaj 3x, čekaj 100ms |
| Bulkhead | Semaphore | „Samo 10 paralelnih poziva ka servisu“ |
import CircuitBreaker from 'opossum';
const breaker = new CircuitBreaker(async (userId: number) => {
const res = await fetch(`http://payment-service/charge/${userId}`);
if (!res.ok) throw new Error('Payment failed');
return res.json();
}, {
timeout: 3000,
errorThresholdPercentage: 50,
resetTimeout: 30000
});
breaker.fallback(() => ({ status: 'degraded', message: 'Try later' }));
// Korišćenje
const result = await breaker.fire(userId);
docker-compose.yml
version: '3.8'
services:
user-service:
build: ./services/user
ports: ["3001:3000"]
environment:
- DB_URL=postgresql://postgres:pass@db:5432/users
depends_on: [db, rabbitmq]
order-service:
build: ./services/order
ports: ["3002:3000"]
depends_on: [rabbitmq, db]
payment-service:
build: ./services/payment
ports: ["3003:3000"]
depends_on: [rabbitmq]
rabbitmq:
image: rabbitmq:3-management
ports: ["5672:5672", "15672:15672"]
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: pass
POSTGRES_MULTIPLE_DATABASES: users,orders
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Pokretanje: docker-compose up –build
5. Praktičan primer: Dva mikroservisa sa RabbitMQ
1. user-service → emituje UserCreated
// user-service/src/events.ts
import amqplib from 'amqplib';
const conn = await amqplib.connect('amqp://rabbitmq');
const channel = await conn.createChannel();
await channel.assertExchange('user.events', 'fanout');
export const publishUserCreated = (user: any) => {
channel.publish('user.events', '', Buffer.from(JSON.stringify({
type: 'UserCreated',
user
})));
};
2. notification-service → prima i šalje email
// notification-service/src/consumer.ts
channel.consume('user_queue', async (msg) => {
if (msg) {
const event = JSON.parse(msg.content.toString());
if (event.type === 'UserCreated') {
await sendWelcomeEmail(event.user.email);
}
channel.ack(msg);
}
});
| Izazov | Rešenje |
|---|---|
| Distribuirane transakcije | Saga Pattern, Eventual Consistency |
| Praćenje grešaka | Distributed Tracing (Jaeger, OpenTelemetry) |
| Verzionisanje API-ja | Consumer-Driven Contracts (Pact) |
| Testiranje | Contract Testing, E2E sa Testcontainers |
| Deployment haos | GitOps, ArgoCD, Progressive Delivery |
Poređenje: Monolit vs Mikroservisi
| Aspekt | Monolit | Mikroservisi |
|---|---|---|
| Brzina razvoja (početak) | ★★★★★ | ★★ |
| Skalabilnost | ★★ | ★★★★★ |
| Nezavisni deploy | ✗ | ✓ |
| Tehnološka sloboda | ✗ | ✓ |
| Operativni trošak | ★★★★★ | ★★ |
| Tim veličina | Mali | Srednji+ |
| Situacija | Preporuka |
|---|---|
| 1–3 developera, MVP | Monolit |
| 5+ timova, 10+ funkcionalnosti | Mikroservisi |
| Potreba za Go/Rust/Python po servisu | Mikroservisi |
| Česta downtime zbog jedne izmene | Mikroservisi |
Zlatno pravilo: „Prvo napravi monolit koji radi. Zatim ga razbij – ako i samo ako osetiš bol.“
Šta dalje?
U šestom delu ulazimo u serverless i edge computing:
- AWS Lambda, Vercel, Cloudflare Workers
- Hladni start, troškovi
- Edge funkcije
Tvoj izazov
- Napravi dva servisa sa docker-compose:
- order-service → kreira porudžbinu
- email-service → prima OrderCreated preko RabbitMQ
- Deploy-uj na Render, Fly.io ili Railway
- Komentariši ispod: „Koliko mikroservisa ima tvoj trenutni projekat?“
Autor: Dušan Antonijević – saradnik ITNetwork.rs
Hvala na čitanju! Podeli tekst sa kolegama.



