Bahaya aplikasi monolitik besar

20

Proyek besar yang saya kerjakan selama beberapa tahun sekarang adalah aplikasi kontrol (dan semuanya) dari perangkat canggih, inti dari firmware-nya.

Perangkat ini cukup canggih, dengan fungsi yang lebih berbeda dari yang dapat saya katakan dari memori, dan 98% di antaranya ditangani oleh perangkat yang sangat besar ini. Di satu sisi, program ini cukup dapat dipertahankan, termodulasi dengan baik di dalam, didokumentasikan dengan baik, ada pemisahan fungsi yang wajar oleh direktori dan file dan sebagainya.

Tetapi pada akhirnya semua itu dikelompokkan menjadi satu aplikasi yang melakukan segalanya mulai dari komunikasi basis data jarak jauh, penanganan layar sentuh, menangani selusin berbagai protokol komunikasi, pengukuran, beberapa algoritma kontrol, pengambilan video, waktu matahari terbit dan tanggal paskah (serius, dan mereka adalah diperlukan untuk tujuan yang sangat serius!) ... Secara umum, hal-hal yang terkait sangat tipis, seringkali hanya terkait melalui beberapa data yang menetes di antara beberapa modul jauh.

Ini dapat dilakukan sebagai beberapa executable terpisah yang berkomunikasi satu sama lain, katakanlah, melalui soket, dengan tujuan yang lebih spesifik, mungkin dimuat / dibongkar sesuai kebutuhan, dan sebagainya. Tidak ada alasan khusus mengapa dibuat seperti ini.

Di satu sisi, ini berfungsi, dan bekerja dengan baik. Proyek ini lebih sederhana, tanpa mempertahankan pembangunan banyak binari. Struktur internal lebih mudah juga, ketika Anda bisa memanggil metode atau membaca variabel daripada berbicara melalui soket atau memori bersama.

Tapi di sisi lain, ukuran, skala benda ini hanya membuatku takut, rasanya seperti mengemudikan Titanic. Saya selalu diajarkan untuk memodulasi, dan mengelompokkan semuanya menjadi satu file raksasa terasa salah. Satu masalah yang saya tahu adalah crash besar pada satu (bahkan tidak signifikan) modul crash semua - tetapi kualitas kode memastikan ini tidak benar-benar terjadi dalam versi rilis. Kalau tidak, pemisahan internal dan pemrograman defensif memastikan ini akan tetap berjalan sebagian besar dengan benar bahkan jika setengah dari modul internal gagal secara normal karena suatu alasan.

Bahaya apa lagi yang saya abaikan? Mengapa ini membuat saya takut? Apakah ini hanya ketakutan irasional yang tidak diketahui? Apakah membuat proyek besar yang serius dengan cara ini merupakan praktik yang diterima? Baik menenangkan ketakutan saya atau memberi saya alasan yang bagus untuk mengubah versi 2.0 menjadi beberapa biner yang lebih kecil.

SF.
sumber
7
Jika matahari terbit terlalu dini, Inggris akan hanyut ke laut.
Maks.
1
Atau tekanan di inti bumi sedikit meningkat.
StuperUser
1
@Maxpm Saya melihat apa yang Anda lakukan di sana ... xkcd.com/687
teto
3
@ Maxm: Untungnya, aplikasi kita tidak menggerakkan matahari terbit dan terbenam. Kami percaya Putri Celestia tidak akan gagal dalam pekerjaannya.
SF.
1
@ rwong: 1. Perangkat dihentikan untuk peningkatan. Sementara itu akan bertahan pembaruan dengan cepat, kami tidak ingin ada hasil yang tidak terduga jika pembaruan terjadi salah karena alasan apa pun. 2. Single-core ARM9 dengan embedded Linux. Ada yang kedua, mengawasi CPU yang berjalan tanpa OS, memverifikasi CPU utama menghasilkan output yang waras.
SF.

Jawaban:

5

Kecuali untuk komentar kecil di akhir (kedua, mengawasi CPU) Anda bisa menggambarkan perusahaan saya. Yup, kita juga perlu Paskah.

Yah, kita sedikit lebih jauh. Kami memang membagi executable besar dan mencoba menggunakan komponen standar untuk bit standar. Bukan peningkatan besar yang Anda harapkan. Bahkan, kinerja menjadi masalah besar bahkan pada perangkat keras yang lebih canggih. Dan biaya perawatan belum benar-benar turun sekarang karena ada banyak kode untuk membuat serial dan menyinkronkan data melalui antarmuka yang sempit.

Pelajaran yang saya pelajari? Memiliki satu executable adalah solusi yang sudah terbukti untuk sistem kecil, dan kami memiliki pengalaman puluhan tahun dalam mengelolanya. Semua alat kami mendukungnya secara asli. Modularitas dapat dilakukan dalam satu executable tunggal, dan ketika Anda perlu berkompromi pada modularitas untuk alasan lain peretasan tetap kecil.

MSalters
sumber
Terima kasih - tidak ada entri "praktik terbaik yang harus diikuti / dikorbankan" dan "menimbang manfaat potensial vs. potensi kerugian" yang sama bermanfaatnya dengan seseorang dengan pengalaman langsung dari sisi lain pagar.
SF.
23

Perangkat ini cukup canggih, dengan fungsi yang lebih berbeda dari yang dapat saya katakan dari memori, dan 98% di antaranya ditangani oleh perangkat yang sangat besar ini. Di satu sisi, program ini cukup dapat dipertahankan, termodulasi dengan baik di dalam, didokumentasikan dengan baik, ada pemisahan fungsi yang wajar oleh direktori dan file dan sebagainya.

Anda mengatakannya sendiri - itu cukup dapat dipertahankan, termodulasi dengan baik ...

Menurut pendapat saya, dan sebagian besar manajemen akan setuju dengan saya tentang hal ini, perubahan tidak boleh dilakukan demi perubahan. Tidak ada yang salah dengan program ini (deskripsi Anda) selain itu tidak mengikuti tren pemrograman terbaru (yang disebutkan dalam jawaban lain).

Ya, ini adalah program yang lebih besar ... sebelumnya banyak juga. Ini didokumentasikan dengan baik juga, jadi yang harus Anda lakukan adalah mempelajari organisasi internalnya dan Anda akan melihat logikanya di dalamnya. Saya ragu bahwa semua sebelum Anda yang menulisnya tidak kompeten. Jadi, jelajahi sedikit, pelajari ... setelah itu, pertahankan sebagaimana adanya hingga alasan yang kuat untuk menulis ulang muncul. Manajer Anda akan berterima kasih kepada Anda karena memiliki rasio biaya / efek yang baik.

Bahaya apa lagi yang saya abaikan? Mengapa ini membuat saya takut? Apakah ini hanya ketakutan irasional yang tidak diketahui? Apakah membuat proyek-proyek besar yang serius dengan cara ini merupakan praktik yang diterima? Baik menenangkan ketakutan saya atau memberi saya alasan yang bagus untuk mengubah versi 2.0 menjadi beberapa biner yang lebih kecil.

Itu membuat Anda takut karena besar - tetapi sekali lagi, tidak ada yang mengharapkan Anda untuk mempelajarinya dengan sepenuh hati dalam seminggu. Jadi kerjakan, sepotong demi sepotong, sedikit demi sedikit, sampai Anda terbiasa. Pada akhirnya, Anda akan belajar bahwa itu mungkin terorganisasi dengan baik seperti apa adanya, dan bagaimana hal itu diatur.

Jika Anda menulis ulang, Anda akan melakukan hal yang sama, tetapi pada saat yang sama merusaknya untuk semua orang yang terbiasa dengan organisasi kode sebelumnya. Dengan cara ini, hanya Anda yang harus "beradaptasi".

Benteng
sumber
16

Saya akan merasa lebih baik jika Anda mengatakan Anda memiliki segalanya yang terbungkus dalam unit test. Jika tidak, Anda harus membuat test suite bahkan sebelum berpikir untuk merancang ulang aplikasi.

Memiliki test suite akan meningkatkan pemahaman Anda tentang aplikasi, dan akan memberi tahu Anda ketika perubahan dalam aplikasi merusak sesuatu.

Robert Harvey
sumber
2
Tapi itu berlaku untuk kedua kemungkinan arsitektur ...
SF.
3
Ya, benar ...
Robert Harvey
10
... dan karena itu jawaban ini tidak menambah apa pun pada diskusi kecuali untuk mempromosikan pengujian unit.
benzado
2
@ Albenzado: Yang, dalam skenario OP, cukup penting.
Robert Harvey
2
@ironcode: Lihatlah buku seperti "Bekerja Efektif dengan Kode Warisan." Hal pertama yang dia katakan dalam buku itu adalah "Jika Anda belum memiliki serangkaian unit test dengan cakupan kode yang tinggi, tulislah terlebih dahulu, sebelum Anda melakukan hal lain. " Saya akan mengatakan bahwa saran lebih dari relevan di sini, mengingat bahwa OP secara khusus bertanya, "Bahaya apa lagi yang saya abaikan."
Robert Harvey
8

Jika kode dimodulasi dengan baik dengan kopling rendah dan kohesi tinggi, maka dipartisi secara efektif. Overhead komunikasi harus lebih rendah dalam satu proses daripada kasus dengan beberapa proses.

Untuk sistem tertanam, satu proses Anda mungkin menghilangkan kebutuhan untuk menerapkan O / S untuk menjalankan semua proses yang Anda akan buat. Anda juga perlu menerapkan sistem untuk memeriksa bahwa semua proses berjalan, dan restart jika memungkinkan. Jika tidak memungkinkan, Anda harus bereaksi sesuai dengan itu.

Memisahkan kode menjadi executable yang terpisah juga akan meningkatkan ukuran keseluruhan kode sumber karena Anda perlu menerapkan semua kode klien / server di antara modul-modul. Anda juga perlu lebih banyak kasus uji untuk menangani kode ini, dan kasus ketika proses server tidak ada. Proyek-proyek besar adalah besar, menghilangkan kompleksitas yang tidak perlu seperti yang tampaknya telah dilakukan di sini membantu menjaga mereka sekecil mungkin.

Pengujian adalah semacam herring merah di sini, karena masalahnya akan tetap ada dengan atau tanpa pengujian. Pengujian yang baik dengan salah satu pilihan desain tentu harus didorong. Saya berharap, pengujian lebih sederhana dengan kode monolitik.

Memaksa crash saat diperlukan juga lebih mudah dengan executable monolitik.

BillThor
sumber
1
+1, rekayasa adalah tentang pengorbanan, binari kecil memiliki biaya juga
benzado
+1 Saya setuju dengan sepenuh hati. Tidak ada alasan khusus yang diberikan untuk menjamin beberapa executable. Komunikasi dan koordinasi antara yang dapat dieksekusi memiliki harga.
Erick Robertson
+1: Jika tidak rusak, jangan memperbaikinya.
Bob Murphy
1

Jika saya mengerjakan aplikasi monolitik yang begitu besar, hal-hal yang akan membuat saya takut adalah kurangnya enkapsulasi, kohesi rendah, kopling tinggi dan bagaimana menguji semua ini. Monolit besar sering kali merupakan undangan untuk meninggalkan arsitektur yang tepat dan mulai turun menjadi bola lumpur yang besar .

Setelah itu terjadi, pengujian menjadi mimpi buruk dan Anda berada di jalan menuju usang.

Namun, jika kode Anda terstruktur dengan baik, dan dipelihara dengan baik, dan prinsip kohesi tinggi, kopling rendah dan enkapsulasi yang tepat dipatuhi, maka saya melihat sedikit alasan untuk memperbaiki ini menjadi unit yang lebih kecil.

Anda memang ingin memiliki tes yang bagus.

wolfgangsz
sumber
1

Idealnya, jawabannya adalah ya. Memiliki banyak binari berpotensi membuatnya lebih stabil ....

... Namun, Anda juga menyebutkan bahwa kode di dalam basis kode monolitik ditulis dengan baik dan termodulasi, yang berarti Anda tidak berurusan dengan kekacauan besar, hanya basis kode besar ...

Secara keseluruhan, saya akan mengatakan bahwa perkataan yang berlaku adalah, "Jangan biarkan yang sempurna menjadi musuh orang baik." Sementara saya merasa bahwa Anda benar dalam mengatakan bahwa basis kode monolitik buruk, saya juga merasa bahwa tidak ada gunanya untuk mengkhawatirkannya.

Adalah masuk akal untuk bergerak maju dengan meletakkan potongan kode baru dalam binari mereka sendiri, tetapi kembali dan refactoring mungkin tidak bernilai saat Anda.

riwalk
sumber
1

Jika Anda menggunakan proses tunggal, ada kemungkinan pointer liar dari salah satu sub modul Anda akan merusak sepotong memori kritis (dan menghancurkan semuanya).

Jika Anda menggunakan proses yang berbeda, Anda setidaknya tidak menggunakan tumpukan atau tumpukan panggilan yang sama, dan mungkin juga lebih mudah untuk memulai kembali satu proses.

Struktur internal lebih mudah juga, ketika Anda bisa memanggil metode atau membaca variabel daripada berbicara melalui soket atau memori bersama.

Mengolah kembali segala sesuatu dalam berbagai proses juga akan memaksa Anda untuk membersihkan desain dan menghindari agar setiap modul mulai menggunakan metode internal modul lain.

Yang sedang mengatakan itu mungkin tugas yang menakutkan.

Apa yang dapat Anda mulai lakukan, adalah memutuskan bahwa setiap modul baru harus merupakan proses yang terisolasi.

Xavier T.
sumber
Anda mengasumsikan banyak sekali tentang perangkat keras runtime dan lingkungan OS, terutama ketika firware dan perangkat tertanam terlibat.
Patrick Hughes
0

Ketika saya masuk ke ranah di mana proyek ini terlalu besar untuk grok sekaligus, saya membangun bagan untuk digantung di dinding yang menjabarkan semua bagian besar dan bagaimana mereka cocok bersama. Lalu ketika saya sedang bekerja saya dapat referensi modul yang saya fokuskan dan memiliki pengingat visual tentang bagaimana hal itu cocok dengan keseluruhan.

Sangat mungkin bahwa kompleksitas dan bahaya mempertahankan sistem build dan versi untuk beberapa binari yang terputus akan jauh lebih besar daripada kegelisahan Anda dengan proyek yang begitu besar dan monolitik.

Patrick Hughes
sumber