5 poin oleh GN⁺ 2023-10-31 | 1 komentar | Bagikan ke WhatsApp
  • Backend biasanya berawal sebagai monolith, tetapi ketika beberapa tim fitur mulai menyentuh codebase yang sama, coupling dapat meningkat dan kecepatan perubahan bisa melambat
  • Microservices adalah pendekatan membagi layanan berdasarkan fungsi bisnis untuk mendapatkan deployment independen dan otonomi tim kecil
  • Jika layanan terlalu kecil, beban operasional menjadi lebih besar daripada manfaatnya, sehingga nama “micro” justru dapat mengaburkan penilaian
  • Adopsi penuh membawa biaya luas, mulai dari standardisasi, provisioning sumber daya, pertahanan terhadap remote call, CI/CD, operasi, hingga eventual consistency
  • Biasanya lebih aman memulai dari monolith, mempelajari batas-batasnya dengan cukup, lalu memisahkan satu per satu ketika growing pains membesar; pendekatan microservices-first cocok ketika ada pengalaman dan kesiapan platform

Keterbatasan yang Terlihat Saat Monolith Membesar

  • Backend untuk aplikasi JavaScript single-page modern biasanya dimulai sebagai satu layanan web stateless yang menyediakan RESTful HTTP API dan menggunakan database relasional
  • Layanan ini terdiri dari komponen atau library yang mengimplementasikan berbagai fungsi bisnis
  • Semakin banyak tim fitur yang berkontribusi pada codebase yang sama, semakin tinggi coupling antarkomponen dan semakin mudah area kerja antartim saling tumpang tindih
    • Produktivitas turun, dan cakupan dampak perubahan menjadi sulit diprediksi
  • Ketika codebase sudah cukup kompleks, tidak ada orang yang benar-benar memahami keseluruhannya, sehingga implementasi fitur baru dan perbaikan bug memakan waktu lama
  • Meski backend dibagi menjadi library per tim, perubahan library pada akhirnya tetap berujung pada redeployment layanan
    • Jika bug seperti memory leak masuk, seluruh layanan bisa terdampak
    • Jika build yang salah di-rollback, dampaknya memengaruhi kecepatan semua tim, bukan hanya tim yang membuat bug

Otonomi yang Diberikan Batas Layanan

  • Salah satu cara mengurangi growing pains pada backend monolitik adalah membagi backend menjadi kumpulan layanan yang dapat di-deploy secara independen
  • Layanan-layanan berkomunikasi melalui API, dan API menciptakan batas yang lebih sulit ditembus dibanding batas komponen dalam proses yang sama
  • Arsitektur ini disebut arsitektur microservices, tetapi istilah micro dapat menimbulkan salah paham
    • Layanan tidak harus kecil
    • Layanan dengan terlalu sedikit fungsi dapat menimbulkan beban operasional yang lebih besar daripada manfaatnya
  • Nama yang lebih tepat mungkin service-oriented architecture, tetapi nama ini juga membawa beban lama

Kecepatan yang Dihasilkan Tim Kecil dan Layanan Independen

  • Jika backend dibagi menjadi layanan berdasarkan fungsi bisnis, setiap layanan dapat dikembangkan dan dioperasikan oleh satu tim kecil
  • Tim kecil lebih efektif karena biaya komunikasi meningkat secara kuadrat seiring ukuran tim
  • Ketika tiap tim menentukan jadwal rilisnya sendiri dan mengendalikan codebase, koordinasi antartim berkurang dan pengambilan keputusan menjadi lebih cepat
  • Jika codebase layanan kecil, developer lebih mudah memahaminya dan waktu adaptasi karyawan baru juga berkurang
    • Codebase kecil juga mengurangi pelambatan IDE, sehingga membantu produktivitas developer
  • Berkat batas layanan yang kuat, developer hanya perlu memahami bagian kecil, bukan keseluruhan backend, saat mengubah sebagian backend
  • Setiap layanan dapat diskalakan secara independen dan dapat memilih technology stack sesuai kebutuhannya sendiri
    • Konsumen API tidak peduli bagaimana fungsi diimplementasikan secara internal
    • Lebih mudah bereksperimen dan mengevaluasi teknologi baru tanpa memengaruhi area sistem lain
  • Setiap microservice dapat memiliki model data dan penyimpanan datanya sendiri
    • Developer dapat mengubah skema tanpa memengaruhi layanan lain

Biaya Nyata yang Ditambahkan Microservices

  • Microservices menambahkan lebih banyak moving parts ke seluruh sistem, dan biaya ini tidak gratis
  • Biaya untuk mengadopsi microservices sepenuhnya hanya layak dibayar jika dapat diamortisasi secara terdistribusi di puluhan tim developer
  • Pengalaman Developer

    • Memungkinkan setiap layanan memakai bahasa, library, dan penyimpanan data yang berbeda, tetapi hal itu dapat membuat pemeliharaan aplikasi menjadi sulit
    • Jika software stack benar-benar berbeda, developer sulit berpindah dari satu tim ke tim lain
    • Untuk menyediakan fitur umum yang dibutuhkan semua layanan, seperti logging, library harus didukung untuk setiap bahasa yang diadopsi
    • Diperlukan tingkat standardisasi tertentu
    • Pengalaman developer yang baik bagi tim yang mengikuti portofolio bahasa dan teknologi yang direkomendasikan dapat mendorong penggunaan teknologi tertentu secara longgar
  • Provisioning Sumber Daya

    • Untuk mendukung banyak layanan independen, server, penyimpanan data, dan sumber daya umum lainnya harus mudah dibuat
    • Setiap tim tidak boleh dibiarkan membuat cara pembuatan sumber daya sendiri-sendiri
    • Sumber daya yang telah diprovisioning harus dikonfigurasi lagi, dan untuk menanganinya diperlukan otomatisasi yang cukup besar
  • Komunikasi

    • Remote call mahal dan memperkenalkan cara-cara baru bagi sistem untuk runtuh
    • Untuk bersiap menghadapi kegagalan, diperlukan mekanisme pertahanan seperti timeout, retry, dan circuit breaker
    • Untuk mengurangi kerugian performa dari komunikasi jaringan, pemrosesan asinkron dan batching juga perlu dimanfaatkan
    • Faktor-faktor ini meningkatkan kompleksitas sistem
    • Monolith juga bisa mengalami masalah serupa karena akses remote client dan penggunaan API pihak ketiga, tetapi skalanya lebih kecil
  • Continuous Integration, Delivery, dan Deployment

    • Continuous integration memastikan perubahan kode digabungkan ke branch utama setelah build dan test otomatis dijalankan
    • Setelah perubahan kode digabungkan, perubahan itu harus dipublikasikan dan di-deploy secara otomatis ke lingkungan yang mirip production
    • Di lingkungan tersebut, integration test dan end-to-end test dijalankan untuk memastikan microservice tidak merusak layanan lain yang bergantung padanya
    • Pengujian microservice individual tidak lebih sulit daripada pengujian monolith, tetapi integration testing untuk semua microservice jauh lebih sulit
    • Saat layanan-layanan individual berinteraksi, perilaku yang sangat halus dan tak terduga dapat muncul
  • Operasi

    • Berbeda dari monolith, menempatkan tim operasi terpisah untuk setiap tim penanggung jawab layanan jauh lebih mahal
    • Tim yang mengembangkan layanan biasanya juga menangani on-call untuk layanan tersebut
    • Tim harus memutuskan di setiap sprint apakah akan memprioritaskan pekerjaan pengembangan atau beban operasional, dan gesekan muncul di antara keduanya
    • Debugging kegagalan sistem juga menjadi lebih sulit
    • Seluruh aplikasi tidak bisa dijalankan di mesin lokal dan dieksekusi langkah demi langkah dengan debugger
    • Karena moving parts lebih banyak, cara kegagalan juga lebih banyak
    • Logging dan monitoring yang baik di semua level menjadi penting
  • Eventual Consistency

    • Jika aplikasi dibagi menjadi beberapa layanan, model data tidak lagi hanya berada dalam satu penyimpanan data
    • Memperbarui record di penyimpanan data yang berbeda secara atomik dan menjamin strong consistency itu lambat, mahal, dan sulit diimplementasikan
    • Arsitektur seperti ini biasanya harus menerima eventual consistency

Kapan Harus Memisahkan

  • Membagi aplikasi menjadi layanan meningkatkan kompleksitas sistem secara keseluruhan secara signifikan
  • Secara umum, lebih baik memulai dengan monolith dan memecahnya hanya ketika ada alasan yang cukup untuk memisahkan
  • Karena menentukan batas antarlayanan dengan benar itu sulit, lebih mudah mencari titik yang tepat dengan memindahkan batas-batas di dalam monolith
  • Ketika monolith sudah cukup matang dan growing pains mulai membesar, microservices dapat dipisahkan satu per satu
  • Pendekatan microservices-first sebaiknya dimulai hanya jika sudah ada pengalaman, dan jika platform untuk itu sudah dibangun atau waktu yang diperlukan untuk membangun platform tersebut sudah diperhitungkan

1 komentar

 
GN⁺ 2023-10-31
Komentar Hacker News
  • Secara umum saya setuju dengan tulisannya, tetapi jika dilihat dari sisi lain, ada juga kasus ketika biayanya layak ditanggung: masalah kompatibilitas dependensi pihak ketiga yang sudah lama bisa dipisahkan menjadi layanan tersendiri sehingga kita dapat menghindari refactoring yang menyakitkan atau implementasi ulang sendiri; batasan deployment pada sistem inti ber-ketersediaan tinggi tidak sampai menghambat deployment sistem lain; dan batasan desain dari pelanggan besar yang tidak bisa mereka ubah dapat diisolasi.
    Bukan berarti ini gratis, melainkan biaya yang layak dibayar agar tidak mengubah monolit sederhana menjadi tumpukan sampah, tidak membuatnya goyah karena deployment yang berisiko, atau tidak terikat pada mitra bisnis dengan stack teknologi yang lebih buruk.

    • Menurut saya ini hanya berarti punya satu atau dua layanan. Saya tidak melihat itu sama dengan “microservices”.
      Bukankah microservices adalah pendekatan yang pada dasarnya membuat komponen internal sebagai layanan, bukan library atau class?
    • Tambahan lagi, ada keuntungan bahwa kita bisa dengan mudah memakai bahasa pemrograman yang berbeda. Tidak semua bahasa cocok untuk semua masalah.
      Jika layanan inferensi machine learning ditulis dengan Python, UI server-side rendering dengan Rails, dan layanan yang banyak I/O serta konkurensinya dengan Go, maka beban tambahan untuk memisahkan ketiganya menjadi layanan terpisah bisa dibenarkan.
    • Ada banyak cara untuk merancang dengan baik, tetapi itu bukan berarti kita harus terburu-buru mengadopsi microservices.
      Saya cukup menyukai microservices, tetapi optimasi dini dan penskalaan dini bisa sama buruknya dengan technical debt yang muncul ketika nanti harus mengoptimalkan ke arah yang sama sekali berbeda.
    • Untuk poin 1, saya tidak mengerti mengapa mengekstraknya menjadi layanan terpisah lebih baik daripada membungkusnya dengan interface yang memiliki API yang jelas.
    • Sepertinya kasus-kasus seperti itu hanya berlaku untuk kurang dari 10% dari seluruh codebase.
  • Saat yang tepat untuk mengekstrak sesuatu menjadi layanan terpisah adalah ketika muncul masalah yang tidak bisa diselesaikan dengan cara yang masih dapat dikelola tanpa melakukannya.
    Menambah kompleksitas arsitektur demi memaksakan batas bukanlah solusi untuk kurangnya disiplin organisasi, tetapi perusahaan teknologi skala menengah terus-menerus memperlakukannya seperti itu. Jika masalah muncul karena batas domain yang lemah, mengekstrak layanan kemungkinan besar tidak akan menyelesaikannya dengan baik.

    • Last responsible moment adalah strategi menunda keputusan sampai saat ketika biaya menundanya lebih lama menjadi lebih besar daripada biaya mengambil keputusan sekarang.”
      Kutipan: https://www.oreilly.com/library/view/software-architects-han...
    • Dikatakan bahwa menambah kompleksitas arsitektur demi memaksakan batas bukanlah solusi untuk kurangnya disiplin organisasi, tetapi dalam praktiknya kita selalu melakukan hal itu.
      CI/CD yang memblokir PR sampai test lulus juga merupakan solusi teknis berbiaya besar untuk menyelesaikan masalah disiplin organisasi.
    • Terdengar seperti SISP, solusi yang mencari masalah. Atau seperti melemparkan solusi ke masalah tanpa memahami akar penyebabnya.
    • Di HN tampaknya ada meme yang tersebar luas bahwa microservices sama sekali tidak pernah bisa dibenarkan, tetapi anehnya industri secara keseluruhan tidak begitu.
      Semua orang mengakui bahwa resolusi nama domain oleh layanan eksternal itu masuk akal, dan hampir tidak ada yang mengintegrasikan recursive DNS resolver beserta cache ke dalam monolit. Namun pemisahan tanggung jawab yang sudah lama seperti ini jarang diterima sebagai contoh.
    • Saya selalu menganggap ini sebagai contoh terbaik dari eksekusi yang ditunda. Mengejutkan betapa sering perusahaan salah dalam hal ini.
      Masalahnya tampaknya adalah semakin “baik” seorang karyawan, semakin besar dorongannya untuk menunjukkan nilai, yang berujung pada over-engineering, dan akhirnya menjadi neraka.
  • Microservices
    grug bertanya-tanya mengapa otak besar mengambil masalah tersulit, yaitu memecah sistem dengan benar, lalu masih menambahkan network call ke dalamnya.
    bagi grug ini terlihat sangat membingungkan.
    https://grugbrain.dev/#grug-on-microservices

    • Sepertinya grug belum pernah mengalami tim-tim besar yang saling menginjak domain dan model data satu sama lain, terkunci pada implementasi tertentu, dan membutuhkan upaya organisasi raksasa untuk merilis fitur per tim. Microservices dan pendekatan ketika masing-masing tim mengontrol data store-nya sendiri meningkatkan kecepatan tim.
      “Karena SCALE_REASONS, kami ingin memodernisasi pendekatan akses FOO_TABLE dengan pindah dari MySQL ke DynamoDB, tetapi 32 dari 59 tim mengakses FOO_TABLE secara langsung atau memanggil private method class kami secara langsung. Karena prioritas mereka berbeda, tim-tim itu tidak bisa dipindahkan agar memakai FOO_SERVICE atau mengubah cara query mereka agar memakai tabel yang di-shard. Sekarang penskalaan FOO_TABLE menjadi pekerjaan beberapa kuartal, dan kami harus memberi waktu agar tim-tim bisa memperbarui secara perlahan. Dalam 1–2 tahun, mungkin kami bisa memensiunkan cara lama yang saat ini sedang terbakar. Sementara itu, selamat menikmati on-call.”
      Dengan microservices, tim akan menyadari bahwa tabelnya tidak bisa diskalakan, tetapi data disediakan melalui API. Mereka merencanakan dan menjalankan migrasi pada sprint berikutnya, dan para pengguna API akan merasa semuanya menjadi jauh lebih cepat.
    • Static typing tidak wajib untuk autocomplete. JetBrains punya IDE yang bisa melakukan autocomplete bahkan untuk bahasa seperti Ruby atau Python.
      Jika membuka REPL Ruby modern, dari sisi autocomplete dan syntax checking Anda bisa mendapatkan banyak hal yang biasanya diharapkan dari IDE bahasa bertipe statis.
    • Memperkenalkan network call adalah hal yang kuat. Dalam praktiknya, muncul batas yang tidak dapat dilampaui dan dipaksakan secara fisik, sehingga dua layanan harus memperlakukan satu sama lain sebagai sesuatu yang terisolasi.
      Isolasi tidak boleh dianggap enteng; itu salah satu kemampuan paling kuat yang bisa dimasukkan ke dalam software. Isolasi dapat meningkatkan performa, menciptakan batas kegagalan, dan menyediakan batas keamanan.
      Ini sama dengan konsep dasar actor model. Alih-alih dua komponen saling berbagi dan mengubah memori satu sama lain, dua sistem yang terisolasi seperti actor atau microservice hanya berkomunikasi melalui protokol yang telah didefinisikan.
  • Saya rasa orang salah memahami modularitas. Modularitas memang penting, tetapi saya jadi berpikir ada satu prinsip arsitektur penting lain: prinsip pusaran tunggal
    Dalam sistem perangkat lunak, pusaran adalah loop aliran data. Jika kita mengirim data ke suatu tempat lalu menerima kembali hasil yang sudah diproses, atau dengan cara apa pun terdampak oleh data itu, berarti ada pusaran. Variabel yang dapat diubah adalah contoh pusaran yang sangat kecil
    Prinsip pusaran tunggal berarti, idealnya, sistem perangkat lunak hanya punya satu pusaran, atau dengan kata lain semua komponen harus tahu ke arah mana pusarannya berputar
    Saat menggabungkan modul-modul yang membentuk dua pusaran menjadi satu, jika arah pusarannya cocok maka komposisinya mudah; jika berlawanan arah, kita harus memutuskan bagaimana arah pusaran baru, sehingga menjadi rumit. Karena itu yang terbaik adalah semua modul memiliki arah pusaran yang sama dan membentuk satu pusaran
    Prinsip ini adalah generalisasi dari ide seperti pola Flux, CQRS, event sourcing, dan immutability

    • Poin yang sangat bagus, dan sepertinya topik ini saja bisa menjadi beberapa tulisan. Service A bisa memanggil B, B memanggil C, dan C bisa memanggil A lagi; kalau begitu masalah akan muncul
      Atau sesuatu yang tak terduga terjadi di A sehingga C ikut terblokir. Idealnya parent hanya memanggil child dan tidak bergantung pada parent; jika gagal melakukan ini, arsitekturnya juga gagal
    • Saya suka konsep ini
      Saat melihat diagram arsitektur, separuh perjuangannya adalah memahami mana yang asynchronous/synchronous, push/pull, serta arah dan urutan alirannya
      Enterprise service bus dan message queue tampak seperti solusi untuk membuat pusaran di tempat-tempat yang arah kedua sisinya tidak cocok
    • Konsep pusaran ini menarik. Saya penasaran apakah ada buku atau materi online yang layak dipelajari
    • Saya kurang memahami paragraf kedua dari terakhir, terutama bagian alasannya. Bisa dijelaskan lebih rinci?
  • Ada bagian yang menyebut masalah “jumlah library yang harus didukung untuk menyediakan fitur umum seperti logging yang dibutuhkan semua service, satu untuk tiap bahasa yang diadopsi”
    Inilah alasan terbesar kami berhenti memakai microservices. Dengan tooling tahun 2023, terutama di lingkungan cloud-native murni atau FaaS yang bisa diskalakan tanpa batas, memakai bandwidth mental untuk kekhawatiran semacam ini benar-benar sia-sia. Apalagi basis pelanggan seperti bank dan lembaga keuangan akan mengaudit tiap dependensi pihak ketiga dengan sangat ketat
    Sekarang kami beroperasi dengan satu distribusi binary monolithic .NET yang sekitar 250MB jika di-gzip, dan sama sekali belum ada tanda-tanda retak. Kalau Anda sedang mengkhawatirkan dengan teliti hal-hal seperti “exe saya tidak lagi muat di L2” untuk distribusi SaaS 10–100MB, tenang saja. Perjalanan software monolithic Anda bahkan belum dimulai
    Jika tiba saatnya harus menulis ulang salah satu tumpukan sampah seperti ini, bukankah jauh lebih mudah kalau semua commit berada di satu tempat yang konsisten secara global?

    • Menurut saya ini false dichotomy. Sebagian besar organisasi microservices yang pernah saya alami hanya mengizinkan 2–3 bahasa karena alasan seperti ini, dan leadership bisa memberi pengecualian jika tim menunjukkan bahwa mereka tidak punya opsi lain
      Microservices bukan berarti wilayah tanpa hukum, dan bukan berarti setiap tim boleh bertindak tanpa mempertimbangkan seluruh organisasi. Aturan untuk menjaga tingkat konsistensi tertentu antar-tim bisa ada dan memang seharusnya ada
    • Sebenarnya ini jauh lebih mudah di microservices. Ada interface yang jelas untuk didukung, dan kodenya tidak terjalin dengan sisa monolith seperti kepang Prancis
      Kode terbaik adalah kode yang mudah dibuang dan ditulis ulang. Dalam kenyataan, kode lama melewati lebih banyak tangan, menjadi semakin buruk, dan yang terpenting, akhirnya tidak ada yang ingin memeliharanya
    • Yang penting adalah berapa banyak developer yang bekerja di monolith itu. Ukuran binary biasanya bukan alasan tim mulai memecah monolith
    • Kalimat “bukankah jauh lebih mudah kalau semuanya ada di satu tempat sehingga tiap commit konsisten secara global?” selalu terasa agak lucu. Kedua kubu sering mengatakannya, tetapi tampaknya jarang memikirkan dari sudut pandang pihak lain
      Pihak yang menyukai microservices mengatakan perubahan atau penulisan ulang lebih mudah karena ada kontrak yang jelas tentang bagaimana service harus berperilaku, dan codebase service tersebut jauh lebih kecil
      Pihak monolith mengatakan perubahan atau penulisan ulang lebih mudah karena semuanya adalah gulungan benang besar, jadi untuk mengubah satu helai cukup mengetahui titik-titik tempat helai itu terjalin dengan helai lain
      Saya tidak tahu siapa yang benar. Monolith kemungkinan lebih baik bagi orang lama yang selama bertahun-tahun menatap codebase dengan mikroskop, sementara microservices mungkin lebih baik bagi orang lain
    • Tidak ada yang mengatakan semua microservices tidak boleh memakai bahasa yang sama
  • Dari sudut pandang release management, perpindahan dari monolith ke microservices sering dilakukan karena alasan yang keliru
    Satu-satunya alasan perubahan yang benar-benar valid tampaknya adalah masalah scalability akibat bottleneck performa. Selebihnya hanya memindahkan kompleksitas pengembangan software ke pemeliharaan sistem
    Tentu developer akan menyukainya karena beban besar untuk berkoordinasi dengan tim lain berkurang. Namun memperjelas kapan dan bagaimana fitur diimplementasikan, diuji dengan benar di seluruh microservices, diaktifkan di produksi, dan dikelola secara terpusat akan jauh lebih sulit jika komunikasi antar-tim pengembangan belum cukup matang. Dan ketidakmatangan itulah yang sering menjadi alasan sebenarnya monolith dipecah sejak awal

    • Ada banyak alasan yang valid, dan ada banyak alasan yang keliru. Jika ada banyak stakeholder, kebutuhan bisnis terus berubah, dan developernya lebih dari 10 orang, mungkin ada cukup alasan untuk memiliki unit yang bisa di-deploy, diuji, dan dirilis secara independen
      Sebaliknya, menangani banyak microservices dengan jumlah developer sedikit dan konteks yang terdefinisi baik itu menyakitkan
      Pernyataan “selebihnya hanya memindahkan kompleksitas pengembangan software ke pemeliharaan sistem” masuk akal jika software sedang aktif dikembangkan. Pengembangan itu mahal. Biaya pemeliharaan sistem terdistribusi mungkin lebih rendah daripada biaya tim besar mengembangkan monolith raksasa, dan pada akhirnya semuanya tergantung situasi
    • Ini juga satu-satunya alasan kami ingin memisahkan bagian aplikasi ini menjadi komponen tersendiri. Bagian itu sudah terlalu besar sehingga sulit dipelihara secara efektif, dan kami akan membiarkan sisa aplikasi apa adanya
  • Di mana tulisan “biaya monolit”? Di sini tidak terlihat. Yang terlihat hanya masalah ini karena semua orang mengimplementasikan microservice secara bodoh
    Kalau semua orang mengimplementasikan monolit secara bodoh, pasti akan ada sangat banyak tulisan “monolit itu buruk”
    Orang-orang tidak memahami bahwa pada akhirnya kedua sistem menghasilkan jumlah masalah yang sama. Bedanya seperti menyuruh satu gajah bekerja versus menyuruh 1000 tikus bekerja. Keduanya akan mengalami masalah, hanya saja masalahnya berbeda
    Memilih salah satu tidak membuat masalah hilang. Masalah akan muncul di sisi mana pun, dan kita harus memilih salah satu lalu menyediakan solusinya. Kalau ada perusahaan yang hambatan terbesarnya adalah “arsitekturnya apa”, saya ingin bekerja di sana

    • Alasan kita sekarang terlalu tenggelam dalam microservice adalah karena dulu ada kira-kira 8 triliun tulisan monolit itu buruk. Sekarang ini adalah reaksi balik setelah orang-orang sadar bahwa rasio biaya-manfaatnya tidak cocok untuk mereka
  • Jika sebuah monolit terurai dengan baik, apa bedanya dengan microservice yang ditempatkan di lokasi yang sama? Mungkin hanya antarmukanya. Pemanggilan fungsi menjadi RPC, dan kita menerima sedikit overhead untuk mendapatkan manfaat memperlakukan komponen secara terpisah, misalnya untuk patch
    Apa bedanya microservice terdistribusi dengan microservice yang berada di lokasi yang sama? Deployment lebih rumit, tetapi proses bisa ditempatkan secara cerdas pada hardware yang lebih sesuai. Mode kegagalan bertambah, tetapi kita bisa memperoleh toleransi kegagalan yang lebih tinggi
    Tidak ada jawaban serba guna di sini. Jika butuh manfaatnya, bayar biayanya. Menurut saya perdebatan microservice vs monolit seperti ini muncul karena suatu pola diterapkan secara keliru, kurangnya alat yang bisa memudahkan hidup, atau sebagian besar karena software berusia 10 tahun tidak terus direfaktor dan didesain ulang sehingga menjadi menyakitkan untuk dikerjakan terlepas dari arsitektur awalnya

    • Beralih dari monolit ke microservice bukan perubahan sepele, betapapun baiknya pemisahan di awal. Tentu saja jika desainnya buruk, transisinya akan lebih sulit
      Ungkapan “pemanggilan fungsi menjadi RPC” terdengar sederhana, tetapi begitu itu terjadi, aplikasi klien harus menangani semua jalur eksekusi seperti server DNS tidak dapat diakses, resolusi hostname gagal, host tidak dapat dijangkau, koneksi ditolak, autentikasi ditolak, sertifikat TLS tidak tepercaya, batas laju terlampaui, 301 pindah permanen, hasil terlambat siap, dan timeout
      Bahkan aplikasi yang terurai dengan baik kemungkinan besar harus didesain ulang agar bisa menangani ini secara tangguh, dengan antrean asinkron, pembatasan laju permintaan, cache hasil, retry dengan backoff log, kredensial klien・trust store・URL resource yang dapat dikonfigurasi, serta logging kegagalan
      Pada pemanggilan fungsi lokal, fungsi RPC dan parameter tambahan juga diperlukan untuk menyediakan data yang sebelumnya ada dalam konteks. Selain itu, UI monolit mungkin perlu menyampaikan latensi dan kegagalan jaringan kepada pengguna, sesuatu yang sebelumnya tidak mungkin terjadi
      Bahkan monolit yang dibuat paling baik pun membutuhkan upaya besar untuk direfaktor menjadi microservice
    • Di balik ungkapan “pemanggilan fungsi menjadi RPC” ada mode kegagalan baru dan lebih banyak pekerjaan plumbing
      Apakah panggilan RPC ini bisa di-retry dengan aman? Bagaimana dengan exponential backoff? Apakah API load balancer bekerja dengan benar? Kalau begitu monitoring juga diperlukan. Bagaimana melakukan tracing antar-microservice? Sekarang kita memerlukan sesuatu seperti OpenTelemetry
      Seberapa jauh lebih sulit debugging dengan breakpoint dalam arsitektur microservice? Bagaimana membatalkan transaksi database di antara dua microservice? Pemanggilan fungsi sederhana tiba-tiba menjadi jauh lebih kompleks
    • Saat membahas microservice, pihak yang mendukung hampir selalu melupakan bagian micro yang merupakan inti konsep ini. Service sendiri sudah diketahui semua orang dan bisa dibuat bila perlu; itu bukan konsep yang perlu diyakinkan
      Setiap kali membela konsep ini, mereka mengabaikan fragmentasi yang ditimbulkan oleh tuntutan bahwa service harus sangat kecil. Lebih spesifiknya, jika ada satu monolit dan satu microservice, itu bukan microservice-microservice. Istilah microservice menyiratkan bahwa semuanya dipecah menjadi service kecil dan tidak ada monolit
      Sebagian besar argumen pro-microservice runtuh begitu menyadari bahwa ia harus benar-benar “micro”. Dan jika tuntutan itu ditinggalkan, tidak ada usulan baru atau mendalam yang tersisa
    • Dari sudut pandang developer, perbedaannya ada pada antarmuka. Ada segala macam alat untuk menjaga monolit tetap tersinkron dan benar, tetapi alat yang membantu komunikasi antarproses tidak bisa melakukan evaluasi statis dan sama sekali tidak interaktif
      Dari sudut pandang operasi, mengatakan “deployment lebih rumit” adalah pernyataan yang sangat mengecilkan masalah. Setiap paket adalah objek yang harus dikelola secara terpisah, dengan karakteristik dan masalahnya sendiri
    • Kita kehilangan transaksi atomik. Karena itu, setiap operasi bisnis menjadi beberapa orde magnitudo lebih kompleks
  • Mirip dengan developer frontend yang berpikir mereka tidak bisa membuat “aplikasi web modern” tanpa framework atau library frontend seperti React/Vue/Svelte, sekarang tampaknya ada anggapan bahwa “monolit” sama dengan menjalankan satu bongkahan tar raksasa yang menakutkan sebagai satu instance sehingga “tidak bisa diskalakan”, dan ini tidak masuk akal
    Hal lain yang terlihat adalah jumlah kode keseluruhan menjadi jauh lebih besar, dan sebagian besar service terdiri dari 20% kode bisnis/domain dan 80% penanganan pengiriman dan penerimaan pesan jaringan. Sebaik apa pun disembunyikan, pada akhirnya itu tetap ada, dan jaringan harus ditangani dengan suatu cara
    Sama seperti kegilaan frontend, kultus microservice ini baru akan berakhir ketika ekonomi runtuh dan tidak ada lagi uang untuk menopang menara Babel menuju kehancuran seperti ini
    Sebagai tambahan, microservice juga punya tempat penggunaannya. Di sebagian perusahaan yang mendapatkan nilai lebih besar daripada biayanya, itu memang tepat

    • Hal yang dilewatkan orang tentang microservice adalah bahwa tujuannya biasanya bukan menyelesaikan masalah teknis, melainkan masalah organisasi dan manusia
      Ada juga manfaat teknis seperti penskalaan independen per service, tetapi manfaat terbesarnya adalah batas kepemilikan yang jelas dan mencegah coupling berlebihan yang tidak perlu
      Jika tim kecil membuat satu produk, kemungkinan besar belum ada masalah organisasi yang dipecahkan oleh microservice, jadi mungkin tidak diperlukan. Dalam kasus itu, microservice adalah optimasi prematur, artinya membayar biaya untuk menyelesaikan masalah yang belum ada
    • React/Vue/Svelte bukan framework, melainkan library view, dan saya akan mempertahankan posisi ini sampai akhir
      Lebih jauh lagi, kompleksitas frontend semuanya ada di kepala: https://bower.sh/front-end-complexity
    • Saya setuju bahwa banyak website memakai JavaScript dan framework secara berlebihan. Namun saat membuat aplikasi web setara desktop, saya penasaran apa yang sebaiknya digunakan agar tidak berubah menjadi kekacauan besar atau pada akhirnya menciptakan ulang konsep-konsep yang sudah ada dalam framework seperti ini
  • Tulisan ini tampaknya berangkat dari premis bahwa organisasi pengembangan sudah benar-benar rusak dan di luar kendali. Mereka tidak bisa menentukan apa yang akan dikerjakan selama sprint, diam-diam memasukkan library pihak ketiga dan bahasa yang tidak dikenal, lalu diam-diam menerapkan perubahan yang tidak kompatibel ke produksi
    Kalau para developer bukan orang bodoh, microservices juga rasanya akan lebih mudah

    • Sayangnya, cukup umum ada orang bodoh di dalam tim, atau seluruh tim yang bekerja di proyek yang sama itu bodoh
      Saya yakin microservices akan lebih mudah jika bekerja di tim yang terdiri dari developer yang cerdas dan kompeten. Tentu saja, kalau begitu semuanya juga akan jadi lebih mudah
    • Setiap developer pasti bisa terlihat bodoh selama beberapa bulan pertama di tempat kerja baru. Sebab butuh waktu untuk menyerap informasi yang diperlukan guna memahami bagaimana sistem yang sudah ada bekerja