Kami sedang menghadapi masalah yang menarik di StackOverflow.
Kami punya banyak tugas kecil "yang harus segera dikerjakan". Contohnya adalah memperbarui daftar "Pertanyaan Terkait". Apa yang telah kami lakukan di masa lalu adalah untuk membuntuti tugas-tugas tersebut ke beberapa halaman pengguna.
Ini tidak pernah ideal, tetapi itu tidak terlalu terlihat. Sekarang SO telah melewati tanda tanya 1.000.000, para pengguna yang sial mulai merasakannya.
Solusi alami adalah benar-benar mendorong tugas-tugas ini ke latar belakang. Ada dua cara luas untuk melakukan ini, saya sedang mempertimbangkan.
1. Di IIS sebagai Thread-Pool / Work-Queue khusus
Pada dasarnya, kami memutar beberapa (non- ThreadPool , agar tidak mengganggu IIS) dan meminta mereka melayani beberapa koleksi yang kami dorong ke dalam Funcs .
Pro besar di sini adalah kesederhanaan. Kami tidak perlu khawatir tentang mengatur apa pun, kami juga tidak harus memastikan beberapa layanan eksternal siap dan merespons.
Kami juga mendapatkan akses ke semua kode umum kami.
Kontra adalah, yah, bahwa kita seharusnya tidak menggunakan utas latar belakang. Keberatan yang saya tahu semuanya berpusat di sekitar kelaparan IIS (jika Anda menggunakan ThreadPool) dan utas mati secara acak (karena daur ulang AppPool).
Kami memiliki infrastruktur yang ada untuk menjadikan kematian utas acak sebagai non-masalah (kemungkinan untuk mendeteksi tugas telah ditinggalkan, pada dasarnya), dan membatasi jumlah utas (dan menggunakan utas non-ThreadPool) juga tidak sulit.
Pindah ke StackOverflow , karena tidak benar-benar dibahas di sini.
2. Sebagai Layanan
Baik solusi pihak ketiga, atau solusi kustom.
Pada dasarnya, kami akan menjalankan tugas melintasi batas proses untuk beberapa layanan dan lupakan saja. Agaknya kita menautkan beberapa kode, atau terbatas pada SQL + string koneksi mentah.
Pro adalah bahwa itu adalah "cara yang tepat" untuk melakukan ini.
Kontra adalah bahwa kita sangat terbatas dalam apa yang dapat kita lakukan, atau kita harus mengerjakan beberapa sistem untuk menjaga layanan ini sinkron dengan basis kode kita. Kita juga harus menghubungkan semua pemantauan dan kesalahan saat masuk, yang kita dapatkan secara gratis dengan opsi "In IIS".
Apakah ada manfaat atau masalah lain dengan pendekatan layanan?
Singkatnya, apakah ada masalah yang tak terduga dan tidak dapat diatasi yang membuat pendekatan # 1 tidak bisa diterapkan dan jika demikian, apakah ada layanan pihak ketiga yang baik yang harus kita perhatikan untuk pendekatan # 2?
sumber
Jawaban:
Beberapa minggu yang lalu saya mengajukan pertanyaan serupa pada SO. Singkatnya, pendekatan saya untuk beberapa waktu sekarang adalah mengembangkan Layanan Windows. Saya akan menggunakan NServiceBus (dasarnya MSMQ di bawah selimut) untuk menyusun permintaan dari aplikasi web saya ke layanan saya. Saya dulu menggunakan WCF tetapi mendapatkan transaksi terdistribusi untuk bekerja dengan benar melalui WCF selalu tampak seperti menyebalkan. NServiceBus melakukan trik, saya bisa mengkomit data dan membuat tugas dalam transaksi dan tidak khawatir apakah layanan saya sudah berjalan dan berjalan pada saat itu. Sebagai contoh sederhana, jika saya perlu mengirim email (misalnya email pendaftaran) saya akan membuat akun pengguna dan mematikan sinyal ke Layanan Windows saya (untuk mengirim email) dalam transaksi. Penangan pesan di sisi layanan akan mengambil pesan dan memprosesnya.
Karena ASP .NET 4.0 dan AppFabric telah dirilis, ada sejumlah alternatif yang layak untuk mekanisme di atas. Mengacu kembali ke pertanyaan yang saya sebutkan di atas, kami sekarang memiliki AppInitialize AppFabric (via net.pipe) serta fitur Auto-Start ASP .NET 4.0 yang menjadikan pengembangan Layanan Windows sebagai aplikasi web sebagai alternatif yang layak. Saya sudah mulai melakukan ini sekarang karena sejumlah alasan (penyebaran terbesar adalah tidak lagi menyebalkan):
Jika Anda menggunakan rute ini (maafkan saya karena menyalin dan menempel dari posting asli saya) saya pasti akan mempertimbangkan menjalankan logika latar belakang dalam aplikasi web yang terpisah. Ada beberapa alasan untuk ini:
Melakukan ini akan kembali ke aspek marshaling. WCF, NServiceBus / RabbitMQ / ActiveMQ dll., Vanilla MSMQ, RESTful API (pikirkan MVC) adalah semua opsi. Jika Anda menggunakan Windows Workflow 4.0, Anda dapat mengekspos titik akhir host yang dapat dikonsumsi aplikasi web Anda.
Pendekatan web hosting untuk layanan masih cukup baru bagi saya, hanya waktu yang akan memberi tahu apakah itu pilihan yang tepat. Sejauh ini baik baik saja. Omong-omong, jika Anda tidak ingin menggunakan AppFabric (saya tidak bisa karena karena alasan yang aneh, Windows Server Web Edition tidak didukung), kemampuan Mulai Otomatis yang disebutkan dalam pos Gu berfungsi dengan baik. Tetap jauh dari file applicationhost.config, semua yang ada di postingan tersebut dapat diatur melalui konsol IIS (Editor Konfigurasi pada tingkat server utama).
Catatan: Saya awalnya memposting beberapa tautan lagi dalam pesan ini tetapi sayangnya, ini adalah posting pertama saya untuk pertukaran ini dan hanya satu tautan yang didukung! Pada dasarnya ada dua orang lain, untuk memberi mereka Google "Death to Windows Services ... Long Live AppFabric!" dan "auto-start-asp-net-aplikasi". Maaf soal itu.
sumber
Sebenarnya ada cara ketiga di Windows untuk menjalankan layanan latar belakang, dan ini sangat umum di dunia UNIX. Cara ketiga adalah
CRON
pekerjaan yang menjalankan sebagian infrastruktur Anda. Di Windows ini dikenal sebagaitask scheduler
dan sangat umum untuk menjalankan kode secara terjadwal. Untuk menggunakan ini, Anda akan membuat aplikasi baris perintah yang dijalankan pada jadwal yang ditentukan sebelumnya. Keuntungan dari ini adalah bahwa Anda tidak perlu khawatir jika prosesnya tetap berjalan dan berjalan seperti layanan, karena jika gagal karena suatu alasan, itu akan mulai lagi di lain waktu.Sedangkan untuk mengatur tugas-tugas tertentu, Anda benar-benar hanya perlu menyimpan tugas-tugas ini dalam penyimpanan biner yang persisten. Sampai aplikasi baris perintah mengambil mereka dari penyimpanan dan mengeksekusi mereka. Saya telah melakukan ini di masa lalu dengan menggunakan basis data Cassandra sebagai Penyedia Status Sesi untuk menjejali tugas-tugas latar belakang untuk pengguna tertentu dalam basis data Cassandra, dan kemudian meminta commandline mengambilnya dan menjalankannya untuk pengguna.
Ini mungkin bukan solusi rawa-rawa yang umum, tetapi ini bekerja dengan sangat baik bagi saya dan ternyata menjadi solusi yang sangat elegan, karena tugas yang dijadwalkan selamat dari shutdown, masalah jaringan, dan mesin apa pun yang dapat menjalankan tugas karena itu terpusat disimpan.
Promosi yang memalukan, tetapi ini adalah proyek saya dan solusi yang saya jelaskan secara singkat adalah alasan saya membuat proyek: http://github.com/managedfusion/fluentcassandra/
sumber
Aplikasi Cron + Web
Ini adalah desain teruji bahwa skala horizontal bersama dengan peternakan web Anda dan memastikan bahwa Anda menggunakan tumpukan teknologi web Anda sudah tahu.
Begini cara kerjanya:
http://mydomain.com/system/cron
.Hore! Sekarang Anda memiliki rute yang akan dipanggil setiap 30 detik. Dan jika permintaan membutuhkan waktu 5 menit untuk diproses, tidak ada yang akan peduli, karena itu bukan bagian dari permintaan halaman pengguna.
The
cron
aksi akhirnya tampak sangat sederhana: ia memiliki daftar metode untuk mengeksekusi pada frekuensi tertentu. Ketika permintaan masuk, ia melihat apakah ada metode yang perlu dieksekusi dan memanggil metode yang sesuai. Ini berarti Anda dapat mengontrol jadwal di basis data Anda , di mana Anda mungkin sudah memiliki banyak data konfigurasi penting untuk situs Anda.Lebih penting lagi (untuk Anda), ini berarti bahwa pekerjaan Anda tidak harus dipanggil pada jadwal yang tetap. Anda dapat menulis logika apa pun yang Anda inginkan untuk menentukan kapan harus mengeksekusi suatu metode.
Pro dan kontra
ProCatatan: Jika ada pertanyaan atau masalah, silakan tambahkan komentar . Saya senang menguraikan.
sumber
Saya telah mencoba dan menggunakan hampir setiap cara yang mungkin untuk melakukan ini dalam aplikasi saya saat ini. Saya mulai melakukan hal yang sama seperti yang Anda lakukan saat ini, membuntuti permintaan pengguna untuk mengisi data dan kemudian menyimpannya. Saya menyadari ini adalah ide yang buruk juga (terutama karena Anda skala ke beberapa server web, lebih banyak pengguna menerima pukulan).
Saya juga telah memiliki pekerjaan yang dijadwalkan yang mengenai URL di aplikasi ASP.NET - ini adalah solusi yang layak tetapi itu mulai memecah saat Anda skala melewati 1 server web.
Saat ini saya menggunakan dua metode yang berbeda, keduanya menggunakan Quartz.NET yang merupakan perpustakaan kecil yang hebat. Yang pertama adalah Quartz.NET berjalan dalam proses dengan ASP.NET, itu adalah setup di global.asax dan berjalan setiap beberapa menit. Saya menggunakan ini untuk memperbarui cache ASP.NET keluar dari band yang merupakan satu-satunya alasan dijalankan sebagai bagian dari ASP.NET.
Yang kedua adalah saya menulis perpustakaan untuk membungkus Quartz.NET disebut DaemonMaster - membuatnya mudah untuk menjatuhkan DLL ke direktori dan menjalankannya di layanan Windows. Saya menemukan itu membantu menghindari beberapa bagian yang mengganggu dari bekerja dengan Layanan Windows dan juga membersihkan api Quartz.NET beberapa. Layanan yang dijalankan melalui DaemonMaster memiliki dua rasa berbeda, yang pertama adalah pekerjaan yang perlu dijalankan setiap malam atau setiap X minuts. Pekerjaan lain bekerja dari antrian berdasarkan data yang masuk dari aplikasi ASP.NET. Aplikasi ASP.NET menjatuhkan objek JSON di RabbitMQ dan polling layanan RabbitMQ kemudian memproses data.
Berdasarkan ini saya akan menyarankan Anda pergi dengan layanan Windows (dan periksa DaemonMaster) dan jika perlu gunakan antrian seperti RabbitMQ untuk meneruskan data dari aplikasi ASP.NET ke layanan - itu telah bekerja dengan baik dari semua solusi ini . Jika Anda memuat cache kemudian menjalankan di ASP.NET masuk akal, kalau tidak saya tidak berpikir begitu.
sumber
Saya akan melakukannya dengan cara yang benar dan menjalankan Layanan Windows yang memonitor "antrian". Saya mengatakan "antrian" karena pemrograman dengan MSMQ mirip dengan menempelkan hot pokers di bola mata Anda.
Saya telah jatuh cinta dengan kesederhanaan Delayed :: Job in Rails, dan hal serupa dapat dengan mudah dilakukan di .NET.
Pada dasarnya Anda menambahkan segala jenis
SomethingOperation
(sesuatu yang memilikiPerform()
metode). Kemudian hanya membuat serial parameter yang relevan, berikan prioritas, semacam perilaku coba lagi default dan masukkan ke dalam database.Layanan Anda hanya akan memonitor ini dan mengerjakan pekerjaan dalam antrian.
sumber
Kami sangat senang dengan pendekatan Bus Layanan / Antrian Pesan / Layanan. Arsitektur dasarnya adalah ini.
Situs web mengirim pesan ke antrian
Layanan Windows menerima dan memproses pesan pada waktunya sendiri
Keuntungannya adalah tidak ada penundaan untuk layanan front-end yang terhubung dengan pengguna juga. Layanan windows dapat dimatikan dan ditingkatkan tanpa gangguan ke situs utama. Plus itu sangat cepat .
Jika Anda tidak dapat menyimpan semua data dalam pesan, Anda selalu dapat menyimpannya dan mengambilnya nanti. Saya sarankan menggunakan mekanisme penyimpanan dokumen seperti: RavenDB atau MongoDB di mana sangat mudah untuk menyimpan kelas Anda tanpa perubahan.
Situs web mengirim pesan ke antrian
Layanan Windows menerima dan memproses pesan pada waktunya sendiri
Untuk mempermudah, kami menggunakan: Badak ESB dan Topshelf . Konfigurasi ini sangat sederhana dan menempatkan ini untuk aplikasi yang sudah ada terbukti membutuhkan waktu yang sangat sedikit.
sumber
Saya ingin tahu mengapa kombinasi keduanya bukan pilihan yang layak. Saat ini Anda memicu pekerjaan pada tampilan halaman, dengan beberapa getah sial macet menunggu 10 detik untuk halaman muncul. Setidaknya itulah pemahaman saya tentang metode Anda saat ini.
Namun pekerjaan itu membutuhkan waktu lebih lama dan lebih lama untuk berjalan seiring pertumbuhan situs, dan Anda tidak ingin menggagalkan pengalaman pengguna di situs. Bahkan untuk beberapa (atau mungkin banyak) pengguna yang tidak beruntung sepanjang hari, jadi sekarang Anda berpikir tentang menjadwalkan pekerjaan di latar belakang.
Saya tidak mengerti mengapa pekerjaan latar belakang berjalan secara berkala tidak dapat meniru pengunjung. Sekarang saya bukan programmer Windows, tetapi di dunia Linux saya akan mengatur pekerjaan cron yang berjalan pada interval reguler, dan itu akan memiliki 2 baris kode.
Ini menggabungkan pro dari kedua sistem. Itu dilakukan di latar belakang. Itu tidak mempengaruhi pengguna. Masih menggunakan tampilan halaman untuk memulai pekerjaan. Saya telah melihat pendekatan ini digunakan sebelumnya. Itu cenderung menjadi jalan tengah antara cara-cara sederhana yang lama, dan cara-cara yang lebih kompleks yang muncul.
Memperbarui
Saya pikir Anda bisa mengatasi masalah penyeimbangan beban dengan menjalankan pelari kerja di server web sendiri. Pelari pekerjaan menarik URL dari antrian pekerjaan, dan menjalankannya seperti ini:
Karena sifat antrian pekerjaan / perpesanan, pekerjaan tersebut akan didistribusikan secara merata di antara para pelari kerja, yang berarti special_crafted_url akhirnya didistribusikan di antara server web Anda.
sumber
specially_crafted_url
berasal dari IP yang dikenal, Anda bisa menambahkan aturan pada load balancer Anda untuk melakukan round-robin hanya untuk permintaan dari IP itu.Saya pikir tipuan dengan pendekatan layanan murni adalah bahwa Anda memiliki kode yang tersebar ke dalam layanan dan jauh dari aplikasi inti.
Inilah yang telah kami lakukan dengan pekerjaan latar belakang non-sensitif yang besar, yang menjaga kode bersama dan menyederhanakan layanan:
Lebih sederhana lagi, cukup buat panggilan di aplikasi konsol dan gunakan Penjadwal Tugas atau VisualCron untuk mengubahnya menjadi "layanan".
sumber
Saya suka TopShelf. Menjaga kesederhanaan, namun tetap melakukannya dengan cara yang benar berjalan sebagai Layanan Windows. Pada dasarnya buat Aplikasi Konsol, tambahkan sekitar 15-20 baris kode, lalu instal sebagai layanan.
http://code.google.com/p/topshelf/
sumber
Bagaimana dengan memiliki layanan Windows yang sangat sederhana yang berjalan di server web dan secara berkala mengenai URL pemeliharaan yang melakukan tugas-tugas lain Anda. Apakah itu mencekik berapa banyak pekerjaan yang dilakukannya dalam permintaan yang diberikan.
sumber
Saya akan melawan tren nyata di sini dan menyarankan untuk menggunakan model in-IIS. Saya sudah menggunakannya sendiri dan berfungsi dengan sangat baik. Benar-benar tidak sulit untuk mengimplementasikan kelas thread-pool yang layak (selama bertahun-tahun, saya telah memperpanjang kelas thread-pool saya untuk mendukung penciptaan dan penghancuran thread yang dinamis, mencoba kembali pekerjaan dan sebagainya). Keuntungannya adalah:
Menurut pendapat saya, solusi di-IIS hanyalah "langkah berikutnya" dari memboncengkan pekerjaan ke tampilan halaman acak.
sumber
Resque bagus. Atau bahkan Kthxbye jika Anda perlu diberitahu tentang nilai yang dihasilkan setelah selesai.
Keduanya berbasis Redis / Ruby.
Jujur, jika Anda melakukan pendekatan berbasis layanan, itu benar-benar tidak perlu super-terintegrasi dengan platform Anda saat ini, yang saya rasa merupakan nilai tambah. Saya berharap itu bisa menjadi sistem set-dan-lupa yang akan berjalan (dengan pemantauan semacam) dan menyelesaikan pekerjaan. Saya tidak yakin itu harus dijalankan pada platform yang sama sekali karena hanya memperbarui / memodifikasi info basis data.
Cukup yakin Anda bisa lolos dengan lebih banyak dengan lebih sedikit jika Anda menanam ini agak berhasil untuk entitas yang terpisah, terutama karena tampaknya Anda sedang berurusan dengan masalah threading. Baik Resque dan Kthxbye memindahkan pemrosesan ke proses terpisah untuk memungkinkan OS menangani konkurensi.
Dijual kembali
Kthxbye
sumber
Saya akan menggunakan layanan WCF yang di-hosting WAS mendengarkan Antrian MSMQ.
Pro
Api dan lupakan pesan satu arah dari aplikasi web
Throttling dan coba ulang MSMQ / WCF
Pengiriman terjamin; D
Manajemen Surat Mati
Pemrosesan terdistribusi
Aktivasi WAS / MSMQ
Con
Fitur MSMQ di WCF membuat penggunaan MSMQ sangat bagus. Ya, Anda akan kehabisan konfigurasi tetapi manfaatnya akan lebih besar dari pengorbanan.
sumber
Saya pernah mengalami ini beberapa kali ketika mengembangkan aplikasi web. Kami telah menyelesaikannya dengan membuat aplikasi konsol windows yang melakukan tugas, dan membuat tugas terjadwal yang berjalan sesering mungkin untuk benar-benar melakukan tugas tersebut.
sumber
Anda dapat shunt bekerja ke utas latar (atau banyak utas latar belakang) menggunakan Rx dan sesuatu seperti berikut:
Menggunakan:
Host semua itu di dalam kelas yang hanya ada satu (alias singleton, tetapi lakukan dengan benar - gunakan wadah IoC Anda untuk menentukan gaya hidup).
Anda dapat mengontrol ukuran kumpulan utas dll dengan menulis penjadwal kustom sebagai pengganti menggunakan EventLoopScheduler (yang menjalankan utas tunggal).
sumber
Saya telah menerapkan hal semacam ini beberapa kali. Di windows, saya membuat program baris perintah python yang melakukan sesuatu di berbagai waktu. Program ini juga memperlihatkan antarmuka xmlrpc di porta. Kemudian, tugas terjadwal berjalan setiap menit dan menanyakan antarmuka xmlrpc. Jika tidak, mereka mencoba meluncurkannya. Jika tidak, email saya.
Keuntungannya adalah bahwa pekerjaan yang dijalankan tidak terikat cron atau jadwal. Saya memiliki pekerjaan proses yang berjalan setiap detik, tetapi akan menunggu lebih lama antara memulai pekerjaan baru tergantung pada apakah pekerjaan itu harus dilakukan. Juga, dapat digunakan untuk bertindak secara cerdas berdasarkan hasil. Punya 500 kesalahan? Punya penundaan sangat lama? Lakukan sesuatu yang lain. Beri tahu layanan lain. Dll
Dan sistem yang sama berfungsi pada unix, dengan sedikit modifikasi.
sumber
Saya sendiri tidak punya jawaban untuk Anda, tetapi masalahnya berbunyi lonceng - Saya ingat beberapa pria acak mendiskusikannya di podcast sekali .
sumber
Ikhtisar Antrian API Java
Konsep Tugas
Dalam pemrosesan latar belakang App Engine, tugas adalah deskripsi lengkap dari unit kerja kecil. Deskripsi ini terdiri dari dua bagian:
Tugas sebagai Kait Web Offline
Untungnya, Internet sudah menyediakan solusi semacam itu, dalam bentuk permintaan HTTP dan responsnya. Payload data adalah isi permintaan HTTP, seperti variabel formulir web, XML, JSON, atau data biner yang disandikan. Referensi kode adalah URL itu sendiri; kode aktual adalah logika apa pun yang dijalankan server dalam menyiapkan respons.
sumber
Lakukan keduanya
Tambahkan parameter opsional ke jalur pertanyaan yang berfungsi saat Anda membonceng permintaan pengguna:
Melayani tugas latar belakang di situs besar
Membuat aplikasi konsol yang berjalan di setiap server dan membuka biner log bersama IIS dan membacanya ke akhir file saat ini. Gunakan pengamat sistem file atau interval waktu untuk membaca maju untuk mengumpulkan pembaruan saat IIS membersihkan log.
Gunakan informasi ini untuk menentukan halaman apa yang saat ini dilihat.
Gunakan url halaman dari log yang diuraikan untuk memanggil versi "extrastuff" dari url di localhost dengan objek klien web.
Tambahkan beberapa kode untuk beralih file pada akhir setiap periode log atau memulai kembali proses setiap periode log.
sumber