Aspnetcore: IIS -> Kunci file DLL aplikasi .NET Core

Dibuat pada 7 Jul 2016  ·  114Komentar  ·  Sumber: dotnet/aspnetcore

Ketika saya mencoba untuk menimpa file .NET Core aplikasi DLL menggunakan FTP pada produksi file server IIS terkunci dan tidak dapat ditimpa.

Untuk menerapkan versi baru, saya harus menghentikan aplikasi di IIS untuk melepaskan kunci, lalu menimpa.
Tidak mungkin untuk menerapkan tanpa menghentikan aplikasi.

affected-medium area-servers bug servers-iis severity-nice-to-have

Komentar yang paling membantu

👍

Tidak mendukung daur ulang yang tumpang tindih adalah regresi.

Semua 114 komentar

Lihat app_offline.htm: https://docs.asp.net/en/latest/hosting/aspnet-core-module.html#asp -net-core-module-app-offline-htm

Jika Anda akhirnya menginginkan cara PowerShell untuk melakukannya, Anda dapat menggunakan cmdlet Admin IIS: https://technet.microsoft.com/en-us/library/ee790599.aspx

Stop-WebAppPool -Name $appPoolName

... deploy ...

Start-WebAppPool -Name $appPoolName

Terima kasih atas penjelasan @Tratcher .
Saya tidak yakin apakah ini ada di rencana Anda tetapi ini berfungsi untuk ASP.NET MVC sebelumnya, saya kira?
Apakah Anda berencana untuk menerapkan fitur ini atau tidak?

@GuardRex Saya tidak dapat melakukannya karena ini adalah lingkungan shared hosting dan tidak memiliki izin untuk menghentikan AppPool

Bisakah Anda membuatnya 'berfungsi' dengan msdeploy.exe dan Azure? Jika saya mengerti dengan benar, situs web perlu direstart untuk mencegah penguncian file. -enableRule:AppOffline berfungsi tetapi seluruh situs web offline selama beberapa menit yang bukan merupakan pengalaman pengguna yang luar biasa terutama karena kami menerapkan beberapa kali per hari.

Lihat juga http://stackoverflow.com/q/40276582/14131

@chuchuva mungkin, tetapi semua keajaiban ada harganya. Versi ASP.NET sebelumnya melakukan penyalinan bayangan yang rumit untuk mengatasi masalah penguncian file.

Ajaib atau tidak, Ini bekerja dengan baik. Saya agak ketinggalan sekarang setelah migrasi ke inti ASP.NET ...

Setuju dengan @HarelM. Kami mengalami masalah dengan ini dari penerapan otomatis kami hingga pengalaman pengguna akhir saja. Kami telah beralih dari penerapan sekitar 10 kali sehari dengan MVC lama menjadi mungkin penerapan harian di malam hari dan menerima bahwa orang-orang yang menggunakan aplikasi Inti akan merasa terganggu ketika kami membuatnya offline. Meskipun bukan penghenti pertunjukan, itu menambahkan gesekan terhadap adopsi Inti.

👍

Tidak mendukung daur ulang yang tumpang tindih adalah regresi.

Apakah ada rencana untuk mengunjungi kembali fitur ini dan meletakkannya di peta jalan? Sangat merepotkan / tidak bersahabat untuk mengharuskan semua orang menggunakan situs web .Net Core untuk secara manual menerapkan strategi staging-slot jika mereka ingin mendukung penerapan zero downtime.

Memiliki fitur ini akan membuat transisi ke situs web .Net Core jauh lebih lancar bagi banyak orang, dan akan memungkinkan adopsi situs web .Net Core yang lebih cepat.

Kami ingin tahu juga. Menempatkan app_offline.htm di dalam direktori aplikasi tidak berfungsi.

Saya baru menyadari 'fitur' ini setelah memindahkan sejumlah situs ke AspNetCore. Saya tidak percaya bahwa menjadikan situs Anda offline selama beberapa menit dianggap dapat diterima setiap kali Anda ingin menerbitkannya!

Ini cukup buruk bagi saya sebagai pemimpin tim kecil - apakah mereka yang mempraktikkan integrasi berkelanjutan dalam skala besar menghindari AspNetCore? Tidak mungkin mereka dapat membuat situs mereka offline selama beberapa menit setiap jam untuk dipublikasikan ulang!

Apakah Anda menyebarkan menggunakan FTP atau xcopying? Atau apakah Anda menggunakan penerapan web?

Saya menerbitkan melalui webdeploy ke IIS.

Kami sedang mengatasi masalah ini dengan hanya menghapus web.config terlebih dahulu (secara efektif mematikan aplikasi), tetapi ini sebenarnya bukan solusi yang dapat diterima dalam jangka panjang.

@DaleMckeown idealnya dengan alur kerja integrasi berkelanjutan, Anda akan memiliki banyak server di belakang penyeimbang beban. Anda kemudian akan menarik satu server, memperbaruinya, mengembalikannya, dan melanjutkan ke server berikutnya. Tentu saja ini tidak selalu memungkinkan (seperti dalam kasus kami), jadi Anda harus hidup dengan waktu istirahat beberapa menit. Dalam kasus kami, aplikasi dicadangkan dalam waktu 30-an, jadi ini sebenarnya bukan masalah.

@Bayu_joo

Saya menerbitkan melalui webdeploy ke IIS.

Ada beberapa opsi yang dapat digunakan untuk membuat penerapan menggunakan webdeploy berfungsi dengan baik (ini mendukung penggantian nama file terkunci dan menjatuhkan aplikasi offline secara otomatis). Apakah itu yang terjadi secara default @shirhatti ?

@jodohgratis

Kami sedang mengatasi masalah ini dengan hanya menghapus web.config terlebih dahulu (secara efektif mematikan aplikasi), tetapi ini sebenarnya bukan solusi yang dapat diterima dalam jangka panjang.

Apakah itu berarti Anda sedang melakukan penerapan xcopy?

Ada beberapa opsi yang dapat digunakan untuk membuat penerapan menggunakan webdeploy berfungsi dengan baik (ini mendukung penggantian nama file terkunci dan menjatuhkan aplikasi offline secara otomatis). Apakah itu yang terjadi secara default @shirhatti ?

Terima kasih David - terdengar lebih baik daripada apa yang saya lakukan saat ini (secara manual menghentikan situs & kumpulan aplikasi di IIS). Dapatkah Anda menunjukkan beberapa sumber agar saya dapat menyelidiki implikasi dari pendekatan ini?

@DaleMckeown beberapa info sampai saya menemukan sumber kebenaran https://github.com/Microsoft/vsts-tasks/issues/5259#issuecomment -346202503

@davidfowl Kami menggunakan webdeploy untuk menyebarkan ke server pengujian kami (yang btw tidak pernah memberi kami masalah), dari sana kami menyalin file ke server langsung kami menggunakan robocopy

@jodohgratis

Kami sedang mengatasi masalah ini dengan hanya menghapus web.config terlebih dahulu

Ketika web.config dihapus dari penyebaran, IIS akan melayani file sensitif dari penyebaran. Seorang penyerang bisa saja meminta file terus menerus siang dan malam sampai jendela 30-an Anda terbuka.

@Bayu_joo

Mengikuti saran @ajeckmans jika Anda ingin sedikit masuk ke dalam gulma dengan pendekatan PS untuk melakukan itu, Anda dapat membuat skrip proses untuk melepaskan AppPools satu per satu untuk diterapkan di seluruh web farm. Untuk contoh bagaimana hal itu dapat dilakukan, lihat https://github.com/guardrex/aspnetcore-iis-ps-publish ... tapi lihat saja itu sebagai contoh eksperimental dan bukan skrip kualitas produksi. Saya sudah lama tidak bermain-main dengan itu, tetapi seharusnya (secara teori) masih berfungsi.

@ Guardian kamu benar. Kita salin app_offline.htm ke dir terlebih dahulu, lalu kita remive web.config, salin aplikasi, letakkan kembali web.config dan hapus app_offline (semua dengan skrip ofc). Sayangnya, hanya menempatkan file app_offline di direktori situs web tidak akan merusak kunci pada dll. Kita perlu menghapus web.config, tindakan yang tidak perlu kita lakukan untuk aplikasi lengkap asp.net yang lebih lama (seperti formulir web lama, dll)

@ajeckmans Itu seharusnya tidak berhasil. Ketika file web.config dihapus, IIS mengambil perubahan itu segera, jadi itu harus permintaan default ke Modul File Statis dan mulai melayani file. Cobalah dan lihat apakah itu yang terjadi ...

  1. Tambahkan app_offline.htm .
  2. Konfirmasikan bahwa situs tersebut menyajikan app_offline.htm .
  3. Tarik web.config out.
  4. Minta file sensitif (mis., http://localhost:<PORT>/<ASSEMBLY_NAME>.deps.json ... menggantikan PORT dan ASSEMBLY_NAME).
  5. Anda harus mendapatkan file deps.json yang disajikan jika Modul File Statis Anda berfungsi dengan benar.

Saya tidak akan percaya hanya menghapus modul dengan ...

<configuration> 
 <system.webServer> 
   <modules> 
     <remove name="StaticFileModule" /> 
   </modules> 
 </system.webServer> 
</configuration>

... karena modul lain akan tetap ada dan mungkin menampilkan vektor serangan lainnya. Mungkin seseorang dapat menghapus semua modul yang tidak penting, tetapi kami memasuki perairan yang belum dipetakan dengan langkah seperti itu hanya untuk menutupi penerapan melalui penghapusan web.config . Itu tidak pernah menjadi opsi di bawah panduan resmi, jadi itu sama sekali tidak didukung. Saya merekomendasikan skrip PS, misalnya, untuk menghapus AppPool, atau beberapa strategi lain.

Saya kira saya harus menambahkan catatan simpati untuk itu ... itu memang mengangkat beberapa alis dari perspektif keamanan. Ketika perubahan tata letak penerapan itu dibuat, hal itu dibahas, termasuk mengembalikan file ke wwwroot , lihat ...

Diskusi untuk: Publikasikan untuk perubahan IIS ke lokasi web.config (IISIntegration 158)
Periksa terlebih dahulu untuk memindahkan web.config kembali ke wwwroot (IISIntegration 164)

[EDIT] Mungkin itu solusi Anda (tidak didukung): Pindahkan web.config kembali ke wwwroot , lalu lanjutkan dengan apa yang Anda lakukan. Masih ... agak menakutkan memecahkan aplikasi untuk membuatnya offline seperti itu.

Ini membuat saya semakin bingung tentang apa yang harus kita lakukan dalam situasi ini.

Apa rekomendasi saat ini untuk menerbitkan situs AspNetCore ke IIS melalui penyebaran web dengan cara yang dapat menghindari kunci file?

Saya juga ingin tahu. Ini menjadi penghalang utama untuk adopsi inti .net di organisasi saya.

Ketika aplikasi web inti .net saya berjalan dan saya mencoba menerbitkan versi baru, saya mendapat kesalahan bahwa DLL sedang digunakan. Jadi saya harus Menghentikan pool aplikasi, kemudian memperbarui DLL dan memulai App Pool.

Apakah ada solusi dalam .Net Core yang dapat digunakan untuk menerbitkan Build / DLL baru tanpa menghentikan App Pool?

Ini secara default didukung dalam kerangka .Net menggunakan mekanisme salinan bayangan. Sayangnya, Sudah 2 tahun sejak peluncuran .Net core dan sepertinya masih belum ada dukungan untuk fungsionalitas yang sangat mendasar dan diperlukan. Apakah ada rencana untuk memperbaikinya di masa mendatang?

Terima kasih sebelumnya atas bantuannya.

@guardrex memang menakutkan untuk merusak aplikasi untuk mendapatkan IIS (atau apa pun yang menahan kunci) untuk melepaskan dll, namun lebih menakutkan untuk tidak dapat mendorong perbaikan terbaru ke suatu produk. Untuk saat ini, membobol aplikasi adalah satu-satunya hal yang dapat kami lakukan, tetapi kami sering mencari pendekatan lain yang lebih modern untuk menangani ini :)

@ shahjay748 jangan menahan nafas. Jika saya mengulangi prosesnya di sini, saya akan meletakkan aplikasi di dalam wadah dan hanya memasang wadah baru dan mengalihkan lalu lintas dan menarik versi lama ke bawah (atau sesuatu seperti itu). Sepertinya hal yang lebih waras untuk dilakukan dan dilihat karena .net core adalah tentang cara-cara modern baru, hanya mendorong versi baru aplikasi dengan hanya menyalin file baru dianggap (dan saya setuju) sedikit cara yang misterius untuk melakukannya.
Yang mana yang tidak membantu kita yang, untuk saat ini, terjebak dengan proses lama :)

Apa yang saya lakukan (Tidak yakin apakah itu cara yang tepat untuk melakukannya), adalah mengunggah situs ke direktori lain dan berpindah jalur di iis

Kami melakukan beberapa penyelidikan internal tentang masalah ini. Dari apa yang saya tahu, ANCM tidak menyimpan file / pegangan apa pun dalam aplikasi yang diterapkan. Tampaknya ada masalah dengan penerapan web itu sendiri, dan penerapannya gagal total. Saya tidak pernah secara konsisten gagal menerapkan aplikasi setelah mencoba ulang beberapa kali setelah app_offline dijatuhkan.

Menambahkan catatan singkat PowerShell untuk itu: Kunci pada perakitan aplikasi selalu terbuka ... Saya tidak pernah punya masalah ( belum! Lol).

@ bpetersen1 ... Pendekatan "staging" Anda memiliki efek samping yang baik dalam menawarkan opsi rollback cepat jika penerapan baru gagal. Itu seharusnya mudah dibuat skripnya jika diperlukan.

Ini masih mengganggu secara eksternal ... kami telah memutuskan untuk mencari solusi buruh pelabuhan untuk meninggalkan IIS.

Saya akan bereksperimen dengan solusi. Tetap disini.

Saya juga mengalami masalah ini saat menggunakan FTP.

Apa saran Microsoft tentang ini ?!

Saya juga mengalami masalah ini saat menggunakan FTP.

Apa saran Microsoft tentang ini ?!

Jatuhkan file appoffline.htm, lalu ftp lalu hapus.

@davidfowl Ya, itulah yang saya lakukan sekarang dengan file batch. IIS membutuhkan beberapa detik untuk membuka kunci dan kemudian menyalin file.

Terima kasih - karena tertarik bagaimana Anda menjalankan file batch?

Juga tautan ke dokumentasi MIcrosoft tentang ini dihargai; Saya tidak dapat menemukannya di google. Terima kasih.

@ niico100 Pada dasarnya, file batch hanya menyalin file ke direktori proyek, dan saya membuat folder cadangan terlebih dahulu sebelum melakukan itu. Sebelum menyalin file, letakkan appoffline.htm ke folder proyek.
Menyebabkan masalah penguncian file, penyalinan akan membuat percobaan ulang. Saya menggunakan robcopy
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy

Jika ada yang tertarik, skrip berikut mengunduh file penerapan dari appveyor, menghentikan situs, menyalin file yang diperlukan, dan mengembalikan situs:
https://github.com/IsraelHikingMap/Site/blob/master/Scripts/Deploy.ps1
Ini perlu dijalankan sebagai administrator. semoga buruh pelabuhan akan menyelesaikan semua yang tidak masuk akal ini setelah kita bermigrasi ...
ini menggunakan perintah Stop-WebAppPool dan Start-WebAppPool PowerShell.

Untuk pengembangan lokal, WebDeploy tidak berfungsi untuk saya. Saya mencoba menggunakannya terhadap IIS lokal saya dan masih akan mengeluh tentang file yang terkunci. Saya kemudian mencoba menggunakan commandlet PowerShell di atas dari VS Pre / Post build event, tetapi itu juga tidak berhasil untuk saya, mungkin karena PowerShell 32-bit tidak dapat mengubah pengaturan IIS 64-bit? Bagaimanapun, yang tampaknya berfungsi dengan baik adalah acara pra / pasca pembangunan berikut di proyek Inti ASP.Net saya:

Acara Pra-Bangun:
echo "App Offline" /a > $(ProjectDir)app_offline.htm

Acara Pasca-Bangun:
del $(ProjectDir)app_offline.htm

Saya membaca sebentar keluhan di sini, dan sepertinya ini mungkin terkait. Saya memindahkan penerapan CI untuk kami dari penerapan gurita yang umumnya "baru saja berfungsi", ke menggunakan rilis devops biru dengan tugas manajemen iis, dan masih cukup sering mengalami masalah dalam menerapkan file baru karena bahkan setelah menghentikan aplikasi web, menghentikan domain aplikasi, file masih ada di menggunakan.

Ini mungkin setidaknya 1 dari setiap 3 penerapan dan belum menemukan apa pun yang tampaknya membuat situasi menjadi lebih baik, atau diterapkan lebih dapat diandalkan.

@Tratcher @ronnyek Sepertinya ini terkait dengan Application Insights; setelah menambahkan ekstensi App Insights, DLL aplikasi web saya tiba-tiba sangat sulit untuk diperbarui, tidak ada masalah sebelumnya.

Ini masuk akal mengingat App Insights harus menghubungkan profiler ke proses aplikasi dan DLL.

Saya masih menghadapi masalah ini. Saya menggunakan bendera -e nableRule: AppOffline , kadang-kadang bekerja dengan baik tetapi sebagian besar waktu penerapan gagal mengucapkan "ERROR_FILE_IN_USE".

Setelah memulai rilis, saya memantau folder aplikasi web dan melihat App_Offline.html dijatuhkan oleh msdeploy. Selanjutnya rilis gagal dengan pesan di atas dan perhatikan file App_Offline masih ada di folder, saya mulai rilis lagi, kali ini berfungsi dengan baik karena modul melihat file di folder.

runtime inti asp.net terakhir diinstal -> aspnetcore.dll 12.1.18263.2

Ada ide? Masih bug?

@dhtek Jika Anda mencoba mengganti file segera setelah menempatkan app_offline.htm , maka server tidak punya cukup waktu untuk mematikan aplikasi. Anda harus menunggu sebentar sebelum mencoba mengganti file.

Oke, saya mengerti tapi saya menggunakan opsi -e nableRule: AppOffline dari msdeploy dan halaman secara otomatis menjatuhkannya ke folder dan sinkronisasi langsung selesai. Saya tidak melakukan apa-apa sendiri.

Saya masih melihat masalah ini juga. File proyek saya mereferensikan Microsoft.NET.Sdk.Web , tetapi file app_offline.htm otomatis dihapus, seperti yang seharusnya disebutkan di dokumen.

Hai kawan. Masalah menjengkelkan ini masih ada dengan Core 2.1 dengan VS terbaru 2017. Saya menggunakan appoffline, masih dll proyek utama selalu digunakan dan membutuhkan penghentian total situs web selama publikasi. Ini membuat penerapan web hampir tidak berguna.

Jika Anda tidak dapat membuat host Anda offline di belakang loadbalancer dan ingin melakukannya lebih cepat, berikut adalah salah satu cara dengan symlink dan beberapa PowerShell.
Saya berpikir untuk melakukan sesuatu seperti ini.

Ini lebih cepat karena Anda tidak perlu menghentikan kumpulan aplikasi selama salin + daur ulang lebih baik daripada berhenti keras karena memungkinkan permintaan saat ini selesai, jadi lebih sedikit waktu henti.

# Setup
Import-Module WebAdministration
# create 2 site root directories
$a = 'C:\inetpub\AspNetCoreSampleA'
$b = 'C:\inetpub\AspNetCoreSampleB'
$siteRoot = 'C:\inetpub\aspnetcoresample'
$siteName = 'AspNetCoreSample'
$poolName = "aspnetcore"
New-Item -Type Directory $a
New-Item -Type Directory $b
# create a symlink to targeting one side
New-Item -Type SymbolicLink -Path $siteRoot -Target $a
# point the site root to the symlink
Set-ItemProperty "IIS:\Sites\$siteName" -name physicalPath -value $siteRoot
# make sure it get's picked up
Restart-WebAppPool -Name $poolName

# this tells you the active side
Get-Item -Path $siteRoot | Select-Object -ExpandProperty target

# Flip the symlink
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
# at this point w3wp.exe still locks the current target folder until it's getting recycled
# Deploy new version to the symlink which is now pointing to the other side which should have no locks
robocopy \\myshare\myapp $siteRoot /mir
# recycle app pool, so it picks up the new files
Restart-WebAppPool -Name $poolName

# bonus point: rollback is easy
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
Restart-WebAppPool -Name $poolName

Inilah intinya
https://gist.github.com/csharmath/b2af0f50700ce9fbdd8c5c3e582fd41b

Restart-WebAppPool pada dasarnya adalah daur ulang, yang berguna jika Anda mengaktifkan daur ulang yang tumpang tindih (default) karena akan memunculkan w3wp.exe baru dan semua permintaan baru akan dilayani oleh proses baru itu sementara yang saat ini sedang dijalankan akan diselesaikan oleh w3wp.exe lama.
Dengan cara ini mereka tumpang tindih sampai yang lama selesai dengan permintaan, Anda berakhir dengan satu w3wp.exe yang menunjuk ke versi baru dan tidak ada masalah penguncian.

Ini mirip dengan penyalinan bayangan, tetapi tidak 100% karena itu memberikan skenario xcopy yang jauh lebih baik dan mulus.

Sejauh ini, ini tampaknya menjadi pendekatan terbaik yang dapat saya pikirkan jika Anda perlu tetap online selama rilis.

@csharmath atau ada juga buruh pelabuhan kayaknya. Tidak ada file yang terkunci dengan cara itu, dan dapat melakukan pembaruan bergulir melalui swarm / k8s / okd

Tentu, itu lebih baik tentunya. menghela napas, belum semua tempat memilikinya.
Untuk pengaturan sekolah lama lainnya, Anda perlu menyimpannya sampai berfungsi untuk Anda tanpa atau waktu henti minimal.

@csharmath Setuju, tetapi pada titik ini, mengingat bahwa ini telah menjadi masalah yang belum diperbaiki untuk _years_, mungkin sebaiknya beradaptasi dan mencari solusi yang berhasil daripada menunggu keajaiban ...

Saya telah menggunakan di bawah skrip power shell dan itu merusak IIS dan bahkan mempengaruhi kumpulan aplikasi lain dan saya harus me-restart mesin untuk mendapatkan semuanya kembali ... proses ini saya dapatkan dari dokumen resmi dan itu bencana, jadi saran saya JANGAN GUNAKAN app_offline.htm lebih baik menggunakan skrip yang menghentikan kumpulan aplikasi dan memulainya lagi, yang saya temukan di utas ini https://github.com/IsraelHikingMap/Site/blob/master/Scripts/Deploy .ps1

$pathToApp = 'G:\prod_web_core'
$pathToAppOfflineHtml = 'G:\prod_web_core\app_offline.htm'
# Stop the AppPool 
New-Item -Path $pathToApp -Name app_offline.htm
# Provide script commands here to deploy the app
Copy-Item "G:\prod_web_core_temp\*" -Destination $pathToApp -Recurse -Force
# Restart the AppPool 
Remove-Item -Path $pathToAppOfflineHtml
Get-ChildItem -Path "G:\prod_web_core_temp" -Recurse | Remove-Item -Force

Saya dipaksa untuk menghentikan AppPool agar sukses diterapkan, kemajuan apa pun untuk memperbaiki masalah ini ?!

Kami baru saja mengalami masalah penguncian file ini untuk pertama kalinya hari ini karena inti dotnet adalah hal baru bagi kami. Saya benar-benar terkejut dengan ini. Sangat lucu bahwa alasan nomor 1 saya beralih dari ASP Klasik ke .Net Framework saat masih dalam versi beta (~ 2001) adalah karena saya dapat melakukan penerapan panas tanpa penguncian file. Itu luar biasa! Hampir 18 tahun kemudian dan sekarang saya kembali ke tempat saya memulai. Baiklah, Anda memenangkan beberapa Anda kehilangan beberapa.

Saya baru saja mereferensikan masalah saya ... dalam kasus saya menerapkan solusi Sisi Server Blazor ....
Beberapa hari yang lalu itu adalah mimpi buruk ... Saya menerapkan app_offline.htm, menutup kumpulan aplikasi, dan bahkan memulai ulang seluruh instance IIS untuk membuka kunci file. Langkah selanjutnya adalah me-restart seluruh server, untungnya setelah 5 menit .dlls membuka kunci sendiri.

2019, masalah yang sama untuk saya ... dan masalah ini dibuat pada tahun 2016 ... masih belum ada solusi?

2020, masalah yang sama bagi saya. Regresi terbesar yang pernah ada. .Net 4.6 Anda mengganti file dll dan aplikasi memuat ulang pada versi baru. Inti bersih mengunci segalanya.

@bladefist Taruhan terbaik Anda saat ini adalah menggunakan kontainer Docker: /

@kanadaj terima kasih tetapi Dockers adalah tingkat

Lewatlah sudah hari-hari .net 4.6 di mana Anda baru saja menyalin dll Anda dan aplikasi Anda otomatis didaur ulang. Saya rasa itu terlalu sederhana. Yang membuat frustasi ganda ini bukanlah masalah di linux. Anda dapat mengganti file yang digunakan di linux.

Ya, saya rasa, tetapi metode itu tidak terlalu mudah di lingkungan produksi. Tanpa HA, aplikasi Anda tidak akan merespons selama satu menit, dan dengan HA Anda mendapatkan beberapa permintaan buruk acak sampai penyeimbang beban mengetahui bahwa aplikasi tersebut mati ... Kecuali jika Anda memutar host secara manual di penyeimbang beban. Tapi kedengarannya lebih merepotkan untuk disiapkan.

@kanadaj ya, kami menggunakan penyeimbang beban dan memperbarui server secara linier. Tidak ada waktu henti.

Kami sukses dengan

  • Penggunaan tautan simbolis untuk direktori aplikasi
  • Terapkan versi baru situs ke direktori yang berbeda
  • Perbarui tautan simbolis
  • Mulai ulang kumpulan aplikasi menggunakan utilitas appcmd yang disertakan dengan IIS.

@davidglassborow itu solusi kreatif. Terima kasih. Solusi kreatif seharusnya tidak diperlukan.

Dalam pengalaman saya, mekanisme lama tidak dapat diandalkan ketika situs sedang dimuat, kami akhirnya memasang proxy terbalik untuk situs dengan lalu lintas tinggi.

Benar, penerapan di tempat tidak pernah dapat diandalkan atau atomic, jika Anda beruntung atau tidak memiliki banyak lalu lintas, itu akan baik-baik saja. Saya berasumsi bahwa mayoritas keluhan ada di sekitar skenario itu. Kami akan mempertimbangkan untuk meningkatkan berbagai hal dalam kerangka waktu .NET 5.0. Beberapa peringatan:

  • Kami akan melihat untuk membuat segalanya lebih baik untuk aplikasi yang bergantung pada kerangka kerja. Jika Anda menyebarkan mandiri maka Anda kurang beruntung. Ini akan mengunci file asli dan terkelola di folder output. Masalah penguncian dll asli selalu ada dan tidak akan diperbaiki oleh mitigasi apa pun yang kami lakukan.
  • Kami berencana untuk melihat memuat rakitan aplikasi ke dalam memori sebagai byte alih-alih memuatnya dari disk dan mengunci file. Ini seharusnya baik-baik saja untuk sebagian besar kasus tetapi dapat mengakibatkan penggunaan memori lebih banyak dalam beberapa kasus.
  • Untuk mendaur ulang aplikasi, Anda masih perlu menambah dan menghapus file appoffline. Menambahkan file appoffline adalah cara untuk memberi sinyal bahwa Anda ingin aplikasi dimulai ulang sebagai hasil dari penerapan.

@davidfowl Rencana yang Anda uraikan untuk 5.0 kedengarannya bagus. Kami menggunakan kerangka kerja yang bergantung seperti yang saya yakin kebanyakan.

Dengan hormat tidak setuju tentang keandalan penerapan di tempat. Saya telah melakukannya selama bertahun-tahun di situs dengan muatan yang sangat tinggi, tidak pernah mengalami masalah, tidak sekali pun. Perubahan pertama yang terdeteksi menyebabkan aplikasi disetel ulang, penyeimbang beban melihat bahwa instance tidak merespons, menjadikannya offline, setelah semua DLL diganti, penyeimbang beban menyelesaikan pemeriksaan kesehatan dan kembali online. Sekarang jika tidak ada pemeriksaan kesehatan penyeimbang beban, maka ya, itu pertaruhan, tapi maksud saya siapa yang menggantikan DLL dalam produksi di bawah beban tinggi tanpa proxy? Mari fokus pada aturan dan bukan pengecualian. Tanpa proxy, saya tidak dapat memikirkan cara apa pun untuk memperbarui aplikasi tanpa menyebabkan pemadaman. Meskipun Anda mendukung hot reload, beberapa permintaan mungkin akan hang atau gagal.

Dengan hormat tidak setuju tentang keandalan penerapan di tempat. Saya telah melakukannya selama bertahun-tahun di situs dengan muatan yang sangat tinggi, tidak pernah mengalami masalah, tidak sekali pun. Perubahan pertama yang terdeteksi menyebabkan aplikasi disetel ulang, penyeimbang beban melihat bahwa instance tidak merespons, menjadikannya offline, setelah semua DLL diganti, penyeimbang beban menyelesaikan pemeriksaan kesehatan dan kembali online. Sekarang jika tidak ada pemeriksaan kesehatan penyeimbang beban, maka ya, itu pertaruhan, tapi maksud saya siapa yang menggantikan DLL dalam produksi di bawah beban tinggi tanpa proxy? Mari fokus pada aturan dan bukan pengecualian. Tanpa proxy, saya tidak dapat memikirkan cara apa pun untuk memperbarui aplikasi tanpa menyebabkan pemadaman. Meskipun Anda mendukung hot reload, beberapa permintaan mungkin akan hang atau gagal.

Anda memiliki penyeimbang beban. Banyak orang tidak memiliki penyeimbang beban dan hanya mengganti file di disk dan mengharapkan keajaiban 😄

@davidfowl Benar tapi lalu lintas tinggi + tidak ada lb = sembrono

Juga, masalah dengan app_offline.htm adalah bahwa dari proses ci / cd Anda tidak tahu kapan proses tersebut berhenti. Kami harus menambahkan perintah tidur yang besar antara membuat file itu dan mendorong DLL karena proses mematikan kami dapat berlangsung dari 1 hingga 1 menit. Saat Anda melakukan load balancing banyak sekali instance, sleep tersebut menambah siklus penerapan yang sangat lama.

Memuat file ke dalam memori memperbaiki semua itu.

@davidfowl Benar tapi lalu lintas tinggi + tidak ada lb = sembrono

👍

Juga, masalah dengan app_offline.htm adalah bahwa dari proses ci / cd Anda tidak tahu kapan proses tersebut berhenti. Kami harus menambahkan perintah tidur yang besar antara membuat file itu dan mendorong DLL karena proses mematikan kami dapat berlangsung dari 1 hingga 1 menit. Saat Anda melakukan load balancing banyak sekali instance, sleep tersebut menambah siklus penerapan yang sangat lama.

Benar, jadi masalahnya adalah menghapus file itu tidak memberi tahu Anda kapan boleh memulai penerapan karena file masih terkunci hingga pemberitahuan diterima oleh ANCM.

Juga, masalah dengan app_offline.htm adalah bahwa dari proses ci / cd Anda tidak tahu kapan proses tersebut berhenti.

Benar, penerbit VS menggunakan waktu tidur singkat dan beberapa percobaan ulang.

  • Untuk mendaur ulang aplikasi, Anda masih perlu menambah dan menghapus file appoffline. Menambahkan file appoffline adalah cara untuk memberi sinyal bahwa Anda ingin aplikasi dimulai ulang sebagai hasil dari penerapan.

Apakah mungkin memiliki file "apprestart" untuk menandai aplikasi yang akan didaur ulang tanpa harus menghapus file appoffline sesudahnya?

@Socolin kenapa begitu?

@Socolin kenapa begitu?

Jika saya mengerti dengan baik (beri tahu saya jika saya salah), apa yang Anda rencanakan adalah menghapus kunci, tetapi kita masih harus membuat appoffline untuk memberi sinyal kepada IIS agar mendaur ulang aplikasi setelah pembuatan selesai?

Untuk melakukannya, kita harus membuat file appoffline, lalu menghapusnya. Bisakah file ini segera dihapus setelah file dibuat? atau haruskah kita menunggu IIS mendeteksinya? Jika diperlukan untuk menunggu sebentar, saya lebih suka memiliki file seperti "apprestart" yang akan didengarkan oleh IIS, kemudian hapus setelah mendeteksi dan mulai mendaur ulang.


Juga, saya punya pertanyaan lain dalam pikiran. Ini tentang pengoptimalan IDE selama build.

Saat ini, saya mengerjakan proyek yang menggunakan dependensi, kami memiliki proyek untuk lapisan Web, dan proyek lain untuk Logika dan Data. Ketika saya bekerja di lapisan Web (ASP.NET Core) selama pembuatan, saya membuat file appoffline sebelum pembuatan, lalu menghapusnya setelah pembuatan dan berhasil.

Tetapi ketika saya bekerja di salah satu dependensi, ketika saya membangunnya dari Rider (saya pikir itu melakukan hal yang sama pada VS karena menggunakan msbuild) ketika saya melihat apa yang dilakukan msbuild, setelah pembangunan proyek selesai, dll disalin langsung di direktori .Web / bin tanpa membangun kembali proyek .Web. Dan karena dll terkunci, diam-diam gagal, dan saya harus me-restart server secara manual atau secara manual memicu pembangunan proyek .Web.

Apakah Anda punya solusi untuk ini?
Sejauh ini solusi yang saya temukan adalah menulis program kecil yang berjalan di latar belakang yang mencari / bin dari proyek .Web saya. Ketika file berubah, itu membuat file appoffline ke direktori tempat IIS mendengarkan, lalu menyalin file yang diubah, lalu menghapus appoffline. Tapi rasanya agak hack tapi sejauh ini satu-satunya cara yang saya temukan untuk dapat membangun, lalu tekan F5 dan uji perubahan saya.

Untuk melakukannya, kita harus membuat file appoffline, lalu menghapusnya. Bisakah file ini segera dihapus setelah file dibuat? atau haruskah kita menunggu IIS mendeteksinya? Jika diperlukan untuk menunggu sebentar, saya lebih suka memiliki file seperti "apprestart" yang akan didengarkan oleh IIS, kemudian hapus setelah mendeteksi dan mulai mendaur ulang.

Bagaimana IIS tahu setelah Anda selesai menyalin file? Bagaimana Anda menghindari keadaan robek? Anda pada dasarnya perlu memberi sinyal permulaan dan penyelesaian transaksi. Pembuatan file menandakan awal dan penghapusan menandai akhir.

Apakah Anda punya solusi untuk ini?
Sejauh ini solusi yang saya temukan adalah menulis program kecil yang berjalan di latar belakang yang mencari / bin dari proyek .Web saya. Ketika file berubah, itu membuat file appoffline ke direktori tempat IIS mendengarkan, lalu menyalin file yang diubah, lalu menghapus appoffline. Tapi rasanya agak hack tapi sejauh ini satu-satunya cara yang saya temukan untuk dapat membangun, lalu tekan F5 dan uji perubahan saya.

VS menangani ini dengan menghentikan proses sebelum memulai file baru untuk apa pun yang mungkin memengaruhi pembangunan proyek itu.

Untuk melakukannya, kita harus membuat file appoffline, lalu menghapusnya. Bisakah file ini segera dihapus setelah file dibuat? atau haruskah kita menunggu IIS mendeteksinya? Jika diperlukan untuk menunggu sebentar, saya lebih suka memiliki file seperti "apprestart" yang akan didengarkan oleh IIS, kemudian hapus setelah mendeteksi dan mulai mendaur ulang.

Bagaimana IIS tahu setelah Anda selesai menyalin file? Bagaimana Anda menghindari keadaan robek? Anda pada dasarnya perlu memberi sinyal permulaan dan penyelesaian transaksi. Pembuatan file menandakan awal dan penghapusan menandai akhir.

Jika tidak ada kunci, mengapa memberi tahu IIS saat build dimulai? Tidak bisakah kita memberi sinyal ketika semua file diperbarui dan aplikasi perlu didaur ulang? Saya pikir saya salah paham tentang sesuatu.

Jika tidak ada kunci, mengapa memberi tahu IIS saat build dimulai? Tidak bisakah kita memberi sinyal ketika semua file diperbarui dan aplikasi perlu didaur ulang? Saya pikir saya salah paham tentang sesuatu.

Ya itu akan berhasil. Saya pikir Anda sedang menggambarkan keadaan seni saat ini. Bahkan mungkin untuk melakukan ini hari ini dengan web.config. Jika Anda menyentuh file tersebut, aplikasi akan di-boot ulang.

Saya telah sukses dengan penerapan di tempat (https://flukefan.github.io/ZipDeploy/), dengan:

  1. Ubah nama file assembly (tampaknya Anda dapat mengganti nama meskipun Anda tidak dapat menghapus / menimpa);
  2. Salin di majelis baru;
  3. Sentuh web-config untuk memulai ulang aplikasi;
  4. Hapus majelis lama yang diganti namanya.

Tidak ada load-balancing; satu contoh IIS; tidak ada perubahan IIS. YMMV.

@FlukeFan Bagaimana Anda menghindari penyebaran yang robek atau itu bukan urusan Anda? Dengan robek, maksud saya ada jendela tempat aplikasi lama memuat rakitan baru sebelum memulai ulang aplikasi.

Saya tidak menyentuh web.config sampai semua rakitan diganti namanya / diperbarui. Saya kira ada kemungkinan kecil bahwa sesuatu yang lain dapat menyebabkan kumpulan aplikasi mendaur ulang selama waktu itu, tetapi itu belum terjadi.

Saya biasanya mematikan semua opsi daur ulang otomatis lainnya, dan juga menonaktifkan daur ulang yang tumpang tindih di pengaturan kumpulan aplikasi IIS.

@FlukeFan bukan daur ulang tetapi jika Anda belum memuat rakitan yang harus diganti. Misalnya, Anda memiliki rakitan A.dll dan B.dll. Katakanlah B digunakan ketika Anda pergi ke halaman pengaturan sehingga dimuat kemudian. Jika Anda pergi ke halaman pengaturan saat B.dll diganti dengan yang baru, Anda bisa berakhir dengan aplikasi lama berjalan dengan B.dll baru.

Saya bertanya-tanya apakah kita harus membuat alat global dotnet untuk membantu penerapan jenis ini. Alat ini pada dasarnya dapat melakukan semua hal sulit yang disebutkan orang di utas ini.

Pikiran?

@FlukeFan bukan daur ulang tetapi jika Anda belum memuat rakitan yang harus diganti. Misalnya, Anda memiliki rakitan A.dll dan B.dll. Katakanlah B digunakan ketika Anda pergi ke halaman pengaturan sehingga dimuat kemudian. Jika Anda pergi ke halaman pengaturan saat B.dll diganti dengan yang baru, Anda bisa berakhir dengan aplikasi lama berjalan dengan B.dll baru.

Jadi saya tidak menangani kasus itu sekarang. https://github.com/FlukeFan/ZipDeploy/blob/master/ZipDeploy/ZipDeploy.cs#L55

Saya kira saya bisa melakukan sesuatu dalam urutan yang berbeda, sentuh web.config terlebih dahulu, tunggu semua permintaan 'lainnya' selesai, lalu akhirnya lakukan penggantian tepat sebelum permintaan terakhir selesai (sementara IIS mengantri permintaan baru untuk about-to- recycle app-pool), tetapi apa yang saya miliki baru saja berhasil untuk saya.

Saat ini mungkin tidak cukup kuat untuk skenario yang Anda gambarkan (tetapi saya belum melakukan sesuatu yang mewah dengan pemuatan perakitan dinamis selain pada waktu startup).

Apakah ada rencana untuk mengunjungi kembali fitur ini dan meletakkannya di peta jalan? Sangat merepotkan / tidak bersahabat untuk mengharuskan semua orang menggunakan situs web .Net Core untuk secara manual menerapkan strategi staging-slot jika mereka ingin mendukung penerapan zero downtime.

Memiliki fitur ini akan membuat transisi ke situs web .Net Core jauh lebih lancar bagi banyak orang, dan akan memungkinkan adopsi situs web .Net Core yang lebih cepat.

Saya tidak pernah memikirkan itu. Tapi Anda mungkin telah memukul paku di kepala. Ini bisa menjadi keputusan bisnis yang jahat untuk memaksa orang menggunakan slot biru. Jika mungkin di masa lalu mengapa butuh waktu lama untuk "memperbaikinya" sekarang? Ini tidak rusak dari perspektif bisnis apa yang ada dalam pikiran. Mungkin saya sedikit sinis. Tapi saya perlahan-lahan melihat fitur biru yang dulunya gratis dipangkas dan dipindahkan ke tingkatan yang lebih mahal.

Saya bertanya-tanya apakah kita harus membuat alat global dotnet untuk membantu penerapan jenis ini. Alat ini pada dasarnya dapat melakukan semua hal sulit yang disebutkan orang di utas ini.

Pikiran?

Ini untuk dijalankan di server CI, katakan? Bagaimana cara mendorong binari / paket ke server tujuan?

Saya tidak pernah memikirkan itu. Tapi Anda mungkin telah memukul paku di kepala. Ini bisa menjadi keputusan bisnis yang jahat untuk memaksa orang menggunakan slot biru. Jika mungkin di masa lalu mengapa butuh waktu lama untuk "memperbaikinya" sekarang? Ini tidak rusak dari perspektif bisnis apa yang ada dalam pikiran. Mungkin saya sedikit sinis. Tapi saya perlahan-lahan melihat fitur biru yang dulunya gratis dipangkas dan dipindahkan ke tingkatan yang lebih mahal.

Penerapan di tempat tanpa koordinasi pada dasarnya tidak dapat diandalkan karena alasan yang disebutkan di atas. Kami tidak akan pernah menerapkan penyalinan bayangan lagi karena fitur tersebut secara historis tidak dapat diandalkan dan telah menyebabkan banyak masalah di ASP.NET pada kerangka .NET. Ini juga hanya berfungsi untuk jenis penyebaran tertentu, tergantung kerangka kerja yang semuanya didukung .NET Framework. .NET core mendukung file mandiri dan tunggal yang membuatnya lebih sulit untuk didukung. Bahkan saran di atas tidak mencakup kasus-kasus tersebut.

Kami masih percaya bahwa melakukan penerapan di tempat harus sekompleks mungkin dan banyak masalah pada masalah ini berasal dari bug dan tidak dapat diandalkannya deteksi dan daur ulang app_offline sehingga kami menghabiskan banyak waktu untuk memperbaikinya (dan juga penguncian pdb).

Penyebaran web adalah satu-satunya alat saat ini yang mewujudkan aliran yang menurut kami masuk akal untuk diterapkan tetapi terjebak dalam teknologi itu sehingga tidak membantu jika Anda menggunakan ftp ke server Anda atau menyalin ke file share (meskipun itu bisa).

Alat global dotnet mungkin bisa menjadi jawabannya di sini.

Ini untuk dijalankan di server CI, katakan? Bagaimana cara mendorong binari / paket ke server tujuan?

Saya rasa tidak. Ini mungkin akan mendukung FTP dan salinan langsung. Apa pun selain itu kemungkinan merupakan protokol berpemilik.

Mudah-mudahan ketika Anda mengatakan FTP yang Anda maksud adalah ftp di atas ssh. Alat seperti itu akan sangat berharga.

Mudah-mudahan ketika Anda mengatakan FTP yang Anda maksud adalah ftp di atas ssh. Alat seperti itu akan sangat berharga.

Tidak, maksudku ftp. Tapi kami akan melakukan apapun yang masuk akal. Mungkin yang terbaik adalah menjadi alat penyalin yang Anda perlukan untuk dijalankan di mesin target. Itu membuat kami keluar dari bisnis karena harus mengirim bit ke mana pun.

Apakah Anda juga menggunakan SSH ke mesin windows Anda untuk diterapkan ke IIS?

@davidfowl Harap tambahkan (ikut serta) dukungan untuk slot penerapan.
https://github.com/dotnet/aspnetcore/issues/3719#issuecomment -473183712
https://github.com/dotnet/aspnetcore/issues/3793#issuecomment -335666414

Kami berencana untuk melihat memuat rakitan aplikasi ke dalam memori sebagai byte alih-alih memuatnya dari disk dan mengunci file. Ini seharusnya baik-baik saja untuk sebagian besar kasus tetapi dapat mengakibatkan penggunaan memori lebih banyak dalam beberapa kasus .

Selain itu, itu tidak akan membiarkan kami mencapai nol waktu henti.

Tidak mungkin kami akan berinvestasi dalam fitur seperti itu dengan modul.

Mudah-mudahan ketika Anda mengatakan FTP yang Anda maksud adalah ftp di atas ssh. Alat seperti itu akan sangat berharga.

Tidak, maksudku ftp. Tapi kami akan melakukan apapun yang masuk akal. Mungkin yang terbaik adalah menjadi alat penyalin yang Anda perlukan untuk dijalankan di mesin target. Itu membuat kami keluar dari bisnis karena harus mengirim bit ke mana pun.

Apakah Anda juga menggunakan SSH ke mesin windows Anda untuk diterapkan ke IIS?

Iya. Kami menggunakan CI / CD dan menerapkannya ke sistem linux dan windows, jadi jauh lebih mudah untuk menginstal openssh di kotak windows.

$ appPool = 'default'
Stop-WebAppPool -Nama $ appPool -Passthru
... terapkan ...

Mulai-WebAppPool -Nama $ appPool -Passthru
...menyebarkan.....

atau

$ appPool = 'default'
Stop-WebAppPool -Name $ appPool
while ((Get-WebAppPoolState -Name $ appPool) .Value -ne 'Stop') {
tidur 1 #detik
}
... terapkan ...

Mulai-WebAppPool -Nama $ appPool
while ((Get-WebAppPoolState -Name $ appPool) .Value -ne 'Start') {
tidur 1 #detik
}

...menyebarkan.....

Slot penempatan orang miskin
Sekitar setahun yang lalu saya telah memposting tentang membuat 2 folder akar situs dan memiliki titik symlink ke salah satunya dikonfigurasi untuk situs IIS.
Manfaatnya adalah waktu henti Anda kurang dibandingkan dengan solusi lain yang lebih sederhana.
Jika daur ulang tumpang tindih diaktifkan maka tidak ada waktu henti, hanya penalti pemanasan untuk permintaan pertama yang tetap terjadi.

Jika operasi penerapan / salin membutuhkan waktu N detik untuk selesai, Anda tidak perlu menghentikan kumpulan aplikasi selama N detik.
Tidak mengotak-atik aplikasi offline yang dipertanyakan.
Cukup salin ke folder tidak aktif, tukar symlink ketika file ada, lalu daur ulang pool aplikasi.
Penyebaran atom, tidak ada waktu henti, hanya permintaan pertama yang lebih lambat seperti biasa.

https://github.com/dotnet/aspnetcore/issues/3793#issuecomment -459870870

Apakah ada yang mencobanya?
Jika sesuatu seperti ini berfungsi maka dapat diubah menjadi layanan dengan alat penyebaran sisi klien.

  • klien -> server apa folder / share yang tidak aktif?
  • S: di sini
  • C: ok diterapkan / disalin
  • S: symlink ditukar dan didaur ulang
  • C: thx, http get / healthcheck (opsional)
  • C: ugh saya mengacaukannya, tolong kembalikan
  • S: swap symlink, daur ulang (kembali berbisnis)
  • C: bilas ulang sampai berhasil

Jadi saya juga mengalami masalah dengan penyebaran file terkunci. di hosting aplikasi. Saya telah mencoba menghentikan kumpulan aplikasi, tetapi file tetap terkunci. Saya telah mencoba mendorong app_offline.htm tetapi tidak berhasil juga.
Juga jika Anda ingin mengelola penghapusan file app_offline.htm Anda dapat dengan mudah melakukannya saat memulai aplikasi di program.cs. Dengan cara ini kami tahu kapan itu mulai menjadi online.

Masalah saat ini yang saya hadapi adalah bahwa dll itu digantung dan bahkan jika Anda mengganti nama kemudian menyalin file, proses lama masih berjalan terhadap file yang diganti namanya. Jadi saat kami mencoba menerapkan lagi, kami harus mengganti nama file lagi. Saya kira kita bisa menggunakan semacam tanggal sebagai pengganti nama file.
Kami menggunakan dotnet core 3.1.4 untuk ini di IIS server windows 2012 R2

@foxjazz bagaimana file masih terkunci jika pool / proses aplikasi dihentikan? Bisakah Anda menjelaskannya?

@foxjazz bagaimana file masih terkunci jika pool / proses aplikasi dihentikan? Bisakah Anda menjelaskannya?

image

image

Ketika mencoba untuk menghapus dll bekas gambar mengatakan digunakan oleh proses lain.
Pool aplikasi telah offline untuk sementara waktu.

Periksa pengelola tugas untuk melihat apakah proses masih berjalan. Menekan tombol stop tidak berarti langsung berakhir.

Periksa pengelola tugas untuk melihat apakah proses masih berjalan. Menekan tombol stop tidak berarti langsung berakhir.

gambar di atas adalah dari task manager. Tidak yakin yang mana, tetapi jika saya menghapusnya, itu akan melepaskan file. Saya kira saya bisa menggunakan pegangan untuk mengetahui pid untuk mengakhiri. Saya tidak berpikir saya harus bersusah payah sejauh ini untuk penerapan. Menangani mengatakan proses w3wp.exe 2 memiliki salah satu file terkunci. meskipun kumpulan aplikasi untuk itu ditutup.

Yang akan sangat menyenangkan adalah memiliki rute untuk menghentikan proses tersebut.
api \ KillDeathKill
{
Program.KillProcess ()
}

Itu tidak mungkin. File dikunci oleh suatu proses. Jika w3wp adalah proses itu maka ia tidak pernah dimatikan untuk memulai atau yang baru diputar dengan pid berbeda yang mengunci file yang sama. Itulah mengapa Anda perlu memastikan aplikasi offline terlebih dahulu untuk memastikan tidak ada proses baru untuk mengunci file, menghentikan proses yang ada, menerapkan bit baru, menghapus aplikasi offline

Itu tidak mungkin. File dikunci oleh suatu proses. Jika w3wp adalah proses itu maka ia tidak pernah dimatikan untuk memulai atau yang baru diputar dengan pid berbeda yang mengunci file yang sama. Itulah mengapa Anda perlu memastikan aplikasi offline terlebih dahulu untuk memastikan tidak ada proses baru untuk mengunci file, menghentikan proses yang ada, menerapkan bit baru, menghapus aplikasi offline

saat Anda mengatakan app_offline.htm turun dulu. Ya, inilah masalahnya. Saya memiliki jalur status yang dapat saya periksa melalui permintaan get, dan sudah pasti offline. Juga menghentikan kumpulan aplikasi secara manual. Namun proses w3wp masih menggantung file tersebut.

Kemudian proses tersebut tidak dihentikan

Kemudian proses tersebut tidak dihentikan

Jadi mengapa menghentikan kumpulan aplikasi, bukan menghentikan proses?

Pool aplikasi memang mewakili proses dan jika Anda menghentikan pool aplikasi, itu akan menghentikan prosesnya. File tidak dapat dikunci jika tidak ada proses untuk menguncinya sehingga salah satu dari teori lain tersebut tampaknya lebih mungkin terjadi.

Pool aplikasi memang mewakili proses dan jika Anda menghentikan pool aplikasi, itu akan menghentikan prosesnya. File tidak dapat dikunci jika tidak ada proses untuk menguncinya sehingga salah satu dari teori lain tersebut tampaknya lebih mungkin terjadi.

hah kamu mengatakan omong kosong. Saya tidak bermaksud untuk terlihat seperti saya meninju Anda. Saya mengatakan bahwa menghentikan kumpulan aplikasi TIDAK berfungsi seperti yang diiklankan di semua dokumentasi. Prosesnya tidak berhenti, bahkan setelah 90 detik, masih berjalan. File terkunci bahkan ketika Anda dapat melihat dengan jelas bahwa kumpulan aplikasi telah dihentikan. Proses tersebut berisi singleton untuk mendapatkan beberapa data. Dan pengontrol lainnya. Alangkah baiknya memiliki skrip yang akan menghentikan proses berdasarkan file yang dikunci. Saya kemudian bisa menyebarkan tanpa rasa takut. Mengganti nama mungkin juga berhasil. File dapat diganti namanya. (dotnet core 3.1.4) rasa

Sekitar setahun yang lalu saya telah memposting tentang membuat 2 folder akar situs dan memiliki titik symlink ke salah satunya dikonfigurasi untuk situs IIS.

Apakah ada yang mencobanya?
Jika sesuatu seperti ini berfungsi maka dapat diubah menjadi layanan dengan alat penyebaran sisi klien.

@CJHarmath - Saya sudah mencobanya, dan memiliki kode yang dimodifikasi yang saya gunakan di bawah ini. Bekerja dengan sangat baik, Terima kasih!

Jika saya menerbitkan pembaruan lebih lanjut, saya mungkin mempertimbangkan alat penyebaran klien, tetapi sebenarnya saya hanya dapat melakukan remote shell ke server IIS dan menjalankan skrip PowerShell untuk membaliknya.
psexec.exe \\IIS_SERVER cmd /c "powershell -noninteractive -file C:\FlipSymLink.ps1"

# FlipSymLink.ps1

Import-Module WebAdministration # run as admin
# create 2 site root directories
$a = 'C:\Websites\MySiteA'
$b = 'C:\Websites\MySiteB'
$appRoot  = 'C:\Websites\MySite'
$appName  = 'MyAppName'
$siteName = 'MySiteName'
$poolName = "MyPoolName"
New-Item -Type Directory $a -ErrorAction SilentlyContinue
New-Item -Type Directory $b -ErrorAction SilentlyContinue

# create a symlink to targeting one side
New-Item -Type SymbolicLink -Path $appRoot -Target $a -Name A -ErrorAction SilentlyContinue
New-Item -Type SymbolicLink -Path $appRoot -Target $b -Name B -ErrorAction SilentlyContinue

# point the site root to the symlink
$currentPath = (Get-ItemProperty "IIS:\Sites\$siteName\$appName" -name physicalPath)
if ($currentPath -eq "$appRoot\A") {
    Write-Host "Switched to B"
    New-Item $b\active.txt
    Remove-Item $a\active.txt
    Set-ItemProperty "IIS:\Sites\$siteName\$appName" -name physicalPath -value $appRoot\B
} else {
    Write-Host "Switched to A"
    New-Item $a\active.txt
    Remove-Item $b\active.txt
    Set-ItemProperty "IIS:\Sites\$siteName\$appName" -name physicalPath -value $appRoot\A
}
Restart-WebAppPool -Name $poolName

psexec.exe \\IIS_SERVER cmd /c "powershell -noninteractive -file C:\FlipSymLink.ps1"

Ini juga bisa diubah menjadi titik akhir JEA , sehingga Anda dapat menjalankan flip sebagai pengguna non-elevasi (mis. Dari langkah penerapan server CI / CD)
Invoke-Command -ComputerName IIS_SERVER -ConfigurationName IIS-Flip -ScriptBlock { Switch-SymlinkTarget -SiteName MySite}
Menggunakan Switch alih-alih Flip karena ini adalah kata kerja yang disetujui.

Menggunakan Switch alih-alih Flip karena ini adalah kata kerja yang disetujui.

Swap adalah kata kerja yang digunakan saat menangani slot - apakah masuk akal untuk digunakan kembali di sini?

mengalami masalah yang sama seperti yang dijelaskan 4 tahun lalu.
Ada pembaruan tentang ini?
Saya tidak ingin membuka Remote desktop hanya untuk mengupload file dll baru.

Ketika saya mencoba untuk menimpa file .NET Core aplikasi DLL menggunakan FTP pada produksi file server IIS terkunci dan tidak dapat ditimpa.

Untuk menerapkan versi baru, saya perlu menghentikan aplikasi di IIS (membuka RDP) untuk melepaskan kunci, lalu menimpa.
Tidak mungkin untuk menerapkan tanpa menghentikan aplikasi.

Ada solusi untuk ini? Terima kasih

Jika Anda tidak dapat membuat host Anda offline di belakang loadbalancer dan ingin melakukannya lebih cepat, berikut adalah salah satu cara dengan symlink dan beberapa PowerShell.
Saya berpikir untuk melakukan sesuatu seperti ini.

Ini lebih cepat karena Anda tidak perlu menghentikan kumpulan aplikasi selama salin + daur ulang lebih baik daripada berhenti keras karena memungkinkan permintaan saat ini selesai, jadi lebih sedikit waktu henti.

# Setup
Import-Module WebAdministration
# create 2 site root directories
$a = 'C:\inetpub\AspNetCoreSampleA'
$b = 'C:\inetpub\AspNetCoreSampleB'
$siteRoot = 'C:\inetpub\aspnetcoresample'
$siteName = 'AspNetCoreSample'
$poolName = "aspnetcore"
New-Item -Type Directory $a
New-Item -Type Directory $b
# create a symlink to targeting one side
New-Item -Type SymbolicLink -Path $siteRoot -Target $a
# point the site root to the symlink
Set-ItemProperty "IIS:\Sites\$siteName" -name physicalPath -value $siteRoot
# make sure it get's picked up
Restart-WebAppPool -Name $poolName

# this tells you the active side
Get-Item -Path $siteRoot | Select-Object -ExpandProperty target

# Flip the symlink
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
# at this point w3wp.exe still locks the current target folder until it's getting recycled
# Deploy new version to the symlink which is now pointing to the other side which should have no locks
robocopy \\myshare\myapp $siteRoot /mir
# recycle app pool, so it picks up the new files
Restart-WebAppPool -Name $poolName

# bonus point: rollback is easy
$current = (Get-Item -Path $siteRoot).Target
$newTarget = if ($current -eq $a) {$b} else {$a}
New-Item -Type SymbolicLink -Path $siteRoot -Target $newTarget -Force
Restart-WebAppPool -Name $poolName

Inilah intinya
https://gist.github.com/csharmath/b2af0f50700ce9fbdd8c5c3e582fd41b

Inilah sesuatu yang menurut saya sudah saya perbaiki. Saya hanya mencoba dengan ASP.NET, tetapi saya membayangkan akan bekerja sama dengan modul hosting untuk inti bersih. Proses pertama menghentikan situs untuk sedikit, jadi mungkin ingin mengubahnya sedikit.

param(
    [Parameter(Mandatory = $true)]
    [string] $iisRootPath,
    [Parameter(Mandatory = $true)]
    [string] $siteName,
    [Parameter(Mandatory = $true)]
    [string] $artifactPath,
    [Parameter(Mandatory = $false)]
    [string] $siteFolderName,
    [Parameter(Mandatory = $false)]
    [string] $appPoolName
)
Import-Module WebAdministration

#populate optional parameters
if (!($PSBoundParameters.ContainsKey('siteFolderName'))) { $siteFolderName = $siteName }
if (!($PSBoundParameters.ContainsKey('appPoolName'))) { $appPoolName = $siteName }

#set A, B and C paths
$a = "$iisRootPath\$siteFolderName" + 'A'
$b = "$iisRootPath\$siteFolderName" + 'B'
$c = "$iisRootPath\$siteFolderName"

#existence test
$cName = Get-Item -Path $c -ErrorAction SilentlyContinue | Select-Object -ExpandProperty name -ErrorAction SilentlyContinue
$bName = Get-Item -Path $b -ErrorAction SilentlyContinue | Select-Object -ExpandProperty name -ErrorAction SilentlyContinue

#get the shudown timeout for the app pool
$shutdownTimeout = Get-WebConfigurationProperty -Filter 'system.web/httpRuntime' -PSPath "IIS:\Sites\$siteName" -Name shutdownTimeout | Select-Object -ExpandProperty Value

#create symlink, if symlink source is an existing directory, rename existing 
if($cName -eq $null) 
{
    Write-Output "Creating SymbolicLink $c -> $a" 
    New-Item -Type SymbolicLink -Path $c -Target $a
} 
else
{
    #directories don't have a target property
    $cTarget = Get-Item -Path $c | Select-Object -ExpandProperty target -ErrorAction SilentlyContinue

    #this is a directory, rename and create symlink
    if($cTarget -eq $null)
    {
        #restart AppPool first so no locked files
        #Write-Output "Restarting AppPool $appPoolName" 
        #Restart-WebAppPool -Name $appPoolName

        #stop AppPool first so no locked files
        Write-Output "Stopping AppPool $appPoolName" 
        Stop-WebAppPool -Name $appPoolName

        #sleep for shutdownTimeout
        Write-Output "Sleeping for $shutdownTimeout" 
        Start-Sleep -Seconds (([System.TimeSpan]::Parse("$shutdownTimeout").TotalSeconds) * 1.1)

        try {
             #if the rename fails, there are files in use. stop the script
            $newName = $siteFolderName + 'A'
            Write-Output "Renaming $c to $newName" 
            Rename-Item -Path $c -NewName $newName -ErrorAction Stop
        }
        catch {
            Write-Error -Message "Failed to rename $c to $newName due to files in use."

            #start AppPool 
            Write-Output "Starting AppPool $appPoolName due to failed folder rename. Consider trying again durring a time with reduced traffic." 
            Start-WebAppPool -Name $appPoolName

        }

        #create symlink
        Write-Output "Creating SymbolicLink $c -> $a" 
        New-Item -Type SymbolicLink -Path $c -Target $a

        #start AppPool 
        Write-Output "Starting AppPool $appPoolName" 
        Start-WebAppPool -Name $appPoolName

        #copy a to b to pick up directory permissions
        if($bName -eq $null) 
        {
            Write-Output "Copying Directory $a to $b"  
            robocopy $a $b /e /sec /sl
        }
    }
}

#existence test
$aName = Get-Item -Path $a -ErrorAction SilentlyContinue | Select-Object -ExpandProperty name -ErrorAction SilentlyContinue
$bName = Get-Item -Path $b -ErrorAction SilentlyContinue | Select-Object -ExpandProperty name -ErrorAction SilentlyContinue

#create if needed
if($aName -eq $null) 
{
    Write-Output "Creating Directory $a"  
    New-Item -Type Directory $a 
}
if($bName -eq $null) 
{
    Write-Output "Creating Directory $b"  
    New-Item -Type Directory $b 
}

#make sure site pointing to symlink
Write-Output "Pointing Website $siteName to Path $c" 
Set-ItemProperty "IIS:\Sites\$siteName" -name physicalPath -value $c

#restart so we know it's loading from symlink
Write-Output "Restarting AppPool $appPoolName" 
Restart-WebAppPool -Name $appPoolName

#sleep for shutdownTimeout 
Write-Output "Sleeping for $shutdownTimeout" 
Start-Sleep -Seconds ([System.TimeSpan]::Parse("$shutdownTimeout").TotalSeconds)

#get current symlink target and set new target
Get-Item -Path $c | Select-Object -ExpandProperty target
$current = (Get-Item -Path $c).Target
$newTarget = if ($current -eq $a) {$b} else {$a}

$fileOrDirectoryName = Get-Item $artifactPath | Select-Object -ExpandProperty name

#test for .zip
if(($fileOrDirectoryName).ToLower().EndsWith(".zip") -eq $true)
{
    #copy to temp location
    $guid = [System.Guid]::NewGuid()
    $tempPath = "$iisRootPath\temp-$guid"
    $tempDest = "$iisRootPath\temp-dest-$guid"

    Write-Output "Creating temp directory $tempPath" 
    New-Item -Type Directory $tempPath

    $artifactDirectory = [System.IO.Path]::GetDirectoryName($artifactPath)
    $artifactFile = [System.IO.Path]::GetFileName($artifactPath);

    #TODO: first robocopy arg needs to be a directory, not a file
    Write-Output "Copying archive from $artifactPath to $tempPath" 
    robocopy $artifactDirectory $tempPath $artifactFile

    #extract to temp destination (seems a failed extract can leave empty folders)
    Write-Output "Extracting archive to $tempDest" 
    Expand-Archive -Path "$tempPath\$fileOrDirectoryName" -DestinationPath $tempDest -Force

    #copy from temp destination to destination
    Write-Output "Copying files from $tempDest to $newTarget" 
    robocopy $tempDest $newTarget /e

    #delete temp directory
    Write-Output "Removing temp directory $tempPath" 
    Remove-Item -Path $tempPath -Recurse -Force

    #delete temp directory
    Write-Output "Removing temp directory $tempDest" 
    Remove-Item -Path $tempDest -Recurse -Force
}
else 
{
    #copy new files
    Write-Output "Copying files from $artifactPath to $newTarget" 
    robocopy $artifactPath $newTarget /e
}

#swap symlink
Write-Output "Pointing SymbolicLink $c -> $newTarget" 
New-Item -Type SymbolicLink -Path $c -Target $newTarget -Force

#restart so it loads from newly swapped symlink
Write-Output "Restarting AppPool $appPoolName" 
Restart-WebAppPool -Name $appPoolName

@LucidObscurity apa itu? kode cmd? di mana saya harus menambahkan kode itu?
Terima kasih

Bagaimana dengan gagasan untuk menambah jumlah percobaan ulang (parameter: -retryAttempts:X ) atau interval waktu percobaan ulang (parameter: -retryInterval:XXXX ) untuk perintah msdeploy , hingga proses melepaskan kunci file?

Saya pikir @davidfowl benar, prosesnya masih ada dan mengunci file. Bahkan Reset IIS tidak membantu, masih menunggu proses hingga timeout. Jika Anda melepaskan app_offline.htm dan menunggu selama 90 detik (pengaturan batas waktu default untuk mematikan AppPool), dan mencoba lagi, Anda akan melihatnya berfungsi.
Bagi saya di lokal, saya tidak ingin menunggu selama itu jadi saya memperbarui Batas Waktu Shutdown (detik) ini menjadi 5 dan memperbarui file proyek untuk menghasilkan app_offline.htm sebelum membangun, menghapusnya setelah dibangun. Ini bekerja dengan baik.
Untuk server, saya menggunakan msdeploy untuk melepaskan app_offline.htm, menyinkronkan versi baru, lalu menghapus app_offline.htm. Dengan msdeploy, ia mencoba ulang jika file dikunci tetapi kadang-kadang menyerah sebelum 90 detik, jadi saya harus memicu penerapan lagi, lalu berfungsi pada percobaan kedua

Ada pembaruan tentang ini? Kapan rilis baru ini akan siap?

Terima kasih telah menghubungi kami.
Kami memindahkan masalah ini ke pencapaian Next sprint planning untuk evaluasi / pertimbangan di masa mendatang. Kami akan mengevaluasi permintaan tersebut ketika kami merencanakan pekerjaan untuk pencapaian berikutnya. Untuk mempelajari lebih lanjut tentang apa yang akan terjadi selanjutnya dan bagaimana masalah ini akan ditangani, Anda dapat membaca lebih lanjut tentang proses triase kami di sini .

Saya menemukan tentang masalah ini minggu ini, setelah mengubah aplikasi .NET 4.5.2 menjadi .NET 5.0. Saya memiliki pendekatan lain untuk mengatasi ini. Saya membuat Layanan Windows yang berjalan di server IIS. Pada Layanan itu saya memiliki Server HTTP sederhana yang berjalan pada port khusus. Aplikasi web dapat melakukan pasca-permintaan ke server tersebut untuk memulai peningkatan. Ini menghentikan kumpulan aplikasi memastikan untuk mematikan semua proses untuk aplikasi itu, membuat cadangan rilis saat ini, menghapus rilis saat ini, mengunduh paket pembaruan dan mengekstraknya. Kemudian mulai app-pool lagi.

Saya membuat aplikasi Windows Forms sederhana, untuk membuat paket pemutakhiran yang didorong ke repo yang diambil dari Layanan Windows yang disebutkan di atas.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat