[{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/articles/","section":"Articles","summary":"","title":"Articles","type":"articles"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/concurrency/","section":"Tags","summary":"","title":"Concurrency","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/garbage-collection/","section":"Tags","summary":"","title":"Garbage-Collection","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/jvm/","section":"Tags","summary":"","title":"Jvm","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/series/jvm--tomcat-performance-engineering/","section":"Series","summary":"","title":"JVM \u0026 Tomcat Performance Engineering","type":"series"},{"content":" 📌 Ringkasan Eksekutif (TL;DR) # Dalam praktik pemantauan sistem berbasis Java Virtual Machine (JVM) seperti Apache Tomcat, banyak tim operasional terjebak pada pendekatan naif: memasang alert peringatan saat CPU Usage \u0026gt; 80% atau Heap Memory Usage \u0026gt; 80%. Ambang batas statis mentah (static raw thresholds) ini adalah sumber utama kebisingan peringatan palsu (alert fatigue). Karakteristik JVM yang generasional secara alami akan mengisi memori hingga 90% sebelum membersihkannya melalui Garbage Collection (GC), dan lonjakan thread sesaat adalah mekanisme normal penyerapan lonjakan trafik (burst traffic elasticity).\nSebaliknya, metrik agregat CPU dan memori biasa sering kali gagal mendeteksi krisis mematikan. CPU host mungkin hanya terlihat terpakai 40%, tetapi aplikasi telah membeku total selama 5 detik akibat Stop-The-World (STW) GC pause. Begitu pula sebaliknya: memori heap tampak berfluktuasi normal, tetapi thread pool Tomcat telah mengalami kejenuhan 100% (thread starvation) sehingga antrean request baru ditolak (rejected execution).\nArtikel ini mengulas mengapa arsitektur observabilitas kami secara resmi menolak ambang batas statis mentah melalui TM-ADR-0022, bagaimana kami merancang Sinyal Emas GC (GC Golden Signals) dan Indikator Kejenuhan Konkurensi (Concurrency Saturation Indicators), serta formula PromQL konkret siap pakai yang diadopsi dari operasional nyata platform Tomcat Monitoring.\n🌍 Latar Belakang \u0026amp; Real-World Problem: Jebakan Ambang Batas Statis Mentah # Setiap engineer yang pernah memegang pager on-call pasti akrab dengan dua skenario frustrasi berikut:\nAlarm Palsu Tengah Malam (The 03:00 AM Phantom Alert):\nPager berdering kencang dengan pesan TomcatHeapMemoryHigh: used \u0026gt; 80%. SRE terbangun, membuka laptop dengan tergesa, lalu mendapati grafik penggunaan heap sudah kembali anjlok ke 30%. Skenario ini berulang setiap siklus GC minor selesai. Akibatnya, tim on-call mulai mengabaikan alert, mematikan notifikasi, atau menaikkan ambang batas secara serampangan. Krisis Senyap yang Tidak Terdeteksi (The Silent Outage):\nPengguna mengeluhkan transaksi checkout perbankan mengalami timeout massal. Tim operasional mengecek dashboard infrastruktur utama: CPU utilization hanya 50%, memori fisik tersisa 12 GB. Tidak ada alert yang berbunyi! Namun di balik layar, siklus Full GC sedang mengalami thrashing—menghabiskan 85% siklus eksekusi thread hanya untuk mencari ruang memori yang tidak pernah ada, membekukan seluruh pemrosesan servlet (cascading backlog). Warning Metrik kapasitas mentah (seperti Gigabyte memori atau persentase CPU OS) hanya mengukur kuantitas ruang yang dialokasikan, bukan kualitas waktu eksekusi dan efisiensi kerja aplikasi.\n🔍 Analisis Masalah \u0026amp; Dilema Teknis: Mengapa Metrik Standar Menipu? # Untuk memahami mengapa pendekatan ambang batas statis mentah gagal di lingkungan produksi, kita perlu membedah internal runtime JVM dan arsitektur model konkurensi Apache Tomcat.\nflowchart TD subgraph NAIVE[\"Pendekatan Konvensional (Naif)\"] M1[\"Heap Usage \u003e 80%\"] --\u003e F1[\"False Alarm saat GC Normal\"] M2[\"CPU Usage \u003e 80%\"] --\u003e F2[\"Gagal deteksi STW Latency saat CPU Rendah\"] M3[\"Active Threads \u003e 80%\"] --\u003e F3[\"False Alarm saat Spike Trafik Singkat\"] end subgraph SATURATION[\"Pendekatan Saturation-Based (TM-ADR-0022)\"] S1[\"GC STW Latency \u003e 1.5s\"] --\u003e D1[\"Deteksi Freeze Nyata Pengguna\"] S2[\"GC Overhead CPU \u003e 15%\"] --\u003e D2[\"Deteksi Thrashing \u0026 CPU Terbuang\"] S3[\"Old Gen Retention \u003e 90% (Post-GC)\"] --\u003e D3[\"Deteksi Kebocoran Memori Nyata (Leak)\"] S4[\"Thread Saturation 100% (Sustained 5m)\"] --\u003e D4[\"Deteksi Antrean Macet / Starvation\"] end 1. Siklus Alokasi Memori Generasional JVM (Generational Heap Dynamic) # Runtime modern Java (G1GC, ZGC, ParallelGC) membagi heap space ke dalam beberapa generasi:\nYoung Generation (Eden \u0026amp; Survivor Spaces): Tempat objek baru dibuat. Sebagian besar objek Java berusia sangat pendek (ephemeral) dan mati dalam hitungan milidetik. Old Generation (Tenured Space): Tempat objek berumur panjang yang bertahan melewati beberapa siklus alokasi (promotion). Ketika aplikasi aktif melayani trafik, ruang Eden akan terisi sangat cepat hingga 90%–95%. Ini adalah perilaku alokasi optimal, bukan anomali. Mengirim alert ketika heap menyentuh 80% sama saja dengan membunyikan alarm kebakaran setiap kali mesin mobil membakar bahan bakar saat berakselerasi.\nKrisis memori yang sesungguhnya baru terjadi jika:\nOld Generation Pool Saturation: Ruang Old Gen tetap penuh ($\u0026gt;90%$) bahkan setelah siklus Full GC selesai dieksekusi. Ini adalah indikator kuat terjadinya kebocoran memori (memory leak atau unclosed connection cache). GC Thrashing: GC berjalan berulang-ulang tanpa henti namun gagal merebut kembali ruang memori yang cukup (GC overhead limit exceeded). 2. Elastisitas Alami Thread Pool Tomcat (Burst Traffic Elasticity) # Tomcat mengelola request HTTP melalui thread pool executor (standar konektor NIO/NIO2). Ketika promosi flash sale atau batch request masuk serentak:\nJumlah thread aktif (busy threads) wajar melonjak dari 15 ke 180 thread dalam beberapa detik untuk menguras antrean TCP socket. Begitu servlet selesai mengirimkan response HTTP, worker thread langsung kembali ke status idle. Jika alert dikonfigurasikan dengan tomcat_threads_busy \u0026gt; 80% tanpa jeda durasi, sistem akan membunyikan ratusan peringatan setiap kali terjadi lonjakan trafik wajar. Sebaliknya, kondisi kritis baru terjadi jika thread pool mencapai kejenuhan total 100% dan bertahan persisten (sustained saturation), atau saat request mulai ditolak (task rejection).\n🏛️ Solusi \u0026amp; Desain Arsitektur: Sinyal Kejenuhan Beban Nyata (TM-ADR-0022) # Melalui keputusan arsitektur TM-ADR-0022, platform pemantauan kami meninggalkan ambang batas statis dan mengadopsi model Workload Saturation Signals.\nflowchart LR subgraph SCRAPE[\"JMX Exporter (Port 9404)\"] JMX[\"JVM MBeans Telemetry\"] --\u003e|TLS Keystore| PROM[\"Prometheus Scraper\"] end subgraph SIGNALS[\"Evaluasi Sinyal Emas\"] PROM --\u003e GC_LAT[\"1. STW Pause Latency (\u003e 1.5s)\"] PROM --\u003e GC_OVR[\"2. GC CPU Overhead (\u003e 15%)\"] PROM --\u003e GC_OLD[\"3. Old Gen Post-GC Retention (\u003e 90%)\"] PROM --\u003e TH_SAT[\"4. Sustained Thread Saturation (100% for 5m)\"] end subgraph ACTION[\"Triage Deterministik\"] GC_LAT --\u003e DS[\"Diagnostic Service(Domain: jvm_memory)\"] GC_OVR --\u003e DS GC_OLD --\u003e DS TH_SAT --\u003e DS_TH[\"Diagnostic Service(Domain: concurrency_threading)\"] end 1. Empat Sinyal Emas Garbage Collection (The 4 GC Golden Signals) # Alih-alih mengukur volume memori total, evaluasi kesehatan JVM kami didasarkan pada empat pilar:\nSinyal Emas GC Pertanyaan Operasional yang Dijawab Metrik Kunci Ambang Batas Rekomendasi GC STW Latency Berapa lama aplikasi benar-benar \u0026ldquo;membeku\u0026rdquo; dan berhenti melayani transaksi pengguna? jvm_gc_pause_seconds_max $\u0026gt; 1.5\\text{s}$ (Warning), $\u0026gt; 2.5\\text{s}$ (Critical) GC CPU Overhead Berapa persen kapasitas prosesor yang terbuang sia-sia hanya untuk membersihkan memori? rate(jvm_gc_pause_seconds_sum[5m]) * 100 $\u0026gt; 15%$ (Warning), $\u0026gt; 30%$ (Critical) Old Gen Retention Berapa banyak memori jangka panjang yang tertahan persisten tanpa bisa dibebaskan? jvm_memory_pool_used_bytes{pool=~\u0026quot;.*Old.*\u0026quot;} $\u0026gt; 90%$ bertahan $\u0026gt; 10\\text{ menit}$ Major GC Rate Apakah JVM panik dan memicu Full GC berulang kali dalam interval singkat? rate(jvm_gc_pause_seconds_count{action=~\u0026quot;.*major.*\u0026quot;}[5m]) $\u0026gt; 0.1\\text{ ops/sec}$ (Anomali) 2. Tiga Indikator Kejenuhan Konkurensi (The 3 Concurrency Indicators) # Untuk konektor HTTP Tomcat, kami memantau saturasi antrean kerja:\nSustained 100% Saturation: Rasio worker thread sibuk mencapai kapasitas maksimum dan bertahan terus-menerus selama minimal 5 menit (for: 5m). Task Rejection Spike: Terjadinya penolakan request baru pada tingkat executor (rejectedExecution \u0026gt; 0). Ini berarti backlog queue TCP telah meluap. Thread Starvation / Deadlock: Jumlah thread yang berstatus BLOCKED atau WAITING pada sinkronisasi lock internal meningkat tajam. 📊 SRE PromQL Cheatsheet \u0026amp; Alerting Rules Siap Pakai # Berikut adalah kumpulan kueri PromQL operasional yang diadopsi dari RUNBOOK.md dan aturan deteksi produksi:\nA. Memantau Retensi Old Generation (Deteksi Memory Leak) # # Persentase utilisasi memori pada pool Old Generation (G1 Old Gen / Tenured Gen) ( jvm_memory_pool_used_bytes{pool=~\u0026#34;.*Old.*\u0026#34;} / jvm_memory_pool_max_bytes{pool=~\u0026#34;.*Old.*\u0026#34;} ) * 100 \u0026gt; 90 Note Alert ini wajib dipasangkan dengan klausul for: 10m agar siklus pembersihan GC alami tidak memicu alarm palsu sesaat.\nB. Menghitung GC Overhead (% Waktu CPU yang Terbuang untuk GC) # # Persentase waktu CPU yang dikonsumsi oleh Garbage Collection dalam 5 menit terakhir (rate(jvm_gc_pause_seconds_sum[5m]) * 100) \u0026gt; 15 Jika metrik ini melebihi 15%, berarti dari setiap 100 detik komputasi prosesor, 15 detik habis hanya untuk menghentikan dunia (Stop-The-World). Jika menyentuh 85%, JVM berada di ambang java.lang.OutOfMemoryError: GC overhead limit exceeded.\nC. Menangkap Puncak Jeda STW (Max Stop-The-World Pause) # # Durasi jeda GC terpanjang yang tercatat jvm_gc_pause_seconds_max \u0026gt; 1.5 D. Mengukur Kejenuhan Thread Pool Tomcat (Sustained Saturation) # # Rasio thread pool Tomcat yang sibuk mencapai 100% kapasitas maksimum ( tomcat_threads_busy_threads / tomcat_threads_current_threads ) * 100 == 100 Pasangkan dengan for: 5m dalam Prometheus alert rule:\n- alert: TomcatThreadPoolSaturated expr: (tomcat_threads_busy_threads / tomcat_threads_current_threads) * 100 == 100 for: 5m labels: severity: critical category: concurrency_threading annotations: summary: \u0026#34;Tomcat connector thread pool 100% saturated on {{ $labels.instance }}\u0026#34; description: \u0026#34;Thread pool has been completely exhausted for over 5 minutes. Application is likely deadlocked or backlogged.\u0026#34; 💡 Pelajaran Praktis: SRE \u0026amp; Performance Tuning Best Practices # Penerapan prinsip sinyal kejenuhan ini menghasilkan sejumlah rekomendasi operasional penting:\n1. Pisahkan Tanggung Jawab Liveness dari Workload Health # Jangan gunakan metrik JMX untuk menguji apakah aplikasi Tomcat hidup atau mati.\nLiveness \u0026amp; Application Availability: Uji menggunakan probe HTTP eksternal (misal: Telegraf / Blackbox Exporter ke endpoint GET :8080/health). Internal Workload Health: Gunakan JMX Exporter murni untuk melacak degradasi laten (GC thrashing, memory leak, pool saturation). 2. Jangan Terburu-buru Me-Restart Saat Thread Pool Jenuh # Mengacu pada kebijakan Zero Destructive Auto-Remediation (TM-ADR-0014), me-restart Tomcat seketika saat thread jenuh adalah kesalahan fatal:\nAmbil Thread Dump Segera: Sebelum proses dimatikan, jalankan perintah diagnostik untuk melihat apa yang sedang ditunggu oleh ratusan thread: # Ambil 3 kali thread dump dengan jeda 5 detik untuk analisis deadlock for i in 1 2 3; do jcmd \u0026lt;PID\u0026gt; Thread.print \u0026gt; /tmp/thread_dump_$i.txt; sleep 5; done Periksa Upstream \u0026amp; Database Dependency: Sering kali thread Tomcat jenuh bukan karena kode Java yang buruk, melainkan karena connection pool basis data (HikariCP) kehabisan koneksi akibat query SQL yang terkunci (row lock timeout). 3. Kendalikan Overhead JMX Exporter (\u0026lt;1-2% CPU) # Memantau ribuan MBeans secara serampangan dapat membebani runtime JVM. Batasi aturan penarikan pada berkas jmx-exporter.yml hanya pada metrik yang relevan (java.lang:type=Memory, java.lang:type=GarbageCollector, dan Catalina:type=ThreadPool).\n📋 Kesimpulan \u0026amp; Checklist Triage # Beralih dari metrik kapasitas statis mentah menuju sinyal kejenuhan beban nyata (workload saturation signals) adalah langkah kunci untuk membebaskan tim operasional dari lingkaran setan alert fatigue. Peringatan yang akurat bukan yang berbunyi paling cepat saat trafik naik, melainkan peringatan yang berbunyi ketika sistem benar-benar mengalami degradasi layanan yang dirasakan oleh pengguna akhir.\n🛠️ Checklist Triage SRE Saat Menerima Alert GC atau Concurrency # 1. Verifikasi Gejala Latensi Pengguna:\nCek dashboard HTTP response time dan error rate (5xx). Apakah jeda GC berdampak langsung pada timeout request pengguna? 2. Evaluasi Sifat Kejenuhan (Transien vs Persisten):\nApakah tomcat_threads_busy_threads kembali turun setelah burst lalu lintas selesai, ataukah tertahan di 100% selama lebih dari 5 menit? 3. Periksa Post-GC Heap Baseline:\nAmati grafik memori Old Gen setelah siklus GC selesai. Jika garis bawah (trough) terus merangkak naik secara linier, siapkan investigasi heap dump untuk kebocoran memori. 4. Ambil Thread Dump Sebelum Restart Manual:\nJika thread pool mengalami kebuntuan (deadlock), abadikan status thread dengan jcmd \u0026lt;PID\u0026gt; Thread.print sebelum mengambil tindakan mitigasi manual. 5. Tinjau Log Diagnostik Terpusat:\nPeriksa laporan notifikasi 7-seksi dari Diagnostic Service (TM-ADR-0016) untuk melihat klasifikasi root cause otomatis (GC-01 .. GC-04 atau TH-01 .. TH-03). 📚 Referensi Terkait # TM-ADR-0022: Adopt JVM Garbage Collection and Concurrency Saturation Signals over Static Raw Thresholds TM-ADR-0014: Enforce Zero Automatic Remediation for Diagnostic Service TM-ADR-0016: Designate Diagnostic Service as the Canonical Incident Notification Authority DevOps Engineering Handbook Online Tomcat Monitoring Platform SRE Operational Runbook ","date":"19 September 2026","externalUrl":null,"permalink":"/articles/mendeteksi-concurrency-saturation-dan-gc-thrashing/","section":"Articles","summary":"Membongkar jebakan ambang batas statis mentah pada Java Virtual Machine dan bagaimana sinyal saturasi beban nyata (GC Golden Signals \u0026 Concurrency Saturation) mencegah alert fatigue dan cascading outage di Apache Tomcat.","title":"Mendeteksi Concurrency Saturation \u0026 GC Thrashing: Jangan Hanya Mengandalkan Metrik CPU \u0026 Memory Biasa","type":"articles"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/categories/observability/","section":"Categories","summary":"","title":"Observability","type":"categories"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/categories/performance/","section":"Categories","summary":"","title":"Performance","type":"categories"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/prometheus/","section":"Tags","summary":"","title":"Prometheus","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/promql/","section":"Tags","summary":"","title":"Promql","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/categories/sre/","section":"Categories","summary":"","title":"SRE","type":"categories"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/sre-best-practices/","section":"Tags","summary":"","title":"Sre-Best-Practices","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/tomcat/","section":"Tags","summary":"","title":"Tomcat","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/alertmanager/","section":"Tags","summary":"","title":"Alertmanager","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/architecture/","section":"Tags","summary":"","title":"Architecture","type":"tags"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/categories/devops/","section":"Categories","summary":"","title":"DevOps","type":"categories"},{"content":" Platform Engineering · SRE · DevOps Architecture\nJurnal rekayasa, studi kasus sistem berskala enterprise, dan dokumentasi arsitektur teknis — dari Autonomous Incident Diagnostics hingga Hybrid-Cloud Fleet Automation.\nFokus Rekayasa # 🛡️ Autonomous Incident Diagnostics \u0026amp; SRE Governance Menerapkan kebijakan Zero Destructive Auto-Remediation, korelasi bukti forensik deterministik multi-sumber, serta format laporan kanonikal 7-seksi untuk tim on-call.\n📊 JVM \u0026amp; Deep Workload Observability Analisis GC Thrashing, latensi Stop-The-World, kejenuhan thread pool, dan instrumentasi metrik JMX Prometheus di lingkungan produksi nyata.\n🚀 Multi-OS Fleet Orchestration Portabilitas multi-engine — Podman rootless di Linux dan Docker di Windows Server — terpadu melalui CLI tmctl dan Ansible playbook.\n⚙️ Pipeline as Code \u0026amp; Immutable Delivery Ephemeral build environment berbasis container (DooD), artefak CI immutable, dan orkestrasi rilis terpisah antara Jenkins dan Ansible.\n","date":"19 September 2026","externalUrl":null,"permalink":"/","section":"Home","summary":" Platform Engineering · SRE · DevOps Architecture\nJurnal rekayasa, studi kasus sistem berskala enterprise, dan dokumentasi arsitektur teknis — dari Autonomous Incident Diagnostics hingga Hybrid-Cloud Fleet Automation.\n","title":"Home","type":"page"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/incident-response/","section":"Tags","summary":"","title":"Incident-Response","type":"tags"},{"content":" 📌 Ringkasan Eksekutif (TL;DR) # Ketika layanan mission-critical seperti Apache Tomcat mengalami kegagalan di production, insting pertama tim operasional sering kali adalah memicu mekanisme pemulihan otomatis (self-healing / auto-remediation)—seperti script watchdog yang mengeksekusi systemctl restart tomcat atau auto-restart container. Pendekatan ini tampak menarik karena menjanjikan penurunan drastis pada Mean Time to Recovery (MTTR) tanpa intervensi manusia.\nNamun, dalam arsitektur sistem enterprise modern, auto-restart tanpa diagnosis forensik adalah anti-pattern yang berbahaya. Tindakan perbaikan buta ini kerap memicu reboot loops, melenyapkan artefak diagnostik memori (heap dump dan crash log), melipatgandakan blast radius keamanan akibat kebutuhan privilege escalation, dan menyamarkan degradasi laten hingga berujung pada pemadaman total (catastrophic outage).\nArtikel ini mengulas alasan teknis mendasar mengapa arsitektur pemantauan Tomcat kami menetapkan kebijakan Zero Destructive Auto-Remediation (TM-ADR-0014), bagaimana kami mengisolasi mesin analisis dalam batas read-only yang ketat, dan bagaimana pola Canonical Incident Notification Authority (TM-ADR-0016) menyajikan laporan insiden terstruktur 7-seksi (7-Section SRE Incident Report) yang memberdayakan operator manusia (human-in-the-loop) untuk mengambil keputusan mitigasi yang tepat, terverifikasi, dan aman.\n🌍 Latar Belakang \u0026amp; Real-World Problem: Godaan Ilusi \u0026ldquo;Self-Healing\u0026rdquo; # Bayangkan skenario berikut: Pukul 02.15 dini hari, Prometheus mendeteksi target Tomcat tidak merespons dan memicu alert TomcatDown. Jika sistem dipasangi script otomatis yang langsung mengeksekusi restart ketika service mati, dua kemungkinan akan terjadi:\nKasus Transien: Jika matinya proses hanya akibat glitch sesaat, restart mungkin membuat service tampak normal kembali dalam hitungan detik. Kasus Struktural: Jika service mati karena konfigurasi server.xml yang rusak (syntax error), sertifikat TLS kedaluwarsa, kehabisan kapasitas disk (storage full), atau alokasi port yang konflik, perintah restart akan langsung gagal. Pada skenario kedua, script otomatis yang tidak memiliki kesadaran konteks (context-blind remediation) akan terus mencoba me-restart service berulang kali dalam hitungan detik (action flapping). Bukannya memulihkan keadaan, otomatisasi ini justru memperparah beban CPU dan I/O host, membanjiri koneksi database backend, dan mengaburkan jejak akar masalah yang sebenarnya.\nWarning Otomatisasi pemulihan yang dirancang untuk menangani kegagalan transien sering kali menjadi akselerator bencana ketika berhadapan dengan kegagalan sistemik (systemic architectural failures).\n🔍 Analisis Masalah: 4 Bahaya Fatal Auto-Restart di Production # Mengapa tindakan me-restart proses secara otomatis pada lapisan pemantauan awal membawa risiko katastropik? Berdasarkan kajian arsitektur kami, terdapat 4 bahaya teknis utama:\nflowchart TD FAIL[\u0026#34;Insiden Terdeteksi (TomcatDown)\u0026#34;] --\u0026gt; AR[\u0026#34;Tindakan Auto-Restart Otomatis\u0026#34;] AR --\u0026gt; R1[\u0026#34;1. Reboot Loop \u0026amp; Action Flapping\u0026lt;br/\u0026gt;(Beban Host \u0026amp; Badai Koneksi DB)\u0026#34;] AR --\u0026gt; R2[\u0026#34;2. Penghapusan Bukti Forensik\u0026lt;br/\u0026gt;(Hilangnya Heap Dump \u0026amp; Crash Log)\u0026#34;] AR --\u0026gt; R3[\u0026#34;3. Pelanggaran Least-Privilege\u0026lt;br/\u0026gt;(Eskalasi Root / Socket Exposure)\u0026#34;] AR --\u0026gt; R4[\u0026#34;4. Pemulihan Semu\u0026lt;br/\u0026gt;(Menutupi Memory Leak \u0026amp; Masalah Kronis)\u0026#34;] R1 --\u0026gt; DISASTER[\u0026#34;Downtime Diperpanjang \u0026amp; Kerusakan Data\u0026#34;] R2 --\u0026gt; DISASTER R3 --\u0026gt; DISASTER R4 --\u0026gt; DISASTER 1. Perulangan Kegagalan \u0026amp; Badai Sumber Daya (Reboot Loop \u0026amp; Flapping) # Ketika akar masalah bersifat persisten—misalnya direktori log penuh (No space left on device), connection pool database jenuh, atau kegagalan permission file—proses Tomcat akan langsung exit seketika setelah inisialisasi.\nJika sistem pengawas (watchdog) terus memaksa restart:\nHost OS terbebani oleh siklus process spawning, inisialisasi JVM, dan pembacaan disk yang tiada henti. Setiap inisialisasi aplikasi mencoba membuka kembali pool koneksi TCP/JDBC ke basis data secara serentak, yang berpotensi melumpuhkan cluster database (cascading failure). 2. Penghapusan Bukti Forensik \u0026amp; Status Memori (Artifact Destruction) # Investigasi akar masalah (Root Cause Analysis / RCA) pada JVM membutuhkan artefak diagnostik yang sangat rapuh (volatile). Ketika proses dimatikan atau di-restart secara otomatis:\nStatus memori JVM (Heap \u0026amp; Metaspace) langsung hilang. Berkas crash dump runtime JVM (hs_err_pid.log) atau core dump berisiko tertimpa oleh process ID baru. Berkas log aplikasi aktif (catalina.out) dapat ter-rotate atau terpotong sebelum tim SRE sempat menangkap baris stack trace awal terjadinya anomali. 3. Celah Keamanan Akibat Eskalasi Hak Akses (Privilege Escalation Risk) # Agar sebuah container pemantau atau layanan diagnostik dapat mengeksekusi systemctl restart, podman restart, atau kill -9 pada proses aplikasi target di host, layanan tersebut harus diberikan hak istimewa yang sangat tinggi:\nMenjalankan container pemantau sebagai root dengan kapabilitas kernel tambahan (CAP_SYS_ADMIN). Memasang (mounting) socket kontrol runtime container host (/run/podman/podman.sock atau /var/run/docker.sock) ke dalam container pemantau. Langkah ini secara langsung merusak prinsip keamanan Hak Akses Minimal (Least Privilege). Jika container pemantau memiliki celah kerentanan (misalnya pada dependensi webhook-nya), penyerang dapat langsung mengambil alih kontrol penuh atas seluruh sistem operasi host melalui socket runtime tersebut.\n4. Pemulihan Semu yang Menutupi Masalah Kronis (Masking Chronic Failures) # Auto-restart sering kali menyembunyikan masalah degradasi bertahap, seperti slow memory leak atau unclosed JDBC connection. Service yang di-restart setiap beberapa jam mungkin tampak \u0026ldquo;sehat\u0026rdquo; di dashboard metrik rata-rata, tetapi tidak menyelesaikan kebocoran kode yang mendasarinya. Masalah ini pasti akan meledak menjadi insiden besar saat trafik bisnis sedang berada pada puncaknya (peak load).\n🏛️ Solusi \u0026amp; Desain Arsitektur: Kebijakan Zero Destructive Auto-Remediation # Untuk mengatasi dilema di atas, pada proyek Tomcat Monitoring Platform kami merumuskan dan menerapkan kebijakan Zero Automatic Remediation (TM-ADR-0014) yang didukung oleh pemisahan peran secara tegas (Separation of Concerns).\n1. Prinsip Batasan Hanya-Baca (Read-Only Boundary \u0026amp; Least-Privilege Isolation) # Layanan diagnostik kami (Tomcat Diagnostic Service) dirancang murni sebagai sistem penasihat independen (read-only advisory engine), bukan eksekutor tindakan.\nflowchart TD subgraph OBSERVABILITY[\u0026#34;Lapisan Observabilitas \u0026amp; Alerting\u0026#34;] PROM[\u0026#34;Prometheus\u0026#34;] --\u0026gt;|Scrape Telemetry| TGT[\u0026#34;Target Tomcat\u0026#34;] PROM --\u0026gt;|Alert Trigger| AM[\u0026#34;Alertmanager\u0026#34;] AM --\u0026gt;|HTTPS Webhook POST| DS[\u0026#34;Diagnostic Service\u0026lt;br/\u0026gt;(Read-Only Boundary)\u0026#34;] end subgraph EVIDENCE_COLLECTION[\u0026#34;Pengumpulan Bukti Terisolasi\u0026#34;] DS --\u0026gt;|HTTP Pull :ro| PROM_TEL[\u0026#34;Metrik Prometheus\u0026#34;] DS --\u0026gt;|Volume Mount :ro,z| LOGS[\u0026#34;catalina.out\u0026lt;br/\u0026gt;(Max 500 lines / 512 KiB)\u0026#34;] DS --\u0026gt;|Spool Read :ro| SPOOL[\u0026#34;Event Spool Host\u0026lt;br/\u0026gt;(Normalized JSON 0700)\u0026#34;] end subgraph EVALUATION[\u0026#34;Mesin Keputusan Deterministik\u0026#34;] DS --\u0026gt; DISPATCHER[\u0026#34;Multi-Domain Dispatcher\u0026#34;] DISPATCHER --\u0026gt; RULEPACK[\u0026#34;Declarative Rulepack Engine\u0026lt;br/\u0026gt;(SQLite State \u0026amp; Memory Cache)\u0026#34;] end subgraph DELIVERY[\u0026#34;Otoritas Notifikasi \u0026amp; Human-in-the-Loop\u0026#34;] RULEPACK --\u0026gt; REPORT[\u0026#34;Canonical 7-Section SRE Incident Report\u0026#34;] REPORT --\u0026gt;|SMTP Delivery| MAIL[\u0026#34;Mailpit / On-Call Inbox\u0026#34;] DS -.-\u0026gt;|BLOCKED / DILARANG| MUTATE[\u0026#34;Mutasi Container / Host Restart\u0026#34;] MAIL --\u0026gt; OPERATOR[\u0026#34;👨‍💻 SRE On-Call Operator\u0026lt;br/\u0026gt;(Triage Terarah \u0026amp; Eksekusi SOP Manual)\u0026#34;] end style MUTATE fill:#ffdddd,stroke:#ff0000,stroke-width:2px,stroke-dasharray: 5 5; Dalam arsitektur ini:\nRootless \u0026amp; Non-Root Execution: Container Diagnostic Service berjalan sepenuhnya tanpa hak root (USER 10001:10001), tanpa privilege khusus, dan tanpa mounting socket container runtime host. Strict Read-Only Volumes: Akses ke direktori log aplikasi di-mount menggunakan opsi :ro,z (/run/tomcat-diagnostic/logs:ro,z), menjamin container tidak memiliki kemampuan menghapus atau mengubah berkas log. Normalized Host Event Spool: Pengumpulan event level container/host (seperti exit code 137 OOMKilled atau lifecycle event) didelegasikan ke daemon terisolasi (Restricted Event Collector / tm-agent, TM-ADR-0008) yang menulis berkas JSON berukuran terbatas dengan izin ketat 0700/0600. 2. Otoritas Notifikasi Tunggal (Canonical Incident Notification Authority) # Sering kali tim operasional mengalami alert fatigue akibat menerima email teks mentah dari Alertmanager yang hanya berisi formula PromQL tanpa konteks. Melalui TM-ADR-0016, kami menetapkan Diagnostic Service sebagai satu-satunya pengirim notifikasi resmi (Single Source of Truth) untuk seluruh insiden monitoring.\nAlertmanager dikonfigurasi murni sebagai router webhook HTTPS menuju Diagnostic Service. Diagnostic Service kemudian mengumpulkan bukti dari multi-sumber (Prometheus telemetry, log snippets, crash dumps, lifecycle spool), mengevaluasi aturan deterministik, dan menerbitkan Canonical 7-Section SRE Incident Report.\n+-------------------------------------------------------------------------+ | CANONICAL 7-SECTION SRE INCIDENT REPORT | +-------------------------------------------------------------------------+ | 1. Incident Header \u0026amp; Target Context (ID, Alert, Severity, Host, Time) | | 2. Primary Root Cause \u0026amp; Decision Branch (TD-xx, GC-xx, AH-xx, etc.) | | 3. Failure Domain Classification (jvm_memory, database_persistence, ..) | | 4. Diagnostic Confidence Score (HIGH / MEDIUM / LOW Matrix) | | 5. Correlated Evidence Summary (Sanitized Logs, Spool, Metrics, Probes) | | 6. Actionable Operator SOP Steps (Explicit Manual Remediation Runbook) | | 7. System Metadata \u0026amp; Verification Audit Trail (SQLite ID, Checksum) | +-------------------------------------------------------------------------+ Note Zero Silent Failure Safeguard (Emergency Bypass): Untuk mencegah kegagalan tanpa notifikasi jika Diagnostic Service itu sendiri mengalami downtime, Alertmanager memiliki rute darurat (Direct SMTP Bypass) khusus untuk alert DiagnosticServiceDown (up{job=\u0026quot;tomcat-diagnostic-service\u0026quot;} == 0). Rute darurat ini langsung mengirimkan email peringatan ke operator tanpa melalui webhook.\n3. Taksonomi 8 Domain Kegagalan (Failure Domain Taxonomy) # Setiap insiden secara otomatis diklasifikasikan ke dalam salah satu dari 8 Standard Failure Domains untuk mempermudah perutean eskalasi:\nFailure Domain (category) Cakupan Kegagalan Contoh Tanda Bukti (Error Signature) Tim Eskalasi Target jvm_memory Alokasi memori heap, metaspace, GC thrashing. OutOfMemoryError: Java heap space, GC overhead limit. Backend / Java Engineers concurrency_threading Kejenuhan worker thread pool, deadlock thread JVM. RejectedExecutionException: Thread pool is exhausted. Platform Engineers / SRE database_persistence HikariCP pool jenuh, DB lock, timeout SQL. CannotGetJdbcConnectionException, HikariPool timeout. Database Administrator (DBA) network_integration Handshake TLS gagal, timeout upstream microservice. SSLHandshakeException, SocketTimeoutException. Network \u0026amp; Cloud Infra application_lifecycle Gagal deploy WAR, inisialisasi context servlet gagal. LifecycleException: Failed to start component. Application Developers storage_os_limits Batas OS (ulimit file descriptor), disk penuh. Too many open files, No space left on device. Systems / SysAdmin security_session Token auth kedaluwarsa, kegagalan replikasi session. SessionReplicationException, InvalidTokenException. Security / IAM \u0026amp; Middleware general Anomali lintas domain atau bukti belum konklusif. Contradicting state, Undetermined fallback. Incident Commander / SRE Lead 4. Contoh Deklarasi Rulepack Deterministik # Berikut adalah contoh bagaimana tim SRE mengodifikasikan pengetahuan mitigasi menjadi aturan deklaratif JSON yang dapat di-hot-reload ke mesin SQLite tanpa me-restart container (POST /api/v1/rules):\n{ \u0026#34;branch\u0026#34;: \u0026#34;TD-19\u0026#34;, \u0026#34;ruleName\u0026#34;: \u0026#34;HikariCPConnectionPoolExhaustion\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;database_persistence\u0026#34;, \u0026#34;targetSource\u0026#34;: \u0026#34;local_file\u0026#34;, \u0026#34;pattern\u0026#34;: \u0026#34;Connection is not available, request timed out after [0-9]+ms\u0026#34;, \u0026#34;assessment\u0026#34;: \u0026#34;Database connection pool exhausted: HikariCP pool saturated or unclosed connection leak detected\u0026#34;, \u0026#34;classification\u0026#34;: \u0026#34;confirmed_cause\u0026#34;, \u0026#34;confidence\u0026#34;: \u0026#34;high\u0026#34;, \u0026#34;recommendedActions\u0026#34;: [ \u0026#34;1. Periksa unclosed java.sql.Connection / Statement blocks pada rilis aplikasi terbaru.\u0026#34;, \u0026#34;2. Verifikasi threshold max_connections dan query lock aktif pada database PostgreSQL/Oracle backend.\u0026#34;, \u0026#34;3. Naikkan parameter maximumPoolSize pada konfigurasi datasource Tomcat jika beban trafik sah meningkat.\u0026#34;, \u0026#34;4. Pantau metrik latensi jaringan antara Tomcat instance dan database cluster.\u0026#34; ], \u0026#34;createdBy\u0026#34;: \u0026#34;sre-incident-response\u0026#34; } 💡 Pelajaran Praktis: SRE \u0026amp; DevOps Best Practices # Dari implementasi arsitektur di atas, terdapat sejumlah prinsip fundamental yang dapat diadaptasi untuk sistem produksi apa pun:\n1. Kejujuran Deterministik (Deterministic Honesty) # Sistem observabilitas tidak boleh \u0026ldquo;mengarang\u0026rdquo; penyebab jika bukti pendukung tidak lengkap. Jika metrik menunjukkan Tomcat tidak merespons tetapi tidak ditemukan jejak OOM atau error log, sistem harus secara transparan menyatakan status UNDETERMINED atau PARTIAL dengan tingkat keyakinan LOW, alih-alih memaksakan kesimpulan palsu.\nImportant Memberitahukan operator bahwa \u0026ldquo;Sistem belum dapat memastikan penyebab pasti, periksa daftar bukti berikut\u0026rdquo; jauh lebih bernilai daripada memberikan diagnosis keliru yang mengarahkan operator ke langkah mitigasi yang salah.\n2. Pertahankan Lingkaran Pembelajaran Berkelanjutan (Continuous Learning Loop) # Jangan biarkan pengetahuan pasca-insiden (post-mortem) hanya berhenti sebagai dokumen PDF yang terlupakan. Dalam platform kami:\nInsiden Terjadi: Kasus kegagalan baru diinvestigasi oleh tim SRE. Kodifikasi Aturan: SRE menulis satu berkas JSON rulepack yang memuat regex pattern dan SOP perbaikan. Hot-Ingest: Rule diunggah via CLI tmctl atau REST API berotentikasi Bearer Token. Otomatisasi Triage: Ketika insiden serupa terulang di masa depan, sistem langsung mengenali polanya dalam hitungan detik dan menyajikan SOP yang tepat. Insiden Baru Terjadi ──\u0026gt; Investigasi SRE ──\u0026gt; Kodifikasi Rule JSON ──\u0026gt; Hot-Ingest ke SQLite ──\u0026gt; Triage Otomatis Masa Depan 3. Batasi Konsumsi Sumber Daya (Bounded Resource Constraints) # Mesin diagnostik tidak boleh membebani dirinya sendiri atau host saat terjadi insiden besar:\nPembacaan log catalina.out dibatasi maksimal 500 baris / 512 KiB dengan penyensoran kredensial otomatis (credential redaction). Kueri Prometheus dibatasi dengan timeout ketat 5 detik. Evaluasi insiden memiliki hard deadline maksimal 60 detik sebelum menghasilkan timeout fallback report. 📋 Kesimpulan \u0026amp; Checklist Triage Operator On-Call # Menolak destructive auto-remediation bukanlah bentuk kemunduran otomatisasi, melainkan langkah pendewasaan arsitektur. Otomatisasi terbaik bukanlah sistem yang mengambil tindakan destruktif tanpa konfirmasi, melainkan sistem yang mampu mengumpulkan bukti multi-dimensi secara instan, menyaring kebisingan data, dan menyajikan rekomendasi mitigasi yang jelas kepada pengambil keputusan manusia.\n🛠️ Checklist Triage Cepat Saat Menerima Laporan Insiden 7-Seksi # Ketika Anda menerima email laporan insiden 7-seksi dari Diagnostic Service di inbox atau Mailpit, ikuti alur verifikasi berikut:\n1. Periksa Section 1 (Header Context): Pastikan target instance, hostname, dan environment (production vs staging) yang terdampak. 2. Evaluasi Section 2 \u0026amp; 4 (Root Cause \u0026amp; Confidence Score): Jika Confidence: HIGH (misal: ExitCode: 137 OOMKilled atau PortConflict terverifikasi): Lanjutkan langsung ke langkah mitigasi Section 6. Jika Confidence: LOW / UNDETERMINED: Buka sesi investigasi manual menggunakan panduan log di Section 5. 3. Identifikasi Section 3 (Failure Domain): Rujuk tiket eskalasi ke tim spesialis terkait (DBA untuk database_persistence, Dev untuk application_lifecycle, Jaringan untuk network_integration). 4. Eksekusi SOP Manual di Section 6: Jalankan perintah mitigasi yang direkomendasikan secara terkontrol melalui SSH / tmctl. 5. Verifikasi Status Pemulihan (Resolved Notification): Pastikan email penutupan insiden (Resolved Notification) diterima setelah metrik health probe kembali stabil. 📚 Referensi Terkait # TM-ADR-0014: Enforce Zero Automatic Remediation for Diagnostic Service TM-ADR-0016: Designate Diagnostic Service as the Canonical Incident Notification Authority TM-ADR-0006: Use Deterministic Multi-Source Evidence for Diagnostic Assessment TM-ADR-0008: Use a Restricted Host Event Collector with a Normalized Evidence Spool RUNBOOK.md: Tomcat Monitoring Platform SRE Operational Runbook ","date":"19 September 2026","externalUrl":null,"permalink":"/articles/mengapa-auto-restart-di-production-berbahaya/","section":"Articles","summary":"Membongkar ilusi ‘self-healing’ otomatis di lingkungan produksi dan bagaimana kebijakan Zero Destructive Auto-Remediation serta arsitektur Canonical Diagnostic Authority menjaga integritas sistem dan forensik insiden.","title":"Mengapa Auto-Restart di Production Berbahaya: Menerapkan Kebijakan Zero Destructive Auto-Remediation","type":"articles"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/series/sre--incident-diagnostics-architecture/","section":"Series","summary":"","title":"SRE \u0026 Incident Diagnostics Architecture","type":"series"},{"content":"","date":"19 September 2026","externalUrl":null,"permalink":"/tags/zero-remediation/","section":"Tags","summary":"","title":"Zero-Remediation","type":"tags"},{"content":" Introduction # Ini adalah artikel pertama pada Personal Site.\n","date":"17 July 2026","externalUrl":null,"permalink":"/articles/my-first-post/","section":"Articles","summary":"Introduction # Ini adalah artikel pertama pada Personal Site.\n","title":"My First Post","type":"articles"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"}]