Artikel ini tersedia dalam Bahasa Inggris

๐Ÿ‡ฌ๐Ÿ‡ง Read in English

26 Mei 2026

๐Ÿ‡ฎ๐Ÿ‡ฉ Bahasa Indonesia

Fleet Management Part 7: Dari Monolith ke Microservices

Mentransformasi monolith menjadi microservices. Service boundaries, komunikasi antar-service, API gateway, saga pattern, dan kapan TIDAK menggunakan microservices.

3 min read

Apa itu Microservices?

Monolith = Satu restoran di mana satu chef memasak semuanya. Jika chef sakit, seluruh restoran tutup.

Microservices = Food court dengan gerai spesialisasi. Satu gerai bikin pizza, satu bikin sushi, satu bikin kopi. Jika gerai pizza tutup maintenance, Anda tetap bisa dapat sushi dan kopi.

Monolith: Microservices: โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Semuanya โ”‚ โ”‚Pizza โ”‚ โ”‚Sushi โ”‚ โ”‚Kopi โ”‚ โ”‚ dalam satu โ”‚ โ†’ โ”‚Gerai โ”‚ โ”‚Gerai โ”‚ โ”‚Gerai โ”‚ โ”‚ aplikasi โ”‚ โ””โ”€โ”€โ”ฌโ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”ฌโ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”ฌโ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ–ผโ”€โ”€โ”€โ” โ”Œโ”€โ”€โ–ผโ”€โ”€โ”€โ” โ”Œโ”€โ”€โ–ผโ”€โ”€โ”€โ” โ”‚ DB 1 โ”‚ โ”‚ DB 2 โ”‚ โ”‚ DB 3 โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Kapan TIDAK Menggunakan Microservices (Perspektif Senior)

Ini bagian terpenting. Kebanyakan tutorial mengajarkan cara membangun microservices tapi tidak pernah mengajarkan kapan tidak.

FaktorGunakan MonolithGunakan Microservices
Ukuran tim1-5 developer10+ developer
Kompleksitas domainFitur sederhana, terkaitDomain berbeda, independen
Kebutuhan skalaBeban seragamBeberapa bagian butuh 10x resource
OrganisasiSatu timTim otonom multiple

Mengapa Kita Pilih Hybrid (3 Service, Bukan 30)

  1. Fleet API (NestJS) โ€” CRUD armada, auth, perencanaan rute
  2. Admin Service (Laravel) โ€” Admin panel internal, invoice, jadwal
  3. Telemetry Service (NestJS) โ€” Ingesti GPS, monitoring BBM, alert

Ini terpisah karena:

  • Frekuensi update berbeda โ€” Telemetri berubah mingguan, admin panel bulanan
  • Kebutuhan scaling berbeda โ€” Telemetri proses 1000+ pesan/menit, admin 10 user
  • Kebutuhan tech berbeda โ€” Telemetri butuh PostgreSQL + Redis, admin butuh MySQL + Filament

Komunikasi Antar-Service

1. Sinkron (REST) โ€” Request-Response

@Injectable()
export class TelemetryClient {
  async getVehiclePosition(truckId: string): Promise<Position> {
    const { data } = await this.httpService.axiosRef.get(
      `${TELEMETRY_URL}/api/telemetry/position/${truckId}`,
      { timeout: 3000 }, // Selalu set timeout!
    );
    return data;
  }
}

2. Asinkron (Message Queue) โ€” Event-Driven

// Telemetry Service mempublikasi event
await this.redis.publish('telemetry:gps-update', JSON.stringify({
  truckId, lat, lng, speed, timestamp: Date.now(),
}));

// Fleet API berlangganan event
this.redis.subscribe('telemetry:gps-update', (message) => {
  const data = JSON.parse(message);
  this.wsGateway.broadcastPosition(data);
});

API Gateway Pattern

server {
    location /api/vehicles { proxy_pass http://fleet_api; }
    location /api/telemetry { proxy_pass http://telemetry_api; }
    location /admin { proxy_pass http://admin_api; }
}

Frontend hanya kenal satu URL. SSL termination di satu tempat. Rate limiting diterapkan seragam.


Saga Pattern: Transaksi Terdistribusi

Bagian tricky dari microservices: transaksi yang meliputi beberapa service.

1. Fleet API: Assign driver ke kendaraan โœ… โ†’ Publish event "driver.assigned" 2. Admin Service: Terima event, buat invoice โŒ GAGAL! โ†’ Publish event "invoice.failed" 3. Fleet API: Terima "invoice.failed", rollback assignment driver
// Kompensasi saat gagal
@OnEvent('invoice.failed')
async handleInvoiceFailed(event: InvoiceFailedEvent) {
  const vehicle = await this.vehicleRepo.findOneOrFail(event.vehicleId);
  vehicle.currentDriverId = null;
  await this.vehicleRepo.save(vehicle);
  this.logger.warn(`Rollback assignment driver untuk kendaraan ${event.vehicleId}`);
}

Circuit Breaker: Menangani Kegagalan Service

class CircuitBreaker {
  private failures = 0;
  private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';

  async call<T>(fn: () => Promise<T>, fallback: T): Promise<T> {
    if (this.state === 'OPEN') {
      if (Date.now() - this.lastFailure > this.resetTimeout) {
        this.state = 'HALF_OPEN';
      } else {
        return fallback; // Langsung return fallback
      }
    }
    try {
      const result = await fn();
      this.onSuccess();
      return result;
    } catch {
      this.onFailure();
      return fallback;
    }
  }
}

Kesalahan Microservices Umum

Kesalahan 1: Distributed Monolith

Jika setiap perubahan service membutuhkan deploy semua service lainnya, Anda punya distributed monolith โ€” semua kompleksitas microservices tanpa manfaatnya.

Kesalahan 2: Shared Database

Jika dua service baca/tulis ke tabel database yang sama, mereka bukan service terpisah sebenarnya.

Kesalahan 3: Terlalu Banyak Service Terlalu Dini

Mulai dengan 2-3 service yang terdefinisi jelas. Anda selalu bisa memecah kemudian.


Selanjutnya

Di Part 8, kita akan bahas DevSecOps โ€” setup pipeline CI/CD dengan GitHub Actions, security scanning, Docker, dan deployment production.


Ini adalah Part 7 dari seri Fleet Management System. Memahami microservices bukan tentang mengetahui pattern-nya โ€” tapi tentang mengetahui kapan menerapkannya dan kapan menahan diri.

Lanjut Membaca

Previous article thumbnail

โ† Artikel Sebelumnya

Fleet Management Part 6: SOLID Principles & Design Patterns in Practice

Artikel Selanjutnya โ†’

Fleet Management Part 8: DevSecOps, CI/CD & Production Deployment

Next article thumbnail