Perbarui situs web .NET tanpa memuat ulang

13

Saya dulu mengembangkan situs web di PHPdan ASP classicdan jika sesuatu perlu diubah. Anda hanya dapat mengubah satu / beberapa file dan tidak ada yang akan memperhatikan. Mungkin jika seseorang akan meminta file yang diubah saat mengunggah, tapi itu seperti setengah detik. Untuk sebagian besar situs kecil itu tidak masalah.

Tetapi situs terbaru dibuat dengan C# MVCdan ketika Anda membuat perubahan pada kode, Anda perlu membangun kembali situs web Anda dan mengunggah DLLfile yang diubah . Tetapi ketika Anda mengubah DLLfile Anda itu akan me-restart situs web Anda dan mengatur ulang semua yang aktif sessions. Ini juga harus memuat ulang semuanya dan dengan situs besar dapat memakan waktu beberapa menit untuk memuat semuanya. Semua orang yang menjelajahi situs akan melihat dan perlu masuk lagi.

Pembaruan situs utama tidak umum, jadi itu tidak masalah. Tetapi kami memiliki pembaruan "kecil" secara teratur untuk promosi. Seperti 'Isi formulir ini dan dapatkan tiga bulan keanggotaan gratis' atau '10 yang pertama mengunggah gambar ... akan menerima harga'. Saya pikir Anda akan mengerti maksudnya. Beberapa promosi serupa dan dapat ditangani dengan modul yang menampilkan info yang tepat berdasarkan pengaturan, tetapi seringkali memerlukan kode khusus.

Saya sedang memikirkan suatu sistem di mana setiap promosi adalah DLLfile itu sendiri berdasarkan pada suatu antarmuka, dan kemudian memuat DLLsecara dinamis menggunakan Type.GetType, Activator.CreateInstancedan InvokeMember. Meskipun itu bisa berhasil, saya bertanya-tanya apakah itu cara yang tepat untuk pergi.

Jadi pertanyaan saya: Bagaimana Anda memperbarui .NETsitus dengan cepat, tanpa memuat ulang seluruh situs dan menjatuhkan sesi (seperti kelompok aplikasi daur ulang).

Hugo Delsing
sumber
Menanggapi komentar karunia Anda: situs web besar yang saya kerjakan menangani perubahan kecil pada kode dengan cara yang sama mereka menangani perubahan besar pada kode: melalui load-balancers dan di luar sesi proses - karena semua kode yang digunakan untuk menjalankan perlu melalui proses peninjauan / keluar dan kami tidak bisa hanya menjatuhkan kode di server. Saya kira definisi kami tentang "besar" mungkin tidak cocok;)
Zhaph - Ben Duguid

Jawaban:

11

Lihat "Inisialisasi Aplikasi" IIS 7.5, Windows 2008 R2 (lebih sulit untuk diatur) IIS 8, Windows 2012

App Inisialisasi memungkinkan aplikasi apa pun (kumpulan aplikasi bukan situs) restart untuk tumpang tindih dan menggunakan yang lama, masih menjalankan aplikasi sebelumnya saat pemanasan aplikasi baru dimulai. Setelah aplikasi baru diputar (ditentukan oleh URL yang dapat Anda atur), aplikasi itu akan mulai menggunakan aplikasi baru dan mematikan yang sebelumnya. Menggunakan Inisialisasi Aplikasi bersama dengan metode untuk memastikan sesi tetap di seluruh kumpulan aplikasi restart dapat memungkinkan situs Anda untuk reboot tanpa hambatan. (Zhaph memiliki catatan bagus tentang kunci mesin.)

Selain tautan di atas untuk konfigurasi Inisialisasi Aplikasi, Anda akan ingin melihat apa yang memicu restart situs - karena restart situs tidak menggunakan Initiliaisasi Aplikasi , restart situs tidak akan mulus.

Anda dapat mengonfigurasi IIS sehingga pembaruan DLL tidak segera memicu restart situs, atau perubahan ke web.config (nilai ChangeNotification tinggi pada file httpRuntime dan konfigurasi eksternal, yang relevan dengan situs Anda).

Hasil akhirnya adalah Anda dapat memperbarui DLL / kode tanpa memulai ulang situs, lalu memaksakan aplikasi restart yang akan menggunakan latar belakang AppInitialization pemanasan untuk perubahan kode mulus.

Melakukan hal-hal ini dalam konser bekerja sangat baik untuk memulai kembali tanpa cacat.

jeffreypriebe
sumber
Seperangkat langkah yang baik di sana - tentu saja sesuatu untuk dipertimbangkan :)
Zhaph - Ben Duguid
Ini terdengar seperti apa yang saya cari. Akan mencobanya dan mengaturnya. Terima kasih
Hugo Delsing
@HugoDelsing Berharap ini berfungsi baik untuk Anda.
jeffreypriebe
Terima kasih, inilah yang akhirnya saya gunakan dan ini berfungsi dengan baik.
Hugo Delsing
@HugoDelsing Senang mendengarnya juga bekerja untuk Anda.
jeffreypriebe
5

Ada beberapa cara untuk menangani apa yang Anda minta, dan beberapa aspek berbeda untuk pertanyaan Anda:

Tangani pembaruan kecil untuk promosi

Apa yang Anda benar-benar setelah di sini adalah sistem manajemen konten atau serupa yang memungkinkan Anda untuk mengedit konten dengan cepat (pikirkan Wordpress / Drupal atau dari sudut pandang .NET N2 CMS, Umbraco, Orchard, dll.), Namun ada ada beberapa hal yang bisa Anda coba jika Anda belum menempuh rute itu.

Karena ASP.NET hanya benar-benar memuat ulang jika Anda menyentuh jenis file tertentu (web.config (s), isi folder /bin/dan /app_code/sebagian besar) - dan memiliki batas yang dapat dikonfigurasi untuk "perubahan file lain" (pada dasarnya begitu Anda telah memodifikasi begitu banyak file di dalam situs Anda kumpulan aplikasi akan restart - NumRecompilesBeforeAppRestart) Anda bisa melihat melakukan sesuatu di mana Anda memeriksa folder yang berbeda untuk beberapa .htmlfile statis (yaitu ) yang Anda tarik dan tampilkan sesuai kebutuhan, atau memanfaatkan LoadControlmetode yang mengambil jalur string untuk sebuah .ascxkontrol pengguna dan dinamis beban itu - bagaimana Anda menentukan untuk acara adalah pertanyaan yang berbeda lebih cocok untuk StackOverflow - namun saya akan merekomendasikan solusi berdasarkan konvensi penamaan.

Anda juga dapat melihat menggunakan sesuatu seperti Managed Extensibility Framework (MEF - yang telah menjadi bagian penuh dari .NET framework sejak versi 4) yang memungkinkan Anda untuk menulis arsitektur berbasis plugin dan menentukan folder di luar /bin/direktori Anda untuk memonitor .DLL baru - walaupun saya belum mencoba ini untuk melihat apakah itu akan menghindari masalah restart aplikasi, saya telah menggunakan ini untuk efek yang baik di lingkungan web untuk menambahkan fungsionalitas umum ke situs.

Jika itu tidak menarik, satu-satunya pilihan lain yang dapat saya pikirkan adalah menambahkan kontrol sebagai "code-in-front" seperti yang kami lakukan pada ASP klasik - yaitu dengan <script runat="server">blok alih-alih kelas "kode-belakang" yang dikompilasi. yang berisi logika untuk menjalankan kontrol - ini akan menghapus kebutuhan untuk perubahan DLL, dengan mengorbankan beberapa kehilangan kinerja pertama kali saat kontrol dikompilasi dengan cepat - lagi Anda harus menyeimbangkan ini dengan NumRecompilesBeforeAppRestartjika Anda Sedang melakukan banyak perubahan kecil.

Bagaimana cara bertahan sesi di restart aplikasi?

Ini mungkin masalah yang lebih mudah untuk dipecahkan dan melibatkan tiga langkah utama:

  1. Konfigurasikan MachineKey (IIS7, tetapi masih berlaku untuk 8) menjadi nilai yang konstan daripada AutoGenerate- ini berarti bahwa ketika AppPool melakukan daur ulang, ia akan menggunakan kunci yang sama, dan dengan demikian akan dapat mendekripsi cookie sesi, kondisi tampilan, dll. Dari sebelumnya daur ulang.
  2. Baik mengatur Server Negara atau mengkonfigurasi Database untuk menahan Sesi Negara .
  3. Beralih dari menggunakan InProcke StateServeratau SQLServerdalam elemen SessionState di web.config Anda.

Dengan cara ini Anda akan memiliki sesi persisten yang selamat dari restart aplikasi. Namun, ini bukan "gratis" - semua yang Anda simpan di sesi sekarang harus serializable, dan Anda akan mendapatkan sedikit performa karena setiap beban halaman sekarang akan memerlukan perjalanan jaringan tambahan untuk mendapatkan, dan berpotensi merilis data sesi.

Namun, jika Anda berada dalam posisi di mana dibutuhkan "beberapa menit" untuk aplikasi untuk memulai kembali setelah penyebaran, Anda mungkin ingin mempertimbangkan untuk pindah ke lingkungan yang seimbang beban, atau setidaknya pengaturan Staging / Live hot-swappable (seperti yang disediakan oleh Azure / AWS / dll.) - dengan cara ini Anda dapat membuat server offline saat Anda memperbaruinya atau membuatnya siap dengan kode baru dan kemudian menukar itu - asalkan Anda telah mengambil langkah-langkah untuk mengatasi alamat bersama sesi (lihat di atas) ini akan berfungsi dengan baik tanpa dampak kepada pengguna Anda.

Zhaph - Ben Duguid
sumber
Terima kasih atas jawaban panjangnya. Sayangnya CMSbukan itu yang saya inginkan. Saya tidak ingin mengubah konten, saya ingin mengubah kode. Bagian tentang sesi hanyalah sebuah contoh. Mengubahnya tidak akan memecahkan masalah situs menjadi turun selama satu atau dua menit ketika memuat ulang DLLfile. Bagian MEFitu menarik, tetapi merupakan solusi pihak ketiga untuk sistem yang saya pikirkan. Jadi +1 untuk upaya ini, tapi sayangnya itu bukan jawaban untuk pertanyaan saya.
Hugo Delsing
1
Saya telah memperbarui jawaban saya untuk mengatasi beberapa poin tersebut: MEF dirilis oleh MS dan telah menjadi bagian penuh dari kerangka .NET sejak v4. Anda dapat mencoba menggunakan kode-di-depan untuk kontrol baru Anda, sebagai alternatif mengadopsi pengaturan beban-seimbang / pementasan-hidup yang memungkinkan untuk membuat server berjalan dan kemudian menukar itu.
Zhaph - Ben Duguid
1
Saya telah menguraikan solusi alternatif menggunakan Inisialisasi Aplikasi. Keuntungannya adalah semua kode dan pengaturan server "normal" tanpa penyeimbangan beban khusus atau kontrol pemuatan dinamis, menjaga lingkungan berjalan Anda lebih sederhana. Tentu saja, pengaturan beban-penyeimbangan / pementasan-hidup mungkin berguna karena alasan lain.
jeffreypriebe