19.1 Arsitektur Tidak Berhenti di Diagram

Saya pernah melihat tim menghabiskan dua minggu mendiskusikan diagram arsitektur yang sangat rapi. Setiap kotak, garis, dan panah digambar dengan presisi. Warnanya konsisten. Labelnya jelas. Semua orang setuju bahwa ini adalah desain yang bagus.

Lalu datang pertanyaan pertama saat implementasi: “Bagaimana cara deploy service ini di production?”

Ruangan tiba-tiba hening. Ternyata tidak ada yang memikirkan environment mana yang akan dipakai. Tim infrastruktur belum diajak bicara. Konfigurasi database masih berupa placeholder. Dan tidak ada yang tahu bagaimana service baru ini akan berkomunikasi dengan sistem lama yang ternyata masih berjalan di server fisik tanpa container.

Diagram itu tidak salah. Tapi arsitektur tidak berhenti di diagram.

Inilah kesenjangan yang sering terjadi: desain terlihat sempurna di atas kertas, tetapi tidak bisa dioperasikan. Arsitek yang baik tidak hanya menggambar, tetapi juga memastikan bahwa apa yang digambar bisa dikirim, dijalankan, diamati, dan diperbaiki. Dalam istilah teknis, ini disebut operability — kemampuan sebuah sistem untuk dioperasikan secara andal dan efisien di lingkungan nyata.

Operability bukan urusan tim operasional saja. Ini adalah keputusan arsitektur. Ketika seorang arsitek memilih pola komunikasi sinkron dengan REST, dia harus tahu bahwa pola itu membutuhkan service discovery, retry logic, circuit breaker, dan timeout yang tepat. Ketika dia memilih event-driven architecture, dia harus siap dengan konsekuensi: message broker, dead letter queue, monitoring backlog, dan mekanisme replay. Semua ini adalah bagian dari desain, bukan tambahan yang bisa diputuskan belakangan.

Berikut contoh konfigurasi Istio VirtualService yang mendefinisikan retry policy, circuit breaker, dan health check endpoint untuk service REST.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
  - order-service
  http:
  - match:
    - uri:
        prefix: /api/orders
    route:
    - destination:
        host: order-service
        port:
          number: 8080
      weight: 100
    retries:
      attempts: 3
      perTryTimeout: 2s
      retryOn: connect-failure,refused-stream,503
    timeout: 10s
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: order-service-circuit-breaker
spec:
  host: order-service
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        http1MaxPendingRequests: 10
        maxRequestsPerConnection: 10
    outlierDetection:
      consecutive5xxErrors: 5
      interval: 30s
      baseEjectionTime: 60s
      maxEjectionPercent: 50

Berikut adalah ilustrasi kesenjangan antara diagram arsitektur dan realitas operasional yang harus diantisipasi.

flowchart TD A[Diagram Arsitektur] --> B[Implementasi] B --> C{Service Communication} C --> D[REST] C --> E[Event-Driven] D --> F[Service Discovery] D --> G[Retry Logic] D --> H[Circuit Breaker] D --> I[Timeout] E --> J[Message Broker] E --> K[Dead Letter Queue] E --> L[Monitoring Backlog] E --> M[Replay Mechanism] F --> N[Operability] G --> N H --> N I --> N J --> N K --> N L --> N M --> N

Deployment, environment, dan konfigurasi adalah tiga area yang paling sering diabaikan saat mendesain. Sebuah service mungkin dirancang dengan asumsi environment yang bersih dan seragam. Kenyataannya, organisasi biasanya memiliki beberapa environment: development, staging, production, dan mungkin juga sandbox untuk eksperimen. Masing-masing punya karakteristik berbeda — ukuran database, kapasitas CPU, network latency, dan kebijakan akses. Arsitek perlu memastikan bahwa desainnya bisa berjalan di semua environment itu tanpa perubahan besar.

Konfigurasi juga sering menjadi sumber masalah. Kode yang sama harus bisa berjalan di environment berbeda dengan konfigurasi yang berbeda. Jika konfigurasi dikeraskan di dalam kode, setiap deployment ke environment baru membutuhkan perubahan kode. Ini lambat, rawan kesalahan, dan membuat tim deployment frustrasi. Arsitek perlu mendesain agar konfigurasi dipisahkan dari kode — baik melalui environment variables, configuration service, atau mekanisme lain yang sesuai dengan konteks organisasi.

Seorang arsitek yang baik tidak menyerahkan diagram lalu pergi. Dia mengikuti bagaimana desainnya diimplementasikan, bagaimana service dideploy, bagaimana konfigurasi dikelola, dan bagaimana tim mengatasi masalah saat pertama kali menjalankan sistem di production. Dia belajar dari gesekan yang muncul dan memperbaiki desain untuk iterasi berikutnya.

Kesenjangan antara desain dan delivery ini harus ditutup. Dan salah satu alat paling ampuh untuk menutupnya adalah jalur pemrosesan yang menghubungkan keputusan arsitektur dengan praktik engineering sehari-hari. Di subbab berikutnya, kita akan melihat bagaimana CI/CD jalur pemrosesan bukan hanya urusan tim development, tetapi juga alat bagi arsitek untuk menjaga konsistensi keputusan desain dari kode hingga production.