Bagikan melalui


Arsitektur aplikasi web umum

Petunjuk / Saran

Konten ini adalah kutipan dari eBook, Architect Modern Web Applications dengan ASP.NET Core dan Azure, tersedia di .NET Docs atau sebagai PDF gratis yang dapat diunduh yang dapat dibaca secara offline.

Rancang Aplikasi Web Modern dengan ASP.NET Core dan Azure eBook gambar mini sampul.

"Jika menurut Anda arsitektur yang baik mahal, cobalah arsitektur yang buruk." - Brian Foote dan Joseph Yoder

Sebagian besar aplikasi .NET tradisional disebarkan sebagai satu kesatuan yang berfungsi sebagai unit eksekusi atau aplikasi web tunggal yang berjalan dalam satu app domain IIS. Pendekatan ini adalah model penyebaran paling sederhana dan melayani banyak aplikasi publik internal dan lebih kecil dengan sangat baik. Namun, meskipun hanya dengan satu unit penyebaran ini, sebagian besar aplikasi bisnis yang kompleks mendapat manfaat dari berbagai pemisahan logis menjadi beberapa lapisan.

Apa itu aplikasi monolitik?

Aplikasi monolitik adalah aplikasi yang sepenuhnya mandiri, dalam hal perilakunya. Ini dapat berinteraksi dengan layanan atau penyimpanan data lain selama melakukan operasinya, tetapi inti perilakunya berjalan dalam prosesnya sendiri dan seluruh aplikasi biasanya disebarkan sebagai satu unit. Jika aplikasi semacam itu perlu diskalakan secara horizontal, biasanya seluruh aplikasi diduplikasi di beberapa server atau komputer virtual.

Aplikasi serba guna

Jumlah proyek sekecil mungkin untuk arsitektur aplikasi adalah satu. Dalam arsitektur ini, seluruh logika aplikasi terkandung dalam satu proyek, dikompilasi ke satu rakitan, dan disebarkan sebagai satu unit.

Proyek baru ASP.NET Core, baik yang dibuat di Visual Studio maupun dari baris perintah, dimulai sebagai monolit sederhana "semua-dalam-satu". Ini berisi semua perilaku aplikasi, termasuk logika presentasi, bisnis, dan akses data. Gambar 5-1 menunjukkan struktur file aplikasi proyek tunggal.

Satu proyek ASP.NET aplikasi Core

Gambar 5-1. Proyek tunggal aplikasi ASP.NET Core.

Dalam skenario proyek tunggal, pemisahan kekhawatiran dicapai melalui penggunaan folder. Templat default mencakup folder terpisah untuk tanggung jawab pola MVC Model, Tampilan, dan Pengontrol, serta folder tambahan untuk Data dan Layanan. Dalam pengaturan ini, detail presentasi harus dibatasi sebanyak mungkin ke folder Tampilan, dan detail implementasi akses data harus dibatasi pada kelas yang disimpan di folder Data. Logika bisnis harus berada di layanan dan kelas dalam folder Model.

Meskipun sederhana, solusi monolitik proyek tunggal memiliki beberapa kelemahan. Seiring bertambahnya ukuran dan kompleksitas proyek, jumlah file dan folder juga akan terus bertambah. Masalah antarmuka pengguna (UI) (model, tampilan, pengontrol) berada di beberapa folder, yang tidak dikelompokkan bersama menurut abjad. Masalah ini bertambah parah ketika elemen tambahan pada tingkat UI, seperti filter atau pengikat model (ModelBinders), ditambahkan ke folder khusus mereka. Logika bisnis tersebar di antara folder Model dan Layanan, dan tidak ada indikasi yang jelas tentang kelas mana yang harus bergantung pada folder lain. Kurangnya organisasi di tingkat proyek ini sering menyebabkan kode spaghetti.

Untuk mengatasi masalah ini, aplikasi sering berkembang menjadi solusi multi-proyek, di mana setiap proyek dianggap berada di lapisan aplikasi tertentu.

Apa itu lapisan?

Ketika aplikasi tumbuh dalam kompleksitas, salah satu cara untuk mengelola kompleksitas tersebut adalah dengan memecah aplikasi sesuai dengan tanggung jawab atau kekhawatirannya. Pendekatan ini mengikuti pemisahan prinsip kekhawatiran dan dapat membantu menjaga basis kode yang berkembang terorganisir sehingga pengembang dapat dengan mudah menemukan di mana fungsionalitas tertentu diterapkan. Arsitektur berlapis menawarkan sejumlah keuntungan selain hanya organisasi kode.

Dengan mengatur kode ke dalam lapisan, fungsionalitas tingkat rendah umum dapat digunakan kembali di seluruh aplikasi. Penggunaan kembali ini bermanfaat karena berarti lebih sedikit kode yang perlu ditulis dan karena dapat memungkinkan aplikasi untuk menstandarkan pada satu implementasi, mengikuti prinsip jangan ulangi diri Sendiri (DRY).

Dengan arsitektur berlapis, aplikasi dapat memberlakukan pembatasan di lapisan mana yang dapat berkomunikasi dengan lapisan lain. Arsitektur ini membantu mencapai enkapulasi. Ketika lapisan diubah atau diganti, hanya lapisan yang bekerja dengannya yang harus terpengaruh. Dengan membatasi lapisan mana yang bergantung pada lapisan lain mana, dampak perubahan dapat dimitigasi sehingga satu perubahan tidak berdampak pada seluruh aplikasi.

Lapisan (dan enkapulasi) membuatnya jauh lebih mudah untuk mengganti fungsionalitas dalam aplikasi. Misalnya, aplikasi awalnya mungkin menggunakan database SQL Server sendiri untuk persistensi, tetapi nantinya dapat memilih untuk menggunakan strategi persistensi berbasis cloud, atau satu di belakang API web. Jika aplikasi telah merangkum implementasi persistensinya dengan benar dalam lapisan logis, lapisan khusus SQL Server dapat digantikan oleh yang baru yang mengimplementasikan antarmuka publik yang sama.

Selain potensi pertukaran implementasi sebagai respons terhadap perubahan persyaratan di masa mendatang, lapisan aplikasi juga dapat mempermudah pertukaran implementasi untuk tujuan pengujian. Alih-alih harus menulis pengujian yang beroperasi terhadap lapisan data nyata atau lapisan UI aplikasi, lapisan ini dapat diganti pada waktu pengujian dengan implementasi palsu yang memberikan respons yang diketahui terhadap permintaan. Pendekatan ini biasanya membuat pengujian jauh lebih mudah ditulis dan jauh lebih cepat untuk dijalankan jika dibandingkan dengan menjalankan pengujian terhadap infrastruktur nyata aplikasi.

Lapisan logis adalah teknik umum untuk meningkatkan organisasi kode dalam aplikasi perangkat lunak perusahaan, dan ada beberapa cara di mana kode dapat diatur ke dalam lapisan.

Nota

Lapisan mewakili pemisahan logis dalam aplikasi. Jika logika aplikasi didistribusikan secara fisik ke server atau proses terpisah, target penyebaran fisik terpisah ini disebut sebagai tingkatan. Dimungkinkan, dan cukup umum, untuk memiliki aplikasi N-Layer yang disebarkan ke satu tingkat.

Aplikasi arsitektur "N-Layer" tradisional

Organisasi logika aplikasi yang paling umum ke dalam lapisan ditunjukkan pada Gambar 5-2.

Lapisan aplikasi umum

Gambar 5-2. Lapisan aplikasi umum.

Lapisan ini sering disingkat sebagai UI, BLL (Business Logic Layer), dan DAL (Lapisan Akses Data). Dengan menggunakan arsitektur ini, pengguna membuat permintaan melalui lapisan UI, yang hanya berinteraksi dengan BLL. BLL, pada gilirannya, dapat memanggil DAL untuk permintaan akses data. Lapisan UI tidak boleh membuat permintaan apa pun ke DAL secara langsung, juga tidak boleh berinteraksi dengan persistensi langsung melalui cara lain. Demikian juga, BLL hanya boleh berinteraksi dengan persistensi dengan melalui DAL. Dengan cara ini, setiap lapisan memiliki tanggung jawab yang khusus yang sudah dikenal.

Salah satu kerugian dari pendekatan lapisan tradisional ini adalah bahwa dependensi waktu kompilasi berjalan dari atas ke bawah. Artinya, lapisan UI tergantung pada BLL, yang tergantung pada DAL. Ini berarti bahwa BLL, yang biasanya memegang logika terpenting dalam aplikasi, tergantung pada detail implementasi akses data (dan seringkali pada keberadaan database). Menguji logika bisnis dalam arsitektur seperti itu seringkali sulit, membutuhkan database pengujian. Prinsip inversi dependensi dapat digunakan untuk mengatasi masalah ini, seperti yang akan Anda lihat di bagian berikutnya.

Gambar 5-3 menunjukkan contoh solusi, memecah aplikasi menjadi tiga proyek berdasarkan tanggung jawab (atau lapisan).

Aplikasi monolitik sederhana dengan tiga proyek

Gambar 5-3. Aplikasi monolitik sederhana dengan tiga proyek.

Meskipun aplikasi ini menggunakan beberapa proyek untuk tujuan organisasi, aplikasi ini masih disebarkan sebagai satu unit dan kliennya akan berinteraksi dengannya sebagai satu aplikasi web. Ini memungkinkan proses penyebaran yang sangat sederhana. Gambar 5-4 menunjukkan bagaimana aplikasi tersebut mungkin dihosting menggunakan Azure.

Penyebaran sederhana Azure Web App

Gambar 5-4. Implementasi sederhana aplikasi web Azure

Saat kebutuhan aplikasi tumbuh, solusi penyebaran yang lebih kompleks dan kuat mungkin diperlukan. Gambar 5-5 menunjukkan contoh rencana penyebaran yang lebih kompleks yang mendukung kemampuan tambahan.

Menyebarkan aplikasi web ke Azure App Service

Gambar 5-5. Menyebarkan aplikasi web ke Azure App Service

Secara internal, organisasi proyek ini menjadi beberapa proyek berdasarkan tanggung jawab meningkatkan keberlanjutan aplikasi.

Unit ini dapat diperbesar atau diperluas skalanya untuk memanfaatkan skalabilitas berbasis cloud sesuai permintaan. Peningkatan skala berarti menambahkan CPU, memori, ruang disk, atau sumber daya lain tambahan ke server yang menghosting aplikasi Anda. Perluasan skala berarti menambahkan instans tambahan server tersebut, apakah ini adalah server fisik, komputer virtual, atau kontainer. Saat aplikasi Anda dihosting di beberapa instans, load balancer digunakan untuk menetapkan permintaan ke instans aplikasi individual.

Pendekatan paling sederhana untuk menskalakan aplikasi web di Azure adalah mengonfigurasi penskalakan secara manual dalam Paket App Service aplikasi. Gambar 5-6 menunjukkan layar dasbor Azure yang sesuai untuk mengonfigurasi berapa banyak instans yang melayani aplikasi.

Skala Rencana App Service di Azure

Gambar 5-6. Penskalakan Rencana Layanan Aplikasi di Azure.

Arsitektur bersih

Aplikasi yang mengikuti Prinsip Inversi Dependensi serta prinsip Domain-Driven Design (DDD) cenderung tiba pada arsitektur serupa. Arsitektur ini telah dikenal dengan banyak nama selama bertahun-tahun. Salah satu nama pertama adalah Arsitektur Heksagonal, diikuti oleh Ports-and-Adapters. Baru-baru ini, ini disebutkan sebagai Arsitektur Bawang atau Arsitektur Bersih. Nama terakhir, Clean Architecture, digunakan sebagai nama untuk arsitektur ini dalam e-book ini.

Aplikasi referensi eShopOnWeb menggunakan pendekatan Clean Architecture dalam mengatur kodenya ke dalam proyek. Anda dapat menemukan templat solusi yang dapat Anda gunakan sebagai titik awal untuk solusi ASP.NET Core Anda sendiri di repositori GitHub ardalis/cleanarchitecture atau dengan menginstal templat dari NuGet.

Arsitektur bersih menempatkan logika bisnis dan model aplikasi di pusat aplikasi. Alih-alih memiliki logika bisnis tergantung pada akses data atau masalah infrastruktur lainnya, dependensi ini terbalik: detail infrastruktur dan implementasi tergantung pada Inti Aplikasi. Fungsionalitas ini dicapai dengan mendefinisikan abstraksi, atau antarmuka, di Inti Aplikasi, yang kemudian diimplementasikan oleh jenis yang ditentukan dalam lapisan Infrastruktur. Cara umum memvisualisasikan arsitektur ini adalah dengan menggunakan serangkaian lingkaran konsentris, mirip dengan bawang. Gambar 5-7 menunjukkan contoh gaya representasi arsitektur ini.

Arsitektur Bersih; pandangan berlapis

Gambar 5-7. Clean Architecture; tampilan berlapis seperti bawang

Dalam diagram ini, dependensi mengalir ke lingkaran terdalam. Application Core mengambil namanya dari posisinya pada inti diagram ini. Dan Anda dapat melihat pada diagram bahwa Application Core tidak memiliki dependensi pada lapisan aplikasi lain. Entitas dan antarmuka aplikasi berada di pusat. Tepat di luar, tetapi masih di Application Core, adalah layanan domain, yang biasanya mengimplementasikan antarmuka yang ditentukan dalam lingkaran dalam. Di luar Inti Aplikasi, baik lapisan UI dan Infrastruktur bergantung pada Application Core, tetapi tidak satu sama lain (tentu saja).

Gambar 5-8 menunjukkan diagram lapisan horizontal yang lebih tradisional yang lebih mencerminkan dependensi antara UI dan lapisan lainnya.

Arsitektur Bersih; tampilan lapisan horizontal

Gambar 5-8. Arsitektur Bersih; tampilan lapisan horizontal

Perhatikan bahwa panah solid mewakili dependensi waktu kompilasi, sementara panah putus-putus mewakili dependensi khusus runtime. Dengan arsitektur bersih, lapisan UI bekerja dengan antarmuka yang ditentukan dalam Application Core pada waktu kompilasi, dan idealnya tidak boleh tahu tentang jenis implementasi yang ditentukan dalam lapisan Infrastruktur. Namun, pada waktu proses, jenis implementasi ini diperlukan agar aplikasi dapat dijalankan, sehingga perlu ada dan terhubung ke antarmuka Application Core melalui injeksi dependensi.

Gambar 5-9 menunjukkan tampilan yang lebih rinci tentang arsitektur aplikasi ASP.NET Core saat dibangun mengikuti rekomendasi ini.

diagram arsitektur inti ASP.NET mengikuti Arsitektur Bersih

Gambar 5-9. Diagram arsitektur ASP.NET Core mengikuti Arsitektur Bersih.

Karena Application Core tidak bergantung pada Infrastruktur, sangat mudah untuk menulis pengujian unit otomatis untuk lapisan ini. Gambar 5-10 dan 5-11 menunjukkan bagaimana pengujian cocok dengan arsitektur ini.

UnitTestCore

Gambar 5-10. Unit menguji Application Core dalam isolasi.

IntegrationTests

Gambar 5-11. Pengujian Integrasi Infrastruktur dengan dependensi eksternal.

Karena lapisan UI tidak memiliki dependensi langsung pada jenis yang ditentukan dalam proyek Infrastruktur, demikian juga sangat mudah untuk menukar implementasi, baik untuk memfasilitasi pengujian atau sebagai respons terhadap perubahan persyaratan aplikasi. Penggunaan dan dukungan bawaan ASP.NET Core untuk injeksi ketergantungan menjadikan arsitektur ini cara paling tepat untuk menyusun aplikasi monolitik yang kompleks.

Untuk aplikasi monolitik, proyek Application Core, Infrastructure, dan UI semuanya dijalankan sebagai satu aplikasi. Arsitektur aplikasi runtime mungkin terlihat seperti Gambar 5-12.

Arsitektur ASP.NET Core 2

Gambar 5-12. Sampel arsitektur runtime aplikasi ASP.NET Core.

Mengatur kode dalam Arsitektur Bersih

Dalam solusi Arsitektur Bersih, setiap proyek memiliki tanggung jawab yang jelas. Dengan demikian, jenis tertentu termasuk dalam setiap proyek dan Anda akan sering menemukan folder yang sesuai dengan jenis ini dalam proyek yang sesuai.

Inti Aplikasi

Application Core memegang model bisnis, yang mencakup entitas, layanan, dan antarmuka. Antarmuka ini mencakup abstraksi untuk operasi yang akan dilakukan menggunakan Infrastruktur, seperti akses data, akses sistem file, panggilan jaringan, dll. Terkadang layanan atau antarmuka yang ditentukan pada lapisan ini perlu bekerja dengan jenis non-entitas yang tidak memiliki dependensi pada UI atau Infrastruktur. Ini dapat didefinisikan sebagai Objek Transfer Data (DTO) sederhana.

Jenis Inti Aplikasi
  • Entitas (kelas model bisnis yang dipertahankan)
  • Agregat (grup entitas)
  • Antarmuka
  • Layanan Domain
  • Spesifikasi
  • Pengecualian Kustom dan Klausul Penjaga
  • Peristiwa dan Penanganan Domain

Infrastruktur

Proyek Infrastruktur biasanya mencakup implementasi akses data. Dalam aplikasi web ASP.NET Core yang khas, implementasi ini termasuk Entity Framework (EF) DbContext, objek EF Core Migration apa pun yang telah ditentukan, dan kelas implementasi akses data. Cara paling umum untuk mengabstraksi kode implementasi akses data adalah melalui penggunaan pola desain Repositori.

Selain implementasi akses data, proyek Infrastruktur harus berisi implementasi layanan yang harus berinteraksi dengan masalah infrastruktur. Layanan ini harus menerapkan antarmuka yang ditentukan dalam Inti Aplikasi, sehingga Infrastruktur harus memiliki referensi ke proyek Inti Aplikasi.

Jenis infrastruktur
  • Jenis Inti EF (DbContext, Migration)
  • Jenis implementasi akses data (Repositori)
  • Layanan khusus infrastruktur (misalnya, FileLogger atau SmtpNotifier)

Lapisan UI

Lapisan antarmuka pengguna dalam aplikasi ASP.NET Core MVC adalah titik masuk untuk aplikasi. Proyek ini harus mereferensikan proyek Application Core, dan jenisnya harus berinteraksi dengan infrastruktur secara ketat melalui antarmuka yang ditentukan dalam Application Core. Tidak ada instansiasi langsung atau pemanggilan statis terhadap jenis lapisan Infrastruktur yang diperbolehkan di lapisan antarmuka pengguna (UI).

Jenis Lapisan UI
  • Pengontrol
  • Filter Kustom
  • Middleware Kustom
  • Pandangan
  • ViewModels
  • Perusahaan rintisan

File Startup kelas atau Program.cs bertanggung jawab untuk mengonfigurasi aplikasi, dan untuk menghubungkan jenis implementasi ke antarmuka. Tempat di mana logika ini dilakukan dikenal sebagai akar komposisi aplikasi, dan itulah yang memungkinkan injeksi dependensi berfungsi dengan baik pada waktu proses.

Nota

Untuk menghubungkan injeksi dependensi selama startup aplikasi, proyek lapisan UI mungkin perlu mereferensikan proyek Infrastruktur. Dependensi ini dapat dihilangkan, paling mudah dengan menggunakan kontainer DI kustom yang secara bawaan mendukung pemuatan tipe dari rakitan. Untuk tujuan sampel ini, pendekatan paling sederhana adalah memungkinkan proyek UI mereferensikan proyek Infrastruktur (tetapi pengembang harus membatasi referensi aktual ke jenis dalam proyek Infrastruktur ke akar komposisi aplikasi).

Aplikasi dan kontainer monolitik

Anda dapat membangun Aplikasi Web atau Layanan berbasis penyebaran tunggal dan monolitik dan menyebarkannya sebagai kontainer. Dalam aplikasi, mungkin tidak monolitik tetapi diatur dalam beberapa pustaka, komponen, atau lapisan. Secara eksternal, ini adalah satu kontainer dengan satu proses, aplikasi web tunggal, atau layanan tunggal.

Untuk mengelola model ini, Anda menyebarkan satu kontainer untuk mewakili aplikasi. Untuk menskalakan, cukup tambahkan salinan tambahan dengan load balancer di depan. Kesederhanaan berasal dari mengelola satu penyebaran dalam satu kontainer atau VM.

Gambar 5-13

Anda dapat menyertakan beberapa komponen/pustaka atau lapisan internal dalam setiap kontainer, seperti yang diilustrasikan dalam Gambar 5-13. Tetapi, mengikuti prinsip kontainer "kontainer melakukan satu hal, dan melakukannya dalam satu proses", pola monolitik mungkin merupakan konflik.

Kelemahan dari pendekatan ini datang jika/ketika aplikasi tumbuh, mengharuskannya untuk menskalakan. Jika seluruh aplikasi berkembang skala, itu tidak terlalu menjadi masalah. Namun, dalam kebanyakan kasus, beberapa bagian aplikasi adalah bottleneck yang memerlukan penskalaan, sementara komponen lain kurang digunakan.

Menggunakan contoh eCommerce yang khas, yang mungkin perlu Anda skalakan adalah komponen informasi produk. Lebih banyak pelanggan menelusuri produk daripada membelinya. Lebih banyak pelanggan menggunakan keranjang mereka daripada menggunakan alur pembayaran. Lebih sedikit pelanggan menambahkan komentar atau melihat riwayat pembelian mereka. Dan Anda mungkin hanya memiliki beberapa karyawan, dalam satu wilayah, yang perlu mengelola konten dan kampanye pemasaran. Dengan meningkatkan skala desain monolitik, semua kode dijalankan berulang kali.

Selain masalah "skalakan semuanya", perubahan pada satu komponen memerlukan pengetesan ulang lengkap dari seluruh aplikasi, dan penyebaran ulang lengkap semua instans.

Pendekatan monolitik adalah umum, dan banyak organisasi mengembangkan dengan pendekatan arsitektur ini. Banyak yang memiliki hasil yang cukup baik, sementara yang lain mencapai batas. Banyak yang merancang aplikasi mereka dalam model ini, karena alat dan infrastruktur terlalu sulit untuk membangun arsitektur berorientasi layanan (SOA), dan mereka tidak melihat kebutuhan sampai aplikasi tumbuh. Jika Anda menemukan bahwa Anda mencapai batas pendekatan monolitik, memecah aplikasi untuk memungkinkannya memanfaatkan kontainer dan layanan mikro dengan lebih baik mungkin merupakan langkah logis berikutnya.

Gambar 5-14

Menyebarkan aplikasi monolitik di Microsoft Azure dapat dicapai menggunakan VM khusus untuk setiap instans. Dengan menggunakan Azure Virtual Machine Scale Sets, Anda dapat dengan mudah menskalakan VM. Azure App Services dapat menjalankan aplikasi monolitik dan menskalakan instans dengan mudah tanpa harus mengelola VM. Azure App Services juga dapat menjalankan instans tunggal kontainer Docker, menyederhanakan penyebaran. Dengan menggunakan Docker, Anda dapat menyebarkan satu VM sebagai host Docker, dan menjalankan beberapa instans. Menggunakan azure balancer, seperti yang ditunjukkan pada Gambar 5-14, Anda dapat mengelola penskalakan.

Penyebaran ke berbagai host dapat dikelola dengan teknik penyebaran tradisional. Host Docker dapat dikelola dengan perintah seperti eksekusi docker yang dilakukan secara manual, atau melalui otomatisasi seperti alur Pengiriman Berkelanjutan (CD).

Aplikasi monolitik yang disebarkan sebagai kontainer

Ada manfaat menggunakan kontainer untuk mengelola penyebaran aplikasi monolitik. Peningkatan instansia kontainer jauh lebih cepat dan lebih mudah dibandingkan penerapan VM tambahan. Bahkan saat menggunakan set skala mesin virtual untuk menskalakan VM, dibutuhkan waktu untuk membuatnya. Saat disebarkan sebagai instans aplikasi, konfigurasi aplikasi dikelola sebagai bagian dari VM.

Menyebarkan pembaruan sebagai gambar Docker jauh lebih cepat dan efisien dalam jaringan. Gambar Docker biasanya dimulai dalam hitungan detik, mempercepat penyebaran. Menghentikan instans Docker semudah menjalankan perintah docker stop, biasanya selesai dalam waktu kurang dari satu detik.

Karena kontainer secara inheren tidak dapat diubah secara desain, Anda tidak perlu khawatir tentang VM yang rusak, sedangkan skrip pembaruan mungkin lupa memperhitungkan beberapa konfigurasi atau file tertentu yang tersisa di disk.

Anda dapat menggunakan kontainer Docker untuk penyebaran monolitik aplikasi web yang lebih sederhana. Pendekatan ini meningkatkan integrasi berkelanjutan dan alur penyebaran berkelanjutan dan membantu mencapai keberhasilan penyebaran ke produksi. Tidak ada lagi "Ini berfungsi pada mesin saya, mengapa tidak berfungsi dalam produksi?"

Arsitektur berbasis layanan mikro memiliki banyak manfaat, tetapi manfaat tersebut dikenakan biaya peningkatan kompleksitas. Dalam beberapa kasus, biaya melebihi manfaatnya, sehingga aplikasi penyebaran monolitik yang berjalan dalam satu kontainer atau hanya dalam beberapa kontainer adalah pilihan yang lebih baik.

Aplikasi monolitik mungkin tidak mudah diurai menjadi layanan mikro yang dipisahkan dengan baik. Layanan mikro harus bekerja secara independen satu sama lain untuk menyediakan aplikasi yang lebih tangguh. Jika Anda tidak dapat memberikan irisan fitur independen aplikasi, memisahkannya hanya menambah kompleksitas.

Aplikasi mungkin belum perlu menskalakan fitur secara independen. Banyak aplikasi, ketika mereka perlu menskalakan melebihi satu instans, dapat melakukannya melalui proses kloning yang relatif sederhana dari seluruh instans tersebut. Pekerjaan tambahan untuk memisahkan aplikasi menjadi layanan diskrit memberikan manfaat minimal ketika peningkatan skala seluruh instans aplikasi mudah dan hemat biaya.

Di awal pengembangan aplikasi, Anda mungkin tidak memiliki gagasan yang jelas di mana batas fungsional alami berada. Saat Anda mengembangkan produk yang layak minimum, pemisahan alami mungkin belum terjadi. Beberapa kondisi ini mungkin bersifat sementara. Anda mungkin mulai dengan membuat aplikasi monolitik, dan kemudian memisahkan beberapa fitur yang akan dikembangkan dan disebarkan sebagai layanan mikro. Kondisi lain mungkin penting untuk ruang masalah aplikasi, yang berarti bahwa aplikasi mungkin tidak pernah dipecah menjadi beberapa layanan mikro.

Memisahkan aplikasi ke dalam banyak proses diskrit juga memperkenalkan overhead. Ada lebih banyak kompleksitas dalam memisahkan fitur ke dalam proses yang berbeda. Protokol komunikasi menjadi lebih kompleks. Alih-alih panggilan metode, Anda harus menggunakan komunikasi asinkron antar layanan. Saat Anda pindah ke arsitektur layanan mikro, Anda perlu menambahkan banyak blok bangunan yang diterapkan dalam versi layanan mikro aplikasi eShopOnContainers: penanganan bus peristiwa, ketahanan dan percobaan ulang pesan, konsistensi akhir, dan banyak lagi.

Aplikasi referensi eShopOnWeb yang jauh lebih sederhana mendukung penggunaan kontainer monolitik kontainer tunggal. Aplikasi ini mencakup satu aplikasi web yang mencakup tampilan MVC tradisional, API web, dan Halaman Razor. Secara opsional, Anda dapat menjalankan komponen admin berbasis Blazor aplikasi, yang memerlukan proyek API terpisah untuk dijalankan juga.

Aplikasi dapat diluncurkan dari akar solusi menggunakan docker-compose build perintah dan docker-compose up . Perintah ini mengonfigurasi kontainer untuk instans web, menggunakan yang Dockerfile ditemukan di root proyek web, dan menjalankan kontainer pada port tertentu. Anda dapat mengunduh sumber untuk aplikasi ini dari GitHub dan menjalankannya secara lokal. Bahkan aplikasi monolitik ini mendapat manfaat dari disebarkan di lingkungan kontainer.

Untuk satu, penyebaran kontainer berarti bahwa setiap instans aplikasi berjalan di lingkungan yang sama. Pendekatan ini mencakup lingkungan pengembang tempat pengujian dan pengembangan awal berlangsung. Tim pengembangan dapat menjalankan aplikasi di lingkungan kontainer yang cocok dengan lingkungan produksi.

Selain itu, aplikasi kontainer meluaskan skala dengan biaya yang lebih rendah. Menggunakan lingkungan kontainer memungkinkan berbagi sumber daya yang lebih besar daripada lingkungan VM tradisional.

Terakhir, kontainerisasi aplikasi memaksa pemisahan antara logika bisnis dan server penyimpanan. Saat aplikasi diskalakan, semua kontainer tersebut akan mengandalkan satu media penyimpanan fisik. Media penyimpanan ini biasanya akan menjadi server dengan ketersediaan tinggi yang menjalankan database SQL Server.

Dukungan Docker

Proyek eShopOnWeb berjalan pada .NET. Oleh karena itu, ini dapat berjalan dalam kontainer berbasis Linux atau berbasis Windows. Perhatikan bahwa untuk penyebaran Docker, Anda ingin menggunakan jenis host yang sama untuk SQL Server. Kontainer berbasis Linux memungkinkan jejak yang lebih kecil dan lebih disukai.

Anda dapat menggunakan Visual Studio 2017 atau yang lebih baru untuk menambahkan dukungan Docker ke aplikasi yang ada dengan mengklik kanan proyek di Penjelajah Solusi dan memilih Tambahkan>Dukungan Docker. Langkah ini menambahkan file yang diperlukan dan memodifikasi proyek untuk menggunakannya. Sampel saat ini eShopOnWeb sudah memiliki file tersebut.

File level solusi docker-compose.yml berisi informasi tentang citra apa yang akan dibangun dan kontainer apa yang akan diluncurkan. File ini memungkinkan Anda menggunakan docker-compose perintah untuk meluncurkan beberapa aplikasi secara bersamaan. Dalam hal ini, hanya meluncurkan proyek web. Anda juga dapat menggunakannya untuk mengonfigurasi dependensi, seperti kontainer database terpisah.

version: '3'

services:
  eshopwebmvc:
    image: eshopwebmvc
    build:
      context: .
      dockerfile: src/Web/Dockerfile
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "5106:5106"

networks:
  default:
    external:
      name: nat

File docker-compose.yml mengacu pada Dockerfile dalam proyek Web. Dockerfile digunakan untuk menentukan kontainer dasar mana yang akan digunakan dan bagaimana aplikasi akan dikonfigurasi di dalamnya. Web' Dockerfile:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app

COPY *.sln .
COPY . .
WORKDIR /app/src/Web
RUN dotnet restore

RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/src/Web/out ./

ENTRYPOINT ["dotnet", "Web.dll"]

Pemecahan masalah Docker

Setelah Anda menjalankan aplikasi kontainer, aplikasi tersebut terus berjalan sampai Anda menghentikannya. Anda dapat melihat kontainer mana yang berjalan dengan docker ps perintah . Anda dapat menghentikan kontainer yang sedang berjalan dengan menggunakan docker stop perintah dan menentukan ID kontainer.

Perhatikan bahwa menjalankan kontainer Docker mungkin terikat ke port yang mungkin Anda coba gunakan di lingkungan pengembangan Anda. Jika Anda mencoba menjalankan atau men-debug aplikasi menggunakan port yang sama dengan kontainer Docker yang sedang berjalan, Anda akan mendapatkan kesalahan yang menyatakan bahwa server tidak dapat mengikat port tersebut. Sekali lagi, menghentikan kontainer harus menyelesaikan masalah.

Jika Anda ingin menambahkan dukungan Docker ke aplikasi Anda menggunakan Visual Studio, pastikan Docker Desktop berjalan saat Anda melakukannya. Wizard tidak akan berjalan dengan benar jika Docker Desktop tidak aktif saat Anda memulai wizard. Selain itu, wizard memeriksa pilihan kontainer Anda saat ini untuk menambahkan dukungan Docker yang benar. Jika Anda ingin menambahkan dukungan untuk Kontainer Windows, Anda perlu menjalankan wizard saat Docker Desktop berjalan dengan Kontainer Windows yang sudah dikonfigurasi. Jika Anda ingin menambahkan, dukungan untuk kontainer Linux, jalankan wizard saat Anda memiliki Docker yang berjalan dengan kontainer Linux yang dikonfigurasi.

Gaya arsitektur aplikasi web lainnya

  • Web-Queue-Worker: Komponen inti arsitektur ini adalah antarmuka web yang melayani permintaan klien, dan worker yang melakukan tugas intensif sumber daya, alur kerja yang berjalan lama, atau pekerjaan batch. Bagian depan web berkomunikasi dengan pekerja melalui antrean pesan.
  • N-tingkat: Arsitektur N-tingkat membagi aplikasi menjadi lapisan logis dan tingkat fisik.
  • Layanan mikro: Arsitektur layanan mikro terdiri dari kumpulan layanan kecil dan otonom. Setiap layanan mandiri dan harus menerapkan kemampuan bisnis tunggal dalam konteks terbatas.

Referensi – Arsitektur web umum