Mengapa polling diterima dalam pemrograman web?

108

Saat ini saya sedang mengerjakan proyek Ruby on Rails yang memperlihatkan daftar gambar.

Yang harus dimiliki untuk proyek ini adalah bahwa ia menampilkan posting baru secara realtime tanpa perlu menyegarkan halaman web. Setelah mencari sebentar, saya menemukan beberapa solusi dan layanan JavaScript seperti PubNub; Namun, tidak ada solusi yang diberikan masuk akal sama sekali.

Dalam solusi JavaScript ( polling ) terjadi hal berikut:

  • Pengguna 1 melihat daftar foto.
  • Di latar belakang, kode JavaScript mengumpulkan titik akhir setiap detik untuk melihat apakah ada posting baru.
  • Pengguna 2 menambahkan foto baru.
  • Ada penundaan 50 ms sebelum siklus baru dipicu dan mengambil data baru.
  • Konten baru dimuat di DOM .

Ini tampak aneh ketika diterjemahkan ke contoh dunia nyata:

  • Pengguna 1 memegang tumpukan foto di atas mejanya.
  • Dia berjalan ke fotografer setiap detik dan bertanya apakah dia punya yang baru.
  • Fotografer membuat foto baru.
  • Detik ini ketika dia masuk, dia bisa mengambil gambar dan menaruhnya di tumpukan.

Menurut saya solusinya adalah sebagai berikut:

  • Pengguna 1 memegang tumpukan foto di atas mejanya.
  • Fotografer mengambil foto baru.
  • Fotografer berjalan ke tumpukan dan meletakkannya dengan sisanya.

Solusi PubNub pada dasarnya sama, namun kali ini ada magang berjalan di antara para pihak untuk berbagi data.

Tidak perlu dikatakan, kedua solusi ini sangat memakan energi karena dipicu bahkan ketika tidak ada data untuk dimuat.

Sejauh pengetahuan saya, tidak ada penjelasan (logika) mengapa cara implementasi ini digunakan di hampir setiap aplikasi realtime.

dennis
sumber
195
Mengabaikan sejenak bahwa browser web bukanlah server yang dapat menerima koneksi masuk ... tunggu, tidak, jangan abaikan itu.
GrandmasterB
17
@dennis: koneksi stateful, persisten antara server dan klien mungkin akan menghilangkan kebutuhan untuk polling, tapi itu bukan bagaimana Web dirancang.
FrustratedWithFormsDesigner
58
Bagaimana dengan Websockets?
I.Devries
25
Atau lihat polling panjang. Pada dasarnya Anda melakukan polling, tetapi server tidak merespons sebelum memiliki data baru untuk ditampilkan.
Matsemann
53
Ada banyak solusi dan algoritma yang masuk akal di ruang komputer yang benar-benar tidak masuk akal untuk dilakukan di meatspace.
whatsisname

Jawaban:

179

Mendorong berfungsi dengan baik untuk 1, atau sejumlah pengguna.

Sekarang ubah skenario dengan satu fotografer dan 1000 pengguna yang semuanya menginginkan salinan gambar. Fotografer harus berjalan ke 1000 tumpukan. Beberapa dari mereka mungkin berada di kantor yang terkunci, atau tersebar di lantai. Atau pengguna mereka sedang berlibur, dan tidak tertarik dengan gambar baru saat ini.

Fotografer akan sibuk berjalan sepanjang waktu dan tidak mengambil foto baru.

Pada dasarnya: model tarikan / jajak pendapat lebih baik untuk banyak pembaca yang tidak dapat diandalkan dengan persyaratan realtime yang longgar (jika gambar membutuhkan waktu 10 detik kemudian untuk tiba di tumpukan, apa masalahnya).

Yang mengatakan, model dorong masih lebih baik dalam banyak situasi. Jika Anda memerlukan latensi rendah (Anda memerlukan foto 5s baru setelah diambil), atau pembaruan jarang terjadi dan permintaan sering dan dapat diprediksi (terus bertanya kepada fotografer setiap 10 detik ketika ia membuat gambar baru sehari), maka menarik tidak pantas. Itu tergantung pada apa yang Anda coba lakukan. NASDAQ: dorong. Layanan cuaca: tarik. Fotografer pernikahan: mungkin menarik. Agen foto berita: mungkin mendorong.

ptyx
sumber
32
Saya sangat menyukai analogi Anda dengan 1000 pengguna, beberapa berlibur, beberapa tidak tertarik. +1.
riwalk
4
@EsbenSkovPedersen: Batas soket bukan karena alamat IP. Itu karena deskriptor file terbuka maksimum. Jadi jumlah maksimum soket terbuka tidak tergantung pada berapa banyak alamat IP yang Anda gunakan.
slebetman
10
Ini analogi yang mengerikan. Agar push to work berfungsi, klien pengguna mana pun harus memelihara semacam koneksi terbuka. Bahkan, pemungutan suara adalah persaingan suatu koneksi. Ini tidak seperti karena beberapa klien memberikan suara, bahwa semua klien diberi tahu. Demikian pula, ketika beberapa klien membuka koneksi untuk pemberitahuan push, tidak semua klien diberi tahu. Ini saran yang sangat buruk yang mengundang membuang sumber daya ke luar jendela. Dibombardir dengan 10.000 permintaan per detik sebenarnya tidak pernah lebih murah atau lebih baik daripada mempertahankan 10.000 soket terbuka.
back2dos
8
@ ptyx: Interval 1s adalah yang sedang dibahas di sini. Permintaan 10rb per detik berarti handrake 10rp TCP dan permintaan HTTP 10rb (masing-masing dengan mudah mencapai 2KB), yang memberi Anda banyak pesanan lebih banyak kebisingan latar belakang yang menghantam server Anda. Ada berbagai perpustakaan yang diuji pertempuran yang membuat langganan push semudah menempatkan polling di tempatnya. Bahkan ada kerangka kerja seperti meteor.js yang sepenuhnya mengaburkan seluruh masalah. Menarik untuk skalabilitas tanpa penjelasan lebih lanjut juga bukan argumen. Bagaimanapun, saya telah menyuarakan keraguan saya dan tidak ingin memulai diskusi;)
back2dos
5
Saya setuju dengan komentar back2dos di atas. Jika tarikan diskalakan lebih baik daripada dorong, google, pertukaran tumpukan, facebook, layanan stok online, dll. Akan menggunakan teknologi tarikan. Tetapi mereka tidak melakukannya. Pada dasarnya, memalu server alih-alih mengatur stasiun mendengarkan sangat buruk. Layanan utama menghindari jajak pendapat.
Travis J
106

Saya sangat terkejut bahwa hanya satu orang yang menyebutkan WebSockets . Dukungan pada dasarnya diterapkan di setiap browser utama .

Bahkan PubNub menggunakannya. Untuk aplikasi Anda, browser mungkin akan berlangganan soket yang akan disiarkan setiap kali foto baru tersedia. Soket tidak akan mengirim foto, ingatlah, tetapi hanya sebuah tautan sehingga browser dapat mengunduhnya secara tidak sinkron.

Dalam contoh Anda bayangkan sesuatu seperti:

  1. Pengguna membuat fotografer tahu bahwa ia ingin tahu tentang semua foto di masa depan
  2. Fotografer mengatakan melalui pengeras suara bahwa foto baru tersedia
  3. Pengguna meminta fotografer untuk foto

Ini agak seperti solusi contoh asli Anda. Ini lebih efisien daripada polling karena klien tidak perlu mengirim data apa pun ke server (kecuali mungkin detak jantung .)

Juga, seperti yang disebutkan orang lain, ada metode lain yang lebih baik daripada polling sederhana yang bekerja di browser lama ( longpolling, et al .)

korylprince
sumber
43
@RobertHarvey kenapa WebSockets tidak terkait dengan pertanyaan? Pertanyaannya menanyakan apakah pemungutan suara adalah strategi yang dapat diterima, dan saat ini jelas tidak dapat diterima (atau setidaknya tidak optimal). WebSockets, peristiwa yang dikirim oleh Server dan polling panjang memiliki kinerja yang jauh lebih baik di hampir setiap kasus penggunaan tunggal.
Fabrício Matté
7
@RobertHarvey itu hanya interpretasi saya, tidak membingkai ulang sejauh yang saya bisa lihat. Tentu, pertanyaan yang diajukan mengapa masih diterima dan bukan apa strategi yang optimal , tetapi ini masih terkait erat.
Fabrício Matté
25
WebSockets (dan sejenisnya) adalah yang paling dekat yang bisa Anda dapatkan untuk mengimplementasikan "solusi" OP, jadi saya pikir ini sangat relevan meskipun dia tidak menyebutkannya secara khusus.
korylprince
6
Belum lagi, StackExchangesitus-situs seperti yang Anda gunakan saat ini (kecuali jika Anda melihat halaman web ini di-cache / disimpan) gunakan WebSockets. Ini sebabnya saya juga bertanya-tanya mengapa tidak ada yang sampai @korylprince disebutkan WebSockets.
trysis
6
@ FabrícioMatté: sebenarnya, tidak setiap kasus penggunaan. Polling panjang membutuhkan menjaga soket terbuka untuk setiap pengguna yang membutuhkan sumber daya sistem. Layanan Fr yang tidak terlalu kritis waktu tetapi memiliki banyak pengguna, menjaga soket terbuka biasanya lebih mahal daripada melayani 304 pendek sesekali. Untuk sebagian besar layanan, sedikit keterlambatan bukanlah masalah. Satu mesin biasanya dapat melayani lebih banyak klien dengan polling daripada dengan push.
Lie Ryan
42

Terkadang cukup baik cukup baik.

Dari semua cara yang mungkin untuk menerapkan proses komunikasi "waktu nyata", pemungutan suara mungkin merupakan cara paling sederhana. Polling dapat digunakan secara efektif ketika interval polling relatif panjang (yaitu detik, menit atau jam daripada sesaat), dan siklus jam dikonsumsi dengan memeriksa koneksi atau sumber daya tidak terlalu penting.

Robert Harvey
sumber
3
Ini, seribu kali ini. Itu diterima karena biasanya cukup baik.
corsiKa
1
Itu jawaban yang cukup bagus
Zain R
31

Protokol HTTP terbatas karena klien HARUS yang memulai permintaan. Server tidak dapat berkomunikasi dengan klien kecuali menanggapi permintaan klien.

Jadi, untuk menyesuaikan contoh dunia nyata Anda, tambahkan pengekangan berikut:

  • Pengguna 2 HANYA dapat menjawab pertanyaan Pengguna 1 dengan satu kalimat balasan, setelah itu Pengguna 1 harus pergi. Pengguna 2 tidak memiliki cara lain untuk berkomunikasi.

Dengan pengekangan baru ini, bagaimana Anda melakukannya selain polling?

riwalk
sumber
6
HTTP 2.0 akan mendukung dorongan server. "Mendorong memungkinkan server untuk mengirim representasi ke klien tanpa permintaan eksplisit dibuat." en.wikipedia.org/wiki/HTTP_2.0
kaptan
5
@ Kapaptan, itu bagus, tapi itu tidak tersedia. Lakukan apa yang Anda punya.
riwalk
7
Ada juga polling panjang yang tersedia saat ini dan mensimulasikan model push menggunakan tarikan.
Tim B
24
@dennis: Setelah menulis perangkat lunak otomasi industri saya hanya ingin mengomentari polling Anda tentang contoh sensor. Sensor polling melayani dua tujuan - yang paling jelas adalah untuk mengambil data baru. Yang kurang jelas adalah untuk mendeteksi bahwa sensor masih hidup, tidak jatuh karena bug atau terbakar karena kebakaran pabrik atau meleleh karena kecelakaan industri. Diam, fakta bahwa Anda tidak menerima balasan, juga merupakan data yang berharga.
slebetman
3
@dennis Sensor sering kali merasakan jauh lebih cepat daripada minat Anda pada data. Polling memungkinkan Anda untuk mendapatkan nilai sensor tepat saat Anda menginginkannya, tanpa dibanjiri dengan pembaruan yang tidak Anda pedulikan. (Bayangkan jika OS memberi tahu aplikasi Anda setiap kali file berubah di mana saja pada disk, alih-alih aplikasi Anda perlu membuka dan membaca file)
immibis
13

Mengapa pemungutan suara diterima? Karena pada kenyataannya setiap solusi sebenarnya adalah pemungutan suara tingkat rendah!

Jika server harus memperbarui Anda segera setelah gambar baru tersedia, biasanya harus memiliki koneksi ke Anda - karena alamat IP sering berubah dan Anda tidak pernah tahu jika seseorang tidak tertarik lagi, sehingga klien harus mengirim beberapa bentuk sinyal tetap-hidup, misalnya, "Aku masih di sini, aku tidak offline"

Semua koneksi stateful (misalnya, TCP / IP) bekerja sama, karena Anda hanya dapat mengirim paket data tunggal melalui Internet; Anda tidak pernah tahu apakah pihak lain masih ada di sana.

Jadi setiap protokol memiliki batas waktu. Jika suatu entitas tidak menjawab dalam X detik, itu dianggap sudah mati. Jadi, bahkan jika Anda hanya memiliki koneksi terbuka antara server dan klien, tanpa mengirim data apa pun, server dan klien harus mengirim paket tetap-hidup (ini ditangani tingkat rendah jika Anda membuka koneksi di antara mereka) - dan bagaimana ini pada akhirnya berbeda dengan polling?

Jadi pendekatan terbaik mungkin adalah longpolling:

Klien mengirim permintaan segera setelah memuat situs (misalnya, memberi tahu fotografer "Beri tahu saya jika ada gambar baru"), tetapi server tidak menjawab jika tidak ada gambar baru. Segera setelah permintaan habis, klien bertanya lagi.

Jika server sekarang memiliki gambar-gambar baru, ia dapat langsung menjawab semua klien yang mengantre untuk foto-foto baru. Jadi waktu reaksi Anda setelah gambar baru bahkan lebih pendek daripada dengan push, karena klien masih menunggu koneksi terbuka untuk balasan dan Anda tidak perlu membangun koneksi ke klien. Dan permintaan polling dari klien tidak lebih banyak lalu lintas daripada koneksi konstan antara klien dan server untuk jawaban!

Falco
sumber
Saya tidak setuju bahwa setiap solusi akhirnya menjadi jajak pendapat tingkat rendah. Anda membingungkan, polling yang diperlukan untuk mengirim data dengan polling, diperlukan untuk mengetahui kapan klien hilang. Ya, yang terakhir akan selalu berakhir polling di suatu tempat di tumpukan protokol, tapi itu bisa pada frekuensi yang sangat rendah (seperti setiap lima menit sekali) sedangkan polling untuk data aktual setiap detik adalah pemborosan yang BISA dihindari dengan pemberitahuan push yang sebenarnya yang TIDAK polling di tingkat mana pun dari tumpukan.
Allon Guralnek
Paket keepalive pertama berjalan pada frekuensi yang cukup tinggi, karena Anda ingin menghindari interval waktu habis yang sama sehingga hanya beberapa detik yang tidak biasa untuk TCP / IP dan hampir semua hal yang tidak menggunakan tcp dapat diblokir oleh firewall. Jadi ketika saya perlu mengirim paket data setiap X detik, mengapa tidak mengisinya dengan beberapa data tanpa biaya?
Falco
1
@Guralnek bahkan jika Anda memiliki koneksi dengan interval tetap 5 menit, batas waktu akan lebih tinggi, karena Anda harus menambahkan paket aktual yang tertunda dan hilang. Dan server akan menyimpan banyak koneksi selama 5 menit setelah klien terputus, sehingga secara keseluruhan ini kemungkinan akan menghabiskan lebih banyak sumber daya server dengan hanya menghemat bandwidth minimal
Falco
1
+1 untuk pemungutan suara panjang. Cari Komet en.wikipedia.org/wiki/Comet_%28programming%29
Zan Lynx
9

Satu keuntungan dari pemungutan suara adalah bahwa itu membatasi kerugian yang dapat disebabkan jika pesan hilang atau keadaan sesuatu menjadi terganggu. Jika X meminta statusnya Y setiap lima detik, maka hilangnya permintaan atau balasan hanya akan mengakibatkan informasi X menjadi sepuluh detik kedaluwarsa daripada 5. Jika Y dibooting ulang, X dapat mengetahuinya selanjutnya waktu Y dapat menanggapi salah satu pesan X. Jika X di-reboot, mungkin tidak pernah repot meminta Y untuk apa pun sesudahnya, tetapi siapa pun yang mengamati status X harus mengakui bahwa ia telah di-reboot.

Jika alih-alih X polling Y, X mengandalkan Y untuk menginformasikannya kapan pun negaranya berubah, maka jika status Y berubah dan mengirim pesan ke X, tetapi untuk alasan apa pun pesan itu tidak diterima, X mungkin tidak akan pernah menyadari perubahan itu. . Demikian juga jika Y di-boot ulang dan tidak pernah punya alasan untuk mengirim pesan kepada X tentang apa pun.

Dalam beberapa kasus mungkin akan membantu bagi X untuk meminta Y mengirim pesan secara otonom dengan statusnya, baik secara berkala atau ketika itu berubah, dan hanya memiliki polling X jika terlalu lama tanpa mendengar apa pun dari Y. Desain semacam itu dapat menghilangkan perlu X untuk mengirim sebagian besar pesannya (biasanya, X setidaknya harus memberi tahu Y bahwa masih tertarik untuk menerima pesan, dan Y harus berhenti mengirim pesan jika terlalu lama tanpa indikasi minat). Namun, desain seperti itu akan menuntut Y untuk terus - menerusmemelihara informasi tentang X, daripada hanya mengirim balasan kepada siapa pun yang melakukan polling dan kemudian segera melupakan siapa itu. Jika Y adalah sistem tertanam, penyederhanaan seperti itu dapat membantu mengurangi kebutuhan memori secara memadai untuk memungkinkan penggunaan pengontrol yang lebih kecil dan lebih murah.

Polling dapat memiliki keuntungan tambahan saat menggunakan media komunikasi yang berpotensi tidak dapat diandalkan (mis. UDP atau radio): sebagian besar dapat menghilangkan kebutuhan akan pengakuan lapisan-link. Jika X mengirimkan Y permintaan status Q, Y merespons dengan laporan status R, dan X mendengar R, X tidak perlu mendengar segala macam pengakuan lapisan-tautan untuk Q untuk mengetahui bahwa itu diterima. Sebaliknya, begitu Y mengirim R, tidak perlu tahu atau peduli jika X menerimanya. Jika X mengirim permintaan status dan tidak mendapat respons, itu dapat mengirim yang lain. Jika Y mengirim laporan dan X tidak mendengarnya, X akan mengirim permintaan lain. Jika setiap permintaan keluar satu kali dan menghasilkan respons atau tidak, tidak ada pihak yang perlu tahu atau peduli apakah ada pesan tertentu yang diterima. Karena mengirim pemberitahuan dapat menggunakan bandwidth hampir sebanyak permintaan status atau laporan, menggunakan round-trip dari request-report tidak membutuhkan biaya lebih banyak daripada laporan dan pengakuan yang tidak diminta Jika X mengirim beberapa permintaan tanpa mendapat balasan, mungkin pada beberapa jaringan yang dialihkan secara dinamis perlu mengaktifkan pengakuan tingkat tautan (dan meminta dalam permintaannya bahwa Y juga melakukan hal yang sama) sehingga tumpukan protokol yang mendasarinya dapat mengenali masalah pengiriman dan mencari rute baru, tetapi ketika hal-hal bekerja, model laporan permintaan akan lebih efisien daripada menggunakan pengakuan tingkat tautan.

supercat
sumber
Masalah yang Anda bicarakan dengan Y mendorong pesan ke X (paragraf kedua) dapat diatasi dengan memasang nomor seri pada setiap pesan. Jika pesan hilang, X akan tahu karena tidak menerima serial itu. Pada titik itu dapat mengambil langkah-langkah lain untuk menyinkronkan dengan Y. DNS master -> replikasi budak bekerja dengan cara ini.
korylprince
@korylprince: Kedua belah pihak dapat mengetahui tentang pesan yang hilang jika pihak lain memiliki kesempatan untuk mengirim sesuatu (dan melakukannya dengan sukses), atau jika ada alasan untuk mengharapkan sesuatu dari pihak lain dan tidak pernah menerimanya. Jika satu sisi mengirim pembaruan status dan tidak memerlukan pengakuan atau menyerah setelah mencoba lagi beberapa kali, dan sisi lain tidak mengharapkan transmisi terjadwal, sisi lain tidak akan tahu bahwa koneksi telah menghilang.
supercat
2
@korylprince - Masalahnya adalah, tanpa pesan berkala, X dapat mendeteksi pesan yang hilang satu hari terlambat atau setahun terlambat atau 10 tahun terlambat. Untuk mendeteksi paket yang hilang dalam waktu yang wajar, Anda perlu melakukan polling. Anda dapat "menarik" polling atau Anda dapat "mendorong" polling. Yang pertama disebut "polling" yang kedua disebut "detak jantung"
slebetman
Keduanya sangat benar. Semua tergantung pada situasinya.
korylprince
@slebetman: Tanpa pesan secara periodik, jika Y akan reboot, mungkin tidak ada mekanisme yang X akan pernah menemukannya.
supercat
1

Pertanyaannya adalah untuk menyeimbangkan jumlah polling yang tidak perlu vs jumlah push yang tidak perlu.

Jika Anda polling:

  • Anda mendapatkan jawaban pada saat ini. Bagus jika Anda hanya bertanya sesekali atau membutuhkan data yang mengatur momen ini.
  • Anda mungkin mendapatkan jawaban "tidak ada konten", yang menyebabkan beban tidak berguna di telepon.
  • Anda menempatkan beban pada garis hanya saat Anda polling, tetapi selalu ketika Anda polling.

Jika Anda menekan:

  • Anda memberikan jawaban tepat saat tersedia, yang memungkinkan pemrosesan langsung di sisi klien.
  • Anda mungkin mengirimkan data ke klien yang tidak tertarik dengan data ini, menyebabkan beban tanpa titik di telepon.
  • Anda menempatkan beban di telepon setiap kali ada data baru, tetapi hanya ketika ada data baru.

Ada beberapa solusi tentang bagaimana menangani berbagai skenario dan kerugiannya, seperti misalnya waktu minimum antara jajak pendapat, proksi hanya-jajak pendapat untuk mengambil beban dari sistem utama, atau - untuk dorongan - peraturan untuk mendaftar dan menentukan data yang diinginkan diikuti dengan tidak mendaftar saat log-off. Yang mana yang paling cocok yang bisa Anda katakan secara umum, itu tergantung pada sistem.

Dalam contoh Anda, pemungutan suara bukanlah solusi yang paling efisien, tetapi yang paling praktis. Sangat mudah untuk menulis sistem pemungutan suara dalam JavaScript, dan sangat mudah untuk mengimplementasikannya di sisi pengiriman juga. Server yang dibuat untuk mengirimkan data gambar harus dapat menangani permintaan tambahan, dan jika tidak, dapat ditingkatkan secara linear, karena sebagian besar data statis dan karenanya dapat dengan mudah di-cache.

Metode push yang menerapkan log-in, deskripsi data yang diinginkan dan akhirnya log-off akan menjadi paling efisien, tetapi mungkin terlalu kompleks untuk "script-kiddy" rata-rata, dan perlu menangani pertanyaan: bagaimana jika pengguna cukup matikan browser dan log-off tidak dapat dilakukan?

Mungkin lebih baik memiliki lebih banyak pengguna (karena mengaksesnya mudah) daripada menyimpan beberapa dolar pada server cache lain?

Dua
sumber
1

Untuk beberapa alasan, hari ini, semua pengembang web yang lebih muda tampaknya telah melupakan pelajaran dari masa lalu, dan mengapa beberapa hal telah berevolusi seperti yang mereka lakukan.

  1. Bandwidth adalah masalah
  2. Koneksi mungkin terputus-putus.
  3. Browser tidak memiliki banyak kekuatan komputasi
  4. Ada metode lain untuk mengakses konten. Web bukan w3.

Dalam menghadapi kendala ini, Anda mungkin tidak memiliki komunikasi 2 arah yang konstan. Dan jika Anda melihat pada model OSI, Anda akan menemukan sebagian besar pertimbangan dimaksudkan untuk memisahkan ketekunan dengan koneksi yang mendasarinya.

Dengan mengingat hal itu, metode pemungutan suara untuk menarik informasi adalah cara yang bagus untuk mengurangi bandwidth dan perhitungan di sisi klien. Munculnya dorongan benar-benar sebagian besar hanya klien melakukan polling konstan, atau soket web. Secara pribadi, jika saya adalah orang lain di luar sana, saya akan menghargai keteraturan pemungutan suara sebagai sarana analisis lalu lintas, di mana permintaan GET / POST yang tidak ada waktu akan memberi sinyal kepada seseorang di tengah situasi semacam itu.

akun tamu
sumber