Masalah Kode Umum dalam Layanan Mikro

Halo semuanya!

Baru-baru ini, pada konferensi PGConf di Moskow, salah satu pembicara menunjukkan arsitektur "layanan mikro", menyebutkan secara sepintas bahwa semua layanan microser mewarisi dari satu kelas dasar yang sama. Meskipun tidak ada penjelasan untuk implementasinya, tampaknya di perusahaan ini istilah "layanan mikro" tidak dipahami dengan cara yang sama seperti yang diajarkan klasik kepada kami. Hari ini kita akan membahas salah satu masalah yang menarik - apa yang bisa menjadi kode umum dalam layanan microser dan apakah bisa sama sekali.

Apa itu layanan mikro? Ini adalah aplikasi mandiri. Bukan modul, bukan proses, bukan sesuatu yang hanya dikerahkan secara terpisah, tetapi aplikasi lengkap, nyata, terpisah. Ia memiliki fungsi utamanya sendiri, tempat penyimpanannya sendiri di git, tesnya sendiri, APInya sendiri, server webnya sendiri, file README-nya sendiri, database-nya sendiri, versinya sendiri, versinya sendiri, pengembangnya sendiri.

Seperti halnya wadah, layanan microser mulai digunakan ketika kekuatan komputasi HW dan keandalan jaringan mencapai tingkat yang memungkinkan Anda melakukan panggilan fungsi yang berlangsung 100 kali lebih lama dari sebelumnya, Anda dapat membeli konsumsi memori 100 kali lebih tinggi, Anda dapat membeli barang mewah untuk menyelesaikan setiap "nenek" tidak hanya di "apartemen" yang terpisah, tetapi di "rumah" yang terpisah. Seperti halnya solusi arsitektur apa pun, arsitektur layanan microser sekali lagi mengorbankan kinerja, menang dalam pemeliharaan kode untuk pengembang. Tetapi karena orang dan kecepatan reaksinya tetap sama, sistem terus memenuhi persyaratan.

Mengapa dipisah menjadi aplikasi yang terpisah? Karena kami mendistribusikan sebagian dari kompleksitas sistem yang sudah ada di level arsitektur sistem. Proses pemrograman umumnya berbicara โ€œmenggigitโ€ bertahap dari โ€œkerumitanโ€ awal yang besar, dan dekomposisi (ke dalam kelas, modul, fungsi, dan dalam kasus kami, seluruh aplikasi) adalah implementasi bagian dari kompleksitas ini dalam bentuk struktur. Ketika kami membagi sistem menjadi layanan-layanan microser, kami membuat keputusan arsitektural (sukses atau tidak), yang tidak lagi perlu diambil oleh pengembang di masa depan ketika mengimplementasikan bagian-bagian tertentu dari fungsionalitas. Diketahui bahwa microservice khusus ini bertanggung jawab untuk mengirim email, dan yang satu ini - untuk otorisasi, telah ditetapkan, sehingga semua fitur baru saya โ€œjatuhโ€ pada pola ini tanpa diskusi.

Aspek kunci dari layanan mikro adalah konektivitas yang buruk. Layanan microser harus independen dari kata "sepenuhnya." Mereka tidak memiliki struktur data umum, dan setiap layanan mikro mungkin / harus memiliki arsitektur, teknologi, metode perakitan sendiri (dan sebagainya). Menurut definisi. Karena itu aplikasi independen. Perubahan dalam kode dari satu layanan Microsoft seharusnya tidak mempengaruhi yang lain dengan cara apa pun, kecuali jika API terpengaruh. Jika saya memiliki N microservices yang ditulis dalam Java, maka seharusnya tidak ada faktor pembatas untuk tidak menulis microservice N +1 di Python, jika ini tiba-tiba menguntungkan karena suatu alasan. Mereka secara longgar digabungkan, dan karena itu pengembang yang mulai bekerja dengan layanan mikro tertentu:

a) Sangat sensitif memonitor API-nya, karena itu adalah satu-satunya komponen yang terlihat dari luar;
b) Terasa benar-benar gratis di refactoring;
c) Memahami tujuan layanan mikro (di sini kita ingat tentang SRP) dan mengimplementasikan fungsi baru yang sesuai;
d) Memilih metode kegigihan yang paling cocok;
dll.

Semua ini baik dan terdengar logis dan harmonis, seperti banyak ideologi dan teori (dan di sini ahli teori ideologi mengakhiri dan pergi makan malam), tetapi kami sedang berlatih. Kode tidak harus ditulis di martinfowler.com . Dan cepat atau lambat kita dihadapkan dengan fakta bahwa semua layanan microser:

  • informasi log;
  • mengandung otorisasi;
  • Akses pialang pesan
  • mengembalikan pesan kesalahan yang benar;
  • entah bagaimana harus memahami entitas umum dalam sistem, jika ada;
  • harus bekerja dengan format pesan umum (dan protokol);

dan melakukannya secara identik.

Dan pada titik tertentu, arsitek ideologis datang untuk bekerja di pagi hari dan menemukan bahwa "perpustakaan" telah muncul di sistem pada malam hari - repositori baru dengan kode umum yang digunakan di banyak layanan mikro. Haruskah seorang arsitek merasa ngeri?

Itu tergantung.

Untuk menilai situasi dengan benar, kita harus kembali ke ide utama: layanan microsoft adalah kumpulan aplikasi independen yang saling berinteraksi melalui API (jaringan). Dalam hal ini kita melihat keuntungan utama dan kesederhanaan arsitektur. Dan kami tidak ingin kehilangan keunggulan ini dalam keadaan apa pun. Apakah kode umum yang ditempatkan di "perpustakaan" mengganggu ini? Mari kita lihat beberapa contoh.

1. Kelas pengguna (atau entitas bisnis lainnya) tinggal di perpustakaan.

  • yaitu entitas bisnis tidak di-enkapsulasi dalam satu layanan mikro, tetapi tersebar secara berbeda (jika tidak, mengapa dimasukkan ke perpustakaan kode bersama?);
  • yaitu layanan microser menjadi terhubung melalui entitas bisnis ini, mengubah logika bekerja dengan entitas akan mempengaruhi beberapa layanan microser;
  • itu buruk, sangat buruk, sama sekali bukan layanan mikro, meskipun itu bukan "bola lumpur besar", tetapi sangat cepat pandangan dunia tim akan mengarah pada "bola besar lumpur yang didistribusikan";
  • tetapi layanan microser dalam sistem bekerja dengan konsep yang sama, dan konsep sering merupakan entitas, atau hanya struktur dengan bidang, apa yang harus saya lakukan? baca DDD, ini persis tentang cara merangkum entitas di dalam layanan microser sehingga mereka tidak "terbang" melalui API.

Sayangnya, logika bisnis apa pun yang ditempatkan di pustaka bersama akan memiliki efek seperti itu. Pustaka kode umum cenderung tumbuh, menghasilkan bagian tengah sistem yang membentuk "tumor" logis yang tidak termasuk dalam layanan microser tertentu, dan arsitekturnya mogok. "Pusat gravitasi logis" sistem mulai bergerak ke dalam repo dengan kode umum, dan kami mendapatkan campuran monolit dan layanan mikro yang luar biasa, dan kami tidak perlu pergi ke sana sama sekali.

2. Kode parsing untuk format pesan ditempatkan di perpustakaan.

  • Kode ini kemungkinan besar ada di Jawa jika semua layanan microser ditulis dalam Java;
  • Jika besok saya menulis layanan dengan Python, saya tidak akan bisa menggunakan parser, tetapi sepertinya itu bukan masalah sama sekali, saya akan menulis versi Python;
  • Poin utama: jika saya menulis microservice baru di Java, apakah saya harus menggunakan parser ini? Ya, mungkin juga tidak. Mungkin saya tidak berkewajiban, meskipun sebagai pengembang layanan-mikro, bisa sangat berguna. Yah, seolah-olah saya menemukan sesuatu yang berguna dalam Repositori Maven.

Pengurai pesan, atau perbaikan logger, atau klien terbungkus untuk mengirim data ke RabbitMQ - ini seperti pembantu, komponen tambahan. Mereka setara dengan perpustakaan standar dari NuGet, Maven atau NPM. Pengembang layanan mikro selalu menjadi raja, ia memutuskan apakah akan menggunakan perpustakaan standar, atau membuat kode barunya sendiri, atau menggunakan kode dari perpustakaan pembantu bersama. Bagaimana itu akan lebih nyaman baginya, karena ia menulis APP TERPISAH DAN INDEPENDEN. Bisakah pembantu tertentu berkembang? Mungkin dia mungkin akan memiliki versi. Biarkan pengembang merujuk ke versi tertentu di layanannya, tidak ada yang memaksanya untuk memperbarui layanan, ketika memperbarui pembantu, ini adalah pertanyaan untuk siapa yang mendukung layanan.

3. antarmuka Java, kelas dasar abstrak, sifat.

  • Atau sepotong lain dari kategori "potongan kode";
  • Yaitu Saya di sini, mandiri dan mandiri, dan sepotong hati saya terletak di tempat lain;
  • Di sini koherensi layanan microser pada level kode muncul, jadi kami tidak akan merekomendasikannya;
  • Pada tahap awal, ini mungkin tidak akan membawa masalah nyata, tetapi esensi dari desain arsitektur adalah jaminan kenyamanan (atau ketidaknyamanan) untuk tahun-tahun mendatang.

Tim mulai bekerja pada produk baru meletakkan dasar untuk arsitektur dan memiliki pengaruh terbesar pada tren apa yang akan dimiliki produk. Jika prinsip-prinsip SRP, dekomposisi yang berhasil, konektivitas rendah, dll pada awalnya dimasukkan dalam sistem, maka ia memiliki peluang untuk terus berkembang dengan benar. Jika tidak, maka percepatan sentrifugal dari "faktor waktu" (tim lain, sedikit waktu, tambalan mendesak, kurangnya dokumentasi) akan melempar sistem ini lebih jauh ke sela-sela lebih cepat daripada yang terlihat.

Pertanyaan tentang kode umum dalam layanan microser tetap sulit karena dikaitkan dengan semacam pertukaran: kita menimbang apa yang akan lebih menguntungkan di masa depan - tingkat kemandirian layanan mikro, lebih sedikit repetisi dalam kode, kualifikasi insinyur, kesederhanaan sistem, dll. Setiap kali ini adalah refleksi dan diskusi, yang dapat menyebabkan keputusan arsitektur spesifik yang berbeda. Namun demikian, mari kita rangkum beberapa rekomendasi:

Rekomendasi 0: Jangan panggil layanan microser apa pun yang dipecah menjadi bagian yang ada secara independen. Tidak setiap tabel dengan kolom adalah matriks, mari kita gunakan istilah dengan benar.

Rekomendasi 1: Sangat diinginkan bahwa layanan microser tidak memiliki kode sama sekali.

Rekomendasi 2: Jika masih ada kode umum, biarkan itu menjadi koleksi (perpustakaan) "pembantu" opsional. Pengembang layanan memutuskan apakah akan menggunakannya atau menulis kode sendiri.

Rekomendasi 3: Dalam keadaan apa pun seharusnya tidak ada logika bisnis dalam kode umum. Semua logika bisnis diringkas dalam layanan microser.

Rekomendasi 4: Biarkan perpustakaan kode umum dirancang sebagai paket standar (NuGet, Maven, NPM, dll), dengan opsi versi (atau, bahkan lebih baik, beberapa paket terpisah).

Rekomendasi 5: "pusat gravitasi logis" dari sistem harus selalu tetap dalam layanan microser sendiri, dan tidak dalam kode umum.

Rekomendasi 6: Jika Anda berencana untuk menulis dalam format microservices, maka rekonsiliasi terlebih dahulu bahwa kode di antara mereka kadang-kadang akan diduplikasi. Dalam batas tertentu, "naluri KERING" alami kita harus ditekan.

Terima kasih atas perhatian dan layanan microser yang sukses.

Source: https://habr.com/ru/post/id454100/


All Articles