[{"data":1,"prerenderedAt":135},["ShallowReactive",2],{"site-header":3,"site-footer-license":37,"article-health-check-readiness-liveness-probe-kubernetes-with-latest":41},{"navigations":4},[5,20],{"collection":6,"item":7},"series",{"__typename":6,"title":8,"slug":9,"children_series":10},"Artikel","all",[11,14,17],{"title":12,"slug":13},"Algoritma dan Struktur Data","algoritma-struktur-data",{"title":15,"slug":16},"Konsep Dasar Pemrograman","konsep-dasar-pemrograman",{"title":18,"slug":19},"Kecerdasan Artifisial","kecerdasan-artifisial",{"collection":6,"item":21},{"__typename":6,"title":22,"slug":23,"children_series":24},"Tutorial","tutorial",[25,28,31,34],{"title":26,"slug":27},"Belajar Java","belajar-java",{"title":29,"slug":30},"Belajar Pascal","belajar-pascal",{"title":32,"slug":33},"Belajar Python","belajar-python",{"title":35,"slug":36},"Belajar Golang","belajar-golang",{"name":38,"url":39,"show":40},"CC BY-SA","https://creativecommons.org/licenses/by-sa/4.0/",false,{"article":42,"renderedBody":67,"renderedTakeaway":68,"latestArticles":69,"toc":118},{"id":43,"title":44,"slug":45,"excerpt":46,"published_at":47,"thumbnail_image":48,"tags":50,"reading_time":58,"takeway":59,"body":60,"authors":61,"series":58},"42","Health Check vs Readiness vs Liveness Probe di Kubernetes: Jangan Sampai Traffic Masuk ke Pod Mati!","health-check-readiness-liveness-probe-kubernetes","Semua pod kalian hijau Running, tapi pengguna malah disambut 502 Bad Gateway? Atau seluruh pod restart barengan gara-gara database lagi lambat? Salah kaprah soal probe bisa jadi biangnya. Yuk, kita bongkar bareng!","2026-09-02T03:15:08.836Z",{"id":49},"922ad82d-599d-4285-9540-8d1586cda4ed",[51,52,53,54,55,56,57],"kubernetes","devops","backend","docker","microservices","reliability","system-design",null,"- Tiga tipe probe di Kubernetes punya peran spesifik: startup probe buat inisialisasi awal, liveness probe buat deteksi deadlock atau crash, dan readiness probe buat nentuin kesiapan nerima traffic.\n- Liveness probe yang meriksa dependensi eksternal (database/Redis) itu jebakan maut, soalnya bisa memicu restart massal alias cascading failure.\n- Endpoint `/healthz` buat liveness dan `/ready` buat readiness sebaiknya dipisah di aplikasi backend, entah itu FastAPI, Go, atau Node.js.\n- Parameter `initialDelaySeconds`, `periodSeconds`, `timeoutSeconds`, dan `failureThreshold` perlu disetel biar lonjakan CPU sesaat nggak memicu false-positive restart.","Pernah nggak kalian ngalamin *deployment* aplikasi di Kubernetes yang kelihatannya sukses? Semua *pod* berstatus `Running` dengan warna hijau cantik. Tapi pengguna langsung disambut *error* `502 Bad Gateway` pas buka aplikasi.\n\nAtau skenario yang lebih horor. *Server database* lagi kelambatan sementara. Eh, tiba-tiba seluruh *pod backend* di-*restart* serentak oleh Kubernetes. Jadilah *cascading failure*. 😅\n\nMasalah klasik ini hampir selalu berakar pada satu hal. Salah kaprah soal *health check* di Kubernetes.\n\nBanyak *developer* pemula nganggep health check cukup satu *endpoint* `/health` sederhana. Padahal [Kubernetes](https://kubernetes.io/) nyediain tiga mekanisme *probe* yang beda. Tugas dan konsekuensinya sangat berlainan. Ada *startup probe*, *liveness probe*, dan *readiness probe*.\n\nMari kita bedah cara kerja masing-masing probe. Sekalian gimana masangnya dengan benar biar aplikasi kita tangguh di *production*.\n\n## Tiga Serangkai Probe di Kubernetes\n\nBiar gampang kebayang, bayangin aja restoran cepat saji. Ada koki, ada dapur, ada manajer. Tiap probe punya peran kayak salah satu dari mereka.\n\nStartup probe bertugas meriksa apakah proses inisialisasi aplikasi udah selesai. Beberapa aplikasi butuh waktu lama buat beneran *booting*. Misalnya yang pakai *framework* berat kayak Java Spring Boot. Atau *backend* yang memuat model *machine learning* dan ngejalanin migrasi *database*. Bisa puluhan detik sampai menit, lho.\n\nSelama startup probe belum berhasil (`Success`), Kubernetes menonaktifkan pemeriksaan *liveness* dan *readiness*. Tujuannya jelas. Biar aplikasi nggak keburu dibunuh liveness probe sebelum sempat selesai menyala.\n\nLiveness probe jawab satu pertanyaan. Apakah proses aplikasi masih hidup dan sehat? Atau udah ngalami *deadlock*, alias *hang* total? Kalau liveness probe gagal (`Failed`) melebihi batas toleransi (`failureThreshold`), *kubelet* langsung membunuh *container* dan me-restart-nya. Ibaratnya gini. Kalau koki pingsan di dapur, manajer restoran bakal ganti dia dengan koki baru.\n\nReadiness probe jawab pertanyaan yang beda lagi. Apakah aplikasi siap nerima *traffic* dari pengguna sekarang? Sebuah pod bisa aja masih hidup normal. Tapi sedang nggak mampu memproses *request*. Contohnya, *cache in-memory* lokal sedang di-*refresh*. Atau koneksi *pool* ke database sedang penuh. Bisa juga aplikasi sedang memproses antrean *batch* yang berat.\n\nKalau readiness probe gagal, Kubernetes **nggak** bakal membunuh pod itu. Kubernetes cuma mencabut pod itu dari daftar *endpoint Service* alias *Load Balancer*. Traffic pengguna nggak bakal dialirin ke pod itu sampai probe-nya kembali sukses.\n\n## Jebakan Terbesar: Meriksa Database di Liveness Probe\n\nIni *anti-pattern* **paling berbahaya** yang sering ketemu di lapangan:\n\n```python\n# CONTOH SALAH BESAR UNTUK LIVENESS PROBE!\n@app.get(\"/healthz\")\nasync def health_check(db: Session = Depends(get_db)):\n    # JANGAN PERNAH LAKUKAN INI DI LIVENESS PROBE!\n    await db.execute(text(\"SELECT 1\"))\n    return {\"status\": \"ok\"}\n```\n\nBayangin kalau database PostgreSQL kalian mendadak kelebihan beban. CPU-nya 100%. Query `SELECT 1` ngalami *timeout* lebih dari 2 detik. Apa yang terjadi kalau endpoint di atas dipasang sebagai liveness probe?\n\n1. Liveness probe di Pod 1 timeout. Kubernetes membunuh Pod 1 dan bikin ulang pod baru.\n2. Liveness probe di Pod 2 timeout. Kubernetes membunuh Pod 2.\n3. Begitu seterusnya sampai seluruh pod di-restart bersamaan!\n4. *Pod-pod* baru langsung membanjiri database dengan *connection pool* baru. Namanya *connection spike*. Database pun makin sekarat. 😅\n\nJadi aturan emasnya gini, nih. Liveness probe cuma periksa status internal aplikasi sendiri. Misal *event loop* nggak *blocking*, atau *web server* masih merespons. **Jangan pernah** meriksa dependensi eksternal kayak database, Redis, atau *service* pihak ketiga. Sementara readiness probe justru tempat yang tepat. Di situ kalian bisa memverifikasi kesiapan koneksi database sebelum nerima request bisnis pengguna.\n\n## Sebaiknya Pisahkan Endpoint Health Check\n\nCara paling bersih adalah memisahkan endpoint di aplikasi backend kalian:\n\n```python\nfrom fastapi import FastAPI, status, Response\n\napp = FastAPI()\n\nis_app_ready = False\n\n@app.on_event(\"startup\")\nasync def startup_event():\n    # Inisialisasi koneksi, load model, warming cache...\n    global is_app_ready\n    await init_database_connection()\n    is_app_ready = True\n\n# 1. Liveness: Cuma cek apakah FastAPI masih bernapas\n@app.get(\"/healthz\", status_code=status.HTTP_200_OK)\nasync def liveness():\n    return {\"status\": \"alive\"}\n\n# 2. Readiness: Cek apakah dependensi siap menerima traffic\n@app.get(\"/ready\")\nasync def readiness(response: Response):\n    global is_app_ready\n    if not is_app_ready or not await check_db_health():\n        response.status_code = status.HTTP_503_SERVICE_UNAVAILABLE\n        return {\"status\": \"unavailable\"}\n    return {\"status\": \"ready\"}\n```\n\n## Konfigurasi Manifest Kubernetes yang Ideal\n\nBerikut contoh konfigurasi Deployment Kubernetes. Isinya ngegabungin ketiga probe secara harmonis. Saya tambahin `selector` dan *label* sekalian, biar manifest-nya beneran valid, ya.\n\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: payment-service\nspec:\n  replicas: 3\n  selector:\n    matchLabels:\n      app: payment-service\n  template:\n    metadata:\n      labels:\n        app: payment-service\n    spec:\n      containers:\n      - name: payment-api\n        image: payment-service:v1.2.0\n        ports:\n        - containerPort: 8000\n\n        # 1. Startup Probe: Berikan napas lega saat cold start\n        startupProbe:\n          httpGet:\n            path: /healthz\n            port: 8000\n          failureThreshold: 30\n          periodSeconds: 2 # Total waktu tunggu booting: hingga 60 detik\n\n        # 2. Liveness Probe: Bunuh container hanya jika hang total\n        livenessProbe:\n          httpGet:\n            path: /healthz\n            port: 8000\n          periodSeconds: 10\n          timeoutSeconds: 2\n          failureThreshold: 3 # Toleransi 3x gagal berturut-turut\n\n        # 3. Readiness Probe: Cabut traffic jika aplikasi overload / DB putus\n        readinessProbe:\n          httpGet:\n            path: /ready\n            port: 8000\n          periodSeconds: 5\n          timeoutSeconds: 2\n          failureThreshold: 2\n          successThreshold: 1 # Langsung alirkan traffic begitu kembali sehat\n```\n\nPerhatiin parameter `periodSeconds` dan `failureThreshold`. Jangan pasang `timeoutSeconds` terlalu agresif, misal 100 ms. Soalnya saat CPU lagi *spike* sesaat, *request probe* bisa tertunda. Akhirnya memicu restart yang nggak perlu, alias *false-positive restart*.\n\n## Jadi, Gimana Biar Pod Nggak Mati Nerima Tamu?\n\nDengan memisahkan peran liveness dan readiness probe secara disiplin, tiga hal ini bakal kalian dapat. Pertama, kita terhindar dari mimpi buruk *cascading restart* saat infrastruktur database bermasalah. Kedua, pengguna nggak bakal dapat error 502/504. Traffic cuma dikirim ke pod yang beneran siap melayani. Ketiga, proses *rolling deployment* dan *auto-scaling* HPA (Horizontal Pod Autoscaler) jalan jauh lebih mulus tanpa *downtime*.\n\nSudahkah probe di klaster Kubernetes kalian dikonfigurasi dengan benar hari ini? Yuk, audit manifest kalian sekarang.\n\nSelamat ber-Kubernetes ria, dan semoga pod kalian nggak pernah restart tanpa alasan! 👋",[62],{"authors_id":63},{"name":64,"slug":65,"role":66,"profile_picture":58},"Inva","inva","Writer","\u003Cp>Pernah nggak kalian ngalamin \u003Cem>deployment\u003C/em> aplikasi di Kubernetes yang kelihatannya sukses? Semua \u003Cem>pod\u003C/em> berstatus \u003Ccode>Running\u003C/code> dengan warna hijau cantik. Tapi pengguna langsung disambut \u003Cem>error\u003C/em> \u003Ccode>502 Bad Gateway\u003C/code> pas buka aplikasi.\u003C/p>\n\u003Cp>Atau skenario yang lebih horor. \u003Cem>Server database\u003C/em> lagi kelambatan sementara. Eh, tiba-tiba seluruh \u003Cem>pod backend\u003C/em> di-\u003Cem>restart\u003C/em> serentak oleh Kubernetes. Jadilah \u003Cem>cascading failure\u003C/em>. 😅\u003C/p>\n\u003Cp>Masalah klasik ini hampir selalu berakar pada satu hal. Salah kaprah soal \u003Cem>health check\u003C/em> di Kubernetes.\u003C/p>\n\u003Cp>Banyak \u003Cem>developer\u003C/em> pemula nganggep health check cukup satu \u003Cem>endpoint\u003C/em> \u003Ccode>/health\u003C/code> sederhana. Padahal \u003Ca href=\"https://kubernetes.io/\">Kubernetes\u003C/a> nyediain tiga mekanisme \u003Cem>probe\u003C/em> yang beda. Tugas dan konsekuensinya sangat berlainan. Ada \u003Cem>startup probe\u003C/em>, \u003Cem>liveness probe\u003C/em>, dan \u003Cem>readiness probe\u003C/em>.\u003C/p>\n\u003Cp>Mari kita bedah cara kerja masing-masing probe. Sekalian gimana masangnya dengan benar biar aplikasi kita tangguh di \u003Cem>production\u003C/em>.\u003C/p>\n\u003Ch2 id=\"tiga-serangkai-probe-di-kubernetes\">Tiga Serangkai Probe di Kubernetes\u003C/h2>\n\u003Cp>Biar gampang kebayang, bayangin aja restoran cepat saji. Ada koki, ada dapur, ada manajer. Tiap probe punya peran kayak salah satu dari mereka.\u003C/p>\n\u003Cp>Startup probe bertugas meriksa apakah proses inisialisasi aplikasi udah selesai. Beberapa aplikasi butuh waktu lama buat beneran \u003Cem>booting\u003C/em>. Misalnya yang pakai \u003Cem>framework\u003C/em> berat kayak Java Spring Boot. Atau \u003Cem>backend\u003C/em> yang memuat model \u003Cem>machine learning\u003C/em> dan ngejalanin migrasi \u003Cem>database\u003C/em>. Bisa puluhan detik sampai menit, lho.\u003C/p>\n\u003Cp>Selama startup probe belum berhasil (\u003Ccode>Success\u003C/code>), Kubernetes menonaktifkan pemeriksaan \u003Cem>liveness\u003C/em> dan \u003Cem>readiness\u003C/em>. Tujuannya jelas. Biar aplikasi nggak keburu dibunuh liveness probe sebelum sempat selesai menyala.\u003C/p>\n\u003Cp>Liveness probe jawab satu pertanyaan. Apakah proses aplikasi masih hidup dan sehat? Atau udah ngalami \u003Cem>deadlock\u003C/em>, alias \u003Cem>hang\u003C/em> total? Kalau liveness probe gagal (\u003Ccode>Failed\u003C/code>) melebihi batas toleransi (\u003Ccode>failureThreshold\u003C/code>), \u003Cem>kubelet\u003C/em> langsung membunuh \u003Cem>container\u003C/em> dan me-restart-nya. Ibaratnya gini. Kalau koki pingsan di dapur, manajer restoran bakal ganti dia dengan koki baru.\u003C/p>\n\u003Cp>Readiness probe jawab pertanyaan yang beda lagi. Apakah aplikasi siap nerima \u003Cem>traffic\u003C/em> dari pengguna sekarang? Sebuah pod bisa aja masih hidup normal. Tapi sedang nggak mampu memproses \u003Cem>request\u003C/em>. Contohnya, \u003Cem>cache in-memory\u003C/em> lokal sedang di-\u003Cem>refresh\u003C/em>. Atau koneksi \u003Cem>pool\u003C/em> ke database sedang penuh. Bisa juga aplikasi sedang memproses antrean \u003Cem>batch\u003C/em> yang berat.\u003C/p>\n\u003Cp>Kalau readiness probe gagal, Kubernetes \u003Cstrong>nggak\u003C/strong> bakal membunuh pod itu. Kubernetes cuma mencabut pod itu dari daftar \u003Cem>endpoint Service\u003C/em> alias \u003Cem>Load Balancer\u003C/em>. Traffic pengguna nggak bakal dialirin ke pod itu sampai probe-nya kembali sukses.\u003C/p>\n\u003Ch2 id=\"jebakan-terbesar-meriksa-database-di-liveness-probe\">Jebakan Terbesar: Meriksa Database di Liveness Probe\u003C/h2>\n\u003Cp>Ini \u003Cem>anti-pattern\u003C/em> \u003Cstrong>paling berbahaya\u003C/strong> yang sering ketemu di lapangan:\u003C/p>\n\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">PYTHON\u003C/span>\n    \u003C/div>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"%23%20CONTOH%20SALAH%20BESAR%20UNTUK%20LIVENESS%20PROBE!%0A%40app.get(%22%2Fhealthz%22)%0Aasync%20def%20health_check(db%3A%20Session%20%3D%20Depends(get_db))%3A%0A%20%20%20%20%23%20JANGAN%20PERNAH%20LAKUKAN%20INI%20DI%20LIVENESS%20PROBE!%0A%20%20%20%20await%20db.execute(text(%22SELECT%201%22))%0A%20%20%20%20return%20%7B%22status%22%3A%20%22ok%22%7D\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C/path>\n      \u003C/svg>\n      \u003Cspan class=\"copy-text\">Copy\u003C/span>\n    \u003C/button>\n  \u003C/div>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># CONTOH SALAH BESAR UNTUK LIVENESS PROBE!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">@app.get\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"/healthz\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">async\u003C/span>\u003Cspan style=\"color:#F97583\"> def\u003C/span>\u003Cspan style=\"color:#B392F0\"> health_check\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(db: Session \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> Depends(get_db)):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # JANGAN PERNAH LAKUKAN INI DI LIVENESS PROBE!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> db.execute(text(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"SELECT 1\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"status\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"ok\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n  \u003C/div>\n\u003C/div>\u003Cp>Bayangin kalau database PostgreSQL kalian mendadak kelebihan beban. CPU-nya 100%. Query \u003Ccode>SELECT 1\u003C/code> ngalami \u003Cem>timeout\u003C/em> lebih dari 2 detik. Apa yang terjadi kalau endpoint di atas dipasang sebagai liveness probe?\u003C/p>\n\u003Col>\n\u003Cli>Liveness probe di Pod 1 timeout. Kubernetes membunuh Pod 1 dan bikin ulang pod baru.\u003C/li>\n\u003Cli>Liveness probe di Pod 2 timeout. Kubernetes membunuh Pod 2.\u003C/li>\n\u003Cli>Begitu seterusnya sampai seluruh pod di-restart bersamaan!\u003C/li>\n\u003Cli>\u003Cem>Pod-pod\u003C/em> baru langsung membanjiri database dengan \u003Cem>connection pool\u003C/em> baru. Namanya \u003Cem>connection spike\u003C/em>. Database pun makin sekarat. 😅\u003C/li>\n\u003C/ol>\n\u003Cp>Jadi aturan emasnya gini, nih. Liveness probe cuma periksa status internal aplikasi sendiri. Misal \u003Cem>event loop\u003C/em> nggak \u003Cem>blocking\u003C/em>, atau \u003Cem>web server\u003C/em> masih merespons. \u003Cstrong>Jangan pernah\u003C/strong> meriksa dependensi eksternal kayak database, Redis, atau \u003Cem>service\u003C/em> pihak ketiga. Sementara readiness probe justru tempat yang tepat. Di situ kalian bisa memverifikasi kesiapan koneksi database sebelum nerima request bisnis pengguna.\u003C/p>\n\u003Ch2 id=\"sebaiknya-pisahkan-endpoint-health-check\">Sebaiknya Pisahkan Endpoint Health Check\u003C/h2>\n\u003Cp>Cara paling bersih adalah memisahkan endpoint di aplikasi backend kalian:\u003C/p>\n\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">PYTHON\u003C/span>\n    \u003C/div>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"from%20fastapi%20import%20FastAPI%2C%20status%2C%20Response%0A%0Aapp%20%3D%20FastAPI()%0A%0Ais_app_ready%20%3D%20False%0A%0A%40app.on_event(%22startup%22)%0Aasync%20def%20startup_event()%3A%0A%20%20%20%20%23%20Inisialisasi%20koneksi%2C%20load%20model%2C%20warming%20cache...%0A%20%20%20%20global%20is_app_ready%0A%20%20%20%20await%20init_database_connection()%0A%20%20%20%20is_app_ready%20%3D%20True%0A%0A%23%201.%20Liveness%3A%20Cuma%20cek%20apakah%20FastAPI%20masih%20bernapas%0A%40app.get(%22%2Fhealthz%22%2C%20status_code%3Dstatus.HTTP_200_OK)%0Aasync%20def%20liveness()%3A%0A%20%20%20%20return%20%7B%22status%22%3A%20%22alive%22%7D%0A%0A%23%202.%20Readiness%3A%20Cek%20apakah%20dependensi%20siap%20menerima%20traffic%0A%40app.get(%22%2Fready%22)%0Aasync%20def%20readiness(response%3A%20Response)%3A%0A%20%20%20%20global%20is_app_ready%0A%20%20%20%20if%20not%20is_app_ready%20or%20not%20await%20check_db_health()%3A%0A%20%20%20%20%20%20%20%20response.status_code%20%3D%20status.HTTP_503_SERVICE_UNAVAILABLE%0A%20%20%20%20%20%20%20%20return%20%7B%22status%22%3A%20%22unavailable%22%7D%0A%20%20%20%20return%20%7B%22status%22%3A%20%22ready%22%7D\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C/path>\n      \u003C/svg>\n      \u003Cspan class=\"copy-text\">Copy\u003C/span>\n    \u003C/button>\n  \u003C/div>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">from\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> fastapi \u003C/span>\u003Cspan style=\"color:#F97583\">import\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> FastAPI, status, Response\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">app \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> FastAPI()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">is_app_ready \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> False\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">@app.on_event\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"startup\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">async\u003C/span>\u003Cspan style=\"color:#F97583\"> def\u003C/span>\u003Cspan style=\"color:#B392F0\"> startup_event\u003C/span>\u003Cspan style=\"color:#E1E4E8\">():\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">    # Inisialisasi koneksi, load model, warming cache...\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    global\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> is_app_ready\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> init_database_connection()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    is_app_ready \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#79B8FF\"> True\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># 1. Liveness: Cuma cek apakah FastAPI masih bernapas\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">@app.get\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"/healthz\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:#FFAB70\">status_code\u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\">status.\u003C/span>\u003Cspan style=\"color:#79B8FF\">HTTP_200_OK\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">async\u003C/span>\u003Cspan style=\"color:#F97583\"> def\u003C/span>\u003Cspan style=\"color:#B392F0\"> liveness\u003C/span>\u003Cspan style=\"color:#E1E4E8\">():\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"status\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"alive\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># 2. Readiness: Cek apakah dependensi siap menerima traffic\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">@app.get\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"/ready\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">async\u003C/span>\u003Cspan style=\"color:#F97583\"> def\u003C/span>\u003Cspan style=\"color:#B392F0\"> readiness\u003C/span>\u003Cspan style=\"color:#E1E4E8\">(response: Response):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    global\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> is_app_ready\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C/span>\u003Cspan style=\"color:#F97583\"> not\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> is_app_ready \u003C/span>\u003Cspan style=\"color:#F97583\">or\u003C/span>\u003Cspan style=\"color:#F97583\"> not\u003C/span>\u003Cspan style=\"color:#F97583\"> await\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> check_db_health():\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        response.status_code \u003C/span>\u003Cspan style=\"color:#F97583\">=\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> status.\u003C/span>\u003Cspan style=\"color:#79B8FF\">HTTP_503_SERVICE_UNAVAILABLE\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        return\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"status\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"unavailable\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C/span>\u003Cspan style=\"color:#E1E4E8\"> {\u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"status\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">\"ready\"\u003C/span>\u003Cspan style=\"color:#E1E4E8\">}\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n  \u003C/div>\n\u003C/div>\u003Ch2 id=\"konfigurasi-manifest-kubernetes-yang-ideal\">Konfigurasi Manifest Kubernetes yang Ideal\u003C/h2>\n\u003Cp>Berikut contoh konfigurasi Deployment Kubernetes. Isinya ngegabungin ketiga probe secara harmonis. Saya tambahin \u003Ccode>selector\u003C/code> dan \u003Cem>label\u003C/em> sekalian, biar manifest-nya beneran valid, ya.\u003C/p>\n\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">YAML\u003C/span>\n    \u003C/div>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"apiVersion%3A%20apps%2Fv1%0Akind%3A%20Deployment%0Ametadata%3A%0A%20%20name%3A%20payment-service%0Aspec%3A%0A%20%20replicas%3A%203%0A%20%20selector%3A%0A%20%20%20%20matchLabels%3A%0A%20%20%20%20%20%20app%3A%20payment-service%0A%20%20template%3A%0A%20%20%20%20metadata%3A%0A%20%20%20%20%20%20labels%3A%0A%20%20%20%20%20%20%20%20app%3A%20payment-service%0A%20%20%20%20spec%3A%0A%20%20%20%20%20%20containers%3A%0A%20%20%20%20%20%20-%20name%3A%20payment-api%0A%20%20%20%20%20%20%20%20image%3A%20payment-service%3Av1.2.0%0A%20%20%20%20%20%20%20%20ports%3A%0A%20%20%20%20%20%20%20%20-%20containerPort%3A%208000%0A%0A%20%20%20%20%20%20%20%20%23%201.%20Startup%20Probe%3A%20Berikan%20napas%20lega%20saat%20cold%20start%0A%20%20%20%20%20%20%20%20startupProbe%3A%0A%20%20%20%20%20%20%20%20%20%20httpGet%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20path%3A%20%2Fhealthz%0A%20%20%20%20%20%20%20%20%20%20%20%20port%3A%208000%0A%20%20%20%20%20%20%20%20%20%20failureThreshold%3A%2030%0A%20%20%20%20%20%20%20%20%20%20periodSeconds%3A%202%20%23%20Total%20waktu%20tunggu%20booting%3A%20hingga%2060%20detik%0A%0A%20%20%20%20%20%20%20%20%23%202.%20Liveness%20Probe%3A%20Bunuh%20container%20hanya%20jika%20hang%20total%0A%20%20%20%20%20%20%20%20livenessProbe%3A%0A%20%20%20%20%20%20%20%20%20%20httpGet%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20path%3A%20%2Fhealthz%0A%20%20%20%20%20%20%20%20%20%20%20%20port%3A%208000%0A%20%20%20%20%20%20%20%20%20%20periodSeconds%3A%2010%0A%20%20%20%20%20%20%20%20%20%20timeoutSeconds%3A%202%0A%20%20%20%20%20%20%20%20%20%20failureThreshold%3A%203%20%23%20Toleransi%203x%20gagal%20berturut-turut%0A%0A%20%20%20%20%20%20%20%20%23%203.%20Readiness%20Probe%3A%20Cabut%20traffic%20jika%20aplikasi%20overload%20%2F%20DB%20putus%0A%20%20%20%20%20%20%20%20readinessProbe%3A%0A%20%20%20%20%20%20%20%20%20%20httpGet%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20path%3A%20%2Fready%0A%20%20%20%20%20%20%20%20%20%20%20%20port%3A%208000%0A%20%20%20%20%20%20%20%20%20%20periodSeconds%3A%205%0A%20%20%20%20%20%20%20%20%20%20timeoutSeconds%3A%202%0A%20%20%20%20%20%20%20%20%20%20failureThreshold%3A%202%0A%20%20%20%20%20%20%20%20%20%20successThreshold%3A%201%20%23%20Langsung%20alirkan%20traffic%20begitu%20kembali%20sehat\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C/path>\n      \u003C/svg>\n      \u003Cspan class=\"copy-text\">Copy\u003C/span>\n    \u003C/button>\n  \u003C/div>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">apiVersion\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">apps/v1\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">kind\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">Deployment\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">metadata\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">  name\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">payment-service\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">spec\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">  replicas\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">3\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">  selector\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">    matchLabels\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">      app\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">payment-service\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">  template\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">    metadata\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">      labels\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">        app\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">payment-service\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">    spec\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">      containers\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">      - \u003C/span>\u003Cspan style=\"color:#85E89D\">name\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">payment-api\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">        image\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">payment-service:v1.2.0\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">        ports\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        - \u003C/span>\u003Cspan style=\"color:#85E89D\">containerPort\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">8000\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">        # 1. Startup Probe: Berikan napas lega saat cold start\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">        startupProbe\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          httpGet\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">            path\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">/healthz\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">            port\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">8000\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          failureThreshold\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">30\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          periodSeconds\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:#6A737D\"> # Total waktu tunggu booting: hingga 60 detik\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">        # 2. Liveness Probe: Bunuh container hanya jika hang total\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">        livenessProbe\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          httpGet\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">            path\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">/healthz\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">            port\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">8000\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          periodSeconds\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">10\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          timeoutSeconds\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          failureThreshold\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">3\u003C/span>\u003Cspan style=\"color:#6A737D\"> # Toleransi 3x gagal berturut-turut\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\">        # 3. Readiness Probe: Cabut traffic jika aplikasi overload / DB putus\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">        readinessProbe\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          httpGet\u003C/span>\u003Cspan style=\"color:#E1E4E8\">:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">            path\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#9ECBFF\">/ready\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">            port\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">8000\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          periodSeconds\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">5\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          timeoutSeconds\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          failureThreshold\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">2\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#85E89D\">          successThreshold\u003C/span>\u003Cspan style=\"color:#E1E4E8\">: \u003C/span>\u003Cspan style=\"color:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:#6A737D\"> # Langsung alirkan traffic begitu kembali sehat\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n  \u003C/div>\n\u003C/div>\u003Cp>Perhatiin parameter \u003Ccode>periodSeconds\u003C/code> dan \u003Ccode>failureThreshold\u003C/code>. Jangan pasang \u003Ccode>timeoutSeconds\u003C/code> terlalu agresif, misal 100 ms. Soalnya saat CPU lagi \u003Cem>spike\u003C/em> sesaat, \u003Cem>request probe\u003C/em> bisa tertunda. Akhirnya memicu restart yang nggak perlu, alias \u003Cem>false-positive restart\u003C/em>.\u003C/p>\n\u003Ch2 id=\"jadi-gimana-biar-pod-nggak-mati-nerima-tamu\">Jadi, Gimana Biar Pod Nggak Mati Nerima Tamu?\u003C/h2>\n\u003Cp>Dengan memisahkan peran liveness dan readiness probe secara disiplin, tiga hal ini bakal kalian dapat. Pertama, kita terhindar dari mimpi buruk \u003Cem>cascading restart\u003C/em> saat infrastruktur database bermasalah. Kedua, pengguna nggak bakal dapat error 502/504. Traffic cuma dikirim ke pod yang beneran siap melayani. Ketiga, proses \u003Cem>rolling deployment\u003C/em> dan \u003Cem>auto-scaling\u003C/em> HPA (Horizontal Pod Autoscaler) jalan jauh lebih mulus tanpa \u003Cem>downtime\u003C/em>.\u003C/p>\n\u003Cp>Sudahkah probe di klaster Kubernetes kalian dikonfigurasi dengan benar hari ini? Yuk, audit manifest kalian sekarang.\u003C/p>\n\u003Cp>Selamat ber-Kubernetes ria, dan semoga pod kalian nggak pernah restart tanpa alasan! 👋\u003C/p>\n","\u003Cul>\n\u003Cli>Tiga tipe probe di Kubernetes punya peran spesifik: startup probe buat inisialisasi awal, liveness probe buat deteksi deadlock atau crash, dan readiness probe buat nentuin kesiapan nerima traffic.\u003C/li>\n\u003Cli>Liveness probe yang meriksa dependensi eksternal (database/Redis) itu jebakan maut, soalnya bisa memicu restart massal alias cascading failure.\u003C/li>\n\u003Cli>Endpoint \u003Ccode>/healthz\u003C/code> buat liveness dan \u003Ccode>/ready\u003C/code> buat readiness sebaiknya dipisah di aplikasi backend, entah itu FastAPI, Go, atau Node.js.\u003C/li>\n\u003Cli>Parameter \u003Ccode>initialDelaySeconds\u003C/code>, \u003Ccode>periodSeconds\u003C/code>, \u003Ccode>timeoutSeconds\u003C/code>, dan \u003Ccode>failureThreshold\u003C/code> perlu disetel biar lonjakan CPU sesaat nggak memicu false-positive restart.\u003C/li>\n\u003C/ul>\n",[70,83,96,107],{"id":71,"title":72,"slug":73,"excerpt":74,"thumbnail_image":75,"tags":77},"46","Mengapa C Mulai Ditinggalkan: Duel Filosofi Keamanan Rust vs Kesederhanaan Zig","mengapa-c-mulai-ditinggalkan-duel-filosofi-rust-vs-zig","Pernah denger kalau sekitar 70% celah keamanan kritis software modern itu asalnya dari bahasa C? Iya, bahasa yang udah jadi fondasi internet ini 😅. Yuk, kita bedah duel filosofi Rust vs Zig dan cari tahu mana yang pas buat proyek kalian!",{"id":76},"1942a5c9-c1f6-476d-9913-768f78d9d8eb",[78,79,80,81,82],"system-programming","rust","zig","c","memory-safety",{"id":84,"title":85,"slug":86,"excerpt":87,"thumbnail_image":88,"tags":90},"45","Rate Limiting Algorithms: Token Bucket vs Leaky Bucket vs Sliding Window","rate-limiting-algorithms-token-bucket-leaky-bucket-sliding-window","Udah tahu kenapa *rate limiting* itu wajib, tapi masih bingung beda Token Bucket, Leaky Bucket, Fixed Window, dan Sliding Window? Yuk, kita adu empat algoritma ini bareng-bareng dan cari tahu mana yang paling pas buat API kalian!",{"id":89},"0e0ed26d-20c6-443c-bde1-4a6200f6f801",[53,57,91,92,93,94,95],"rate-limiting","redis","api-gateway","architecture","traffict-management",{"id":97,"title":98,"slug":99,"excerpt":100,"thumbnail_image":101,"tags":103},"44","Transactional Outbox Pattern: Solusi Konsistensi Database dan Message Broker Tanpa 2PC","transactional-outbox-pattern-konsistensi-database-message-broker","Pernah nggak kalian lihat pesanan udah masuk database, tapi email konfirmasinya nggak pernah kekirim? Itu gejala *dual-write problem*. Yuk, kita bedah Transactional Outbox Pattern biar data dan *event* kalian nggak lagi berselisih paham!",{"id":102},"e3c617fd-1486-4b82-b937-94fbec846c77",[53,55,94,104,105,57,106],"database","message-broker","postgresql",{"id":108,"title":109,"slug":110,"excerpt":111,"thumbnail_image":112,"tags":114},"43","Dead Letter Queue (DLQ) & Retry Policy: Menyelamatkan Pesan Nyasar di RabbitMQ Tanpa Bikin Worker Macet","dead-letter-queue-retry-policy-rabbitmq-resilient-messaging","Pernah nggak sih, *worker* kalian nolak satu pesan terus-terusan sampai CPU melonjak 100%? Itu namanya *poison message loop*, jebakan klasik di RabbitMQ. Yuk, kita bahas cara pasang *retry policy* dan *dead letter queue* yang bener!",{"id":113},"6c0a7ead-4841-4073-b29e-df7ae0f2aa3c",[115,105,53,94,55,116,117],"rabbitmq","async","python",[119,123,126,129,132],{"text":120,"depth":121,"id":122},"Tiga Serangkai Probe di Kubernetes",2,"tiga-serangkai-probe-di-kubernetes",{"text":124,"depth":121,"id":125},"Jebakan Terbesar: Meriksa Database di Liveness Probe","jebakan-terbesar-meriksa-database-di-liveness-probe",{"text":127,"depth":121,"id":128},"Sebaiknya Pisahkan Endpoint Health Check","sebaiknya-pisahkan-endpoint-health-check",{"text":130,"depth":121,"id":131},"Konfigurasi Manifest Kubernetes yang Ideal","konfigurasi-manifest-kubernetes-yang-ideal",{"text":133,"depth":121,"id":134},"Jadi, Gimana Biar Pod Nggak Mati Nerima Tamu?","jadi-gimana-biar-pod-nggak-mati-nerima-tamu",1791045071526]