Вопрос

Недавно я слышал, как несколько разработчиков говорили, что они просто опрашивают данные (базы данных, файлы и т.д.), Чтобы определить, когда что-то изменилось, а затем запускают задачу, такую как импорт.

Я действительно против этой идеи и считаю, что использование доступных технологий, таких как Удаленное управление, WCF, и т.д.это было бы намного лучше, чем опрос.

Тем не менее, я хотел бы определить причины, по которым другие люди предпочитают один подход другому, и, что более важно, как я могу убедить других в том, что опрос является неправильным в наши дни?

Это было полезно?

Решение

Опрос не является "неправильным" как таковым.

Многое зависит от того, как это реализовано и с какой целью.Если вы действительно заботитесь о немедленном уведомлении об изменениях, это очень эффективно.Ваш код находится в замкнутом цикле, постоянно опрашивая (спрашивая) ресурс, изменился ли он / обновлен.Это означает, что вы будете уведомлены, как только сможете, о том, что что-то изменилось.Но ваш код больше ничего не делает, и возникают накладные расходы в виде множества вызовов рассматриваемого объекта.

Если вас меньше заботит немедленное уведомление, вы можете увеличить интервал между опросами, и это тоже может хорошо работать, но выбрать правильный интервал может быть непросто.Слишком длинный - и вы можете пропустить важные изменения, слишком короткий - и вы вернетесь к проблемам первого метода.

Альтернативы, такие как прерывания, сообщения и т.д.может обеспечить лучший компромисс в таких ситуациях.Вы получаете уведомление об изменении как можно скорее, но эту задержку вы не контролируете, она зависит от того, своевременно ли сам компонент передает изменения в состоянии.

Что "не так" с опросом?

  • Это может быть перерасход ресурсов.
  • Это может быть ограничивающим (особенно если у вас есть много вещей, о которых вы хотите узнать / опрос).
  • Это может быть излишеством.

Но...

  • По своей сути это не является неправильным.
  • Это может быть очень эффективно.
  • Это очень просто.

Другие советы

Есть две причины, по которым опрос можно считать принципиально плохим.

  1. Это пустая трата ресурсов.Весьма вероятно, что вы будете проверять наличие изменений, хотя никаких изменений не произошло.Циклы процессора / пропускная способность, затрачиваемые на это действие, не приводят к изменению и, следовательно, могли бы быть лучше потрачены на что-то другое.

  2. Опрос проводится с определенным интервалом.Это означает, что вы не будете знать о том, что произошло изменение, до тех пор, пока не истечет следующий интервал.

Было бы лучше получать уведомления об изменениях.Таким образом, вы не проводите опрос на предмет изменений, которые еще не произошли, и узнаете об изменении, как только получите уведомление.

Примеры того, что использует опрос в наши дни:

  • Почтовые клиенты опрашивают наличие новых сообщений (даже с IMAP).
  • Читатели RSS опрашивают об изменениях в лентах.
  • Поисковые системы опрашивают об изменениях на страницах, которые они индексируют.
  • Пользователи StackOverflow проводят опрос на наличие новых вопросов, нажав "обновить" ;-)
  • Клиенты Bittorrent опрашивают трекер (и друг друга, я думаю, с помощью DHT) на предмет изменений в рое.
  • Спин-блокировки в многоядерных системах могут быть наиболее эффективной синхронизацией между ядрами в случаях, когда задержка слишком мала, чтобы было время запланировать другой поток на этом ядре, прежде чем другое ядро сделает то, чего мы ждем.

Иногда просто нет никакого способа получать асинхронные уведомления:например, чтобы заменить RSS на push-систему, сервер должен был бы знать обо всех, кто читает ленту, и иметь способ связаться с ними.Это список рассылки - как раз одна из тех вещей, которых RSS был разработан, чтобы избежать.Отсюда тот факт, что большинство моих примеров - это сетевые приложения, где это, скорее всего, будет проблемой.

В других случаях опрос достаточно дешев, чтобы работать даже при наличии асинхронного уведомления.

Для локального файла уведомление об изменениях, вероятно, в принципе будет лучшим вариантом.Например, вы могли бы предотвратить остановку вращения диска, если вы постоянно нажимаете на него, хотя, опять же, ОС может кэшироваться.И если вы проводите ежесекундный опрос файла, который меняется только раз в час, возможно, вы напрасно занимаете 0,001% (или что-то еще) вычислительной мощности вашего компьютера.Это звучит незначительно, но что произойдет, когда вам нужно будет опросить 100 000 файлов?

Однако на практике накладные расходы, вероятно, будут незначительными, что бы вы ни делали, что затрудняет процесс изменения кода, который работает в данный момент.Лучше всего следить за конкретными проблемами, которые вызывает опрос в системе, которую вы хотите изменить, - если вы обнаружите таковые, то поднимите их, а не пытайтесь привести общий аргумент против всех опросов.Если вы ничего не найдете, то не сможете починить то, что не сломано...

Опрос прост в выполнении, очень прост, он такой же простой, как любой процедурный код.Отказ от опроса означает, что вы вступаете в мир асинхронного программирования, что не так просто, а временами может даже стать сложной задачей.

И, как и во всем в любой системе, обычно чаще выбирают путь меньшего сопротивления, поэтому всегда найдутся программисты, использующие опрос, даже отличные программисты, потому что иногда нет необходимости усложнять ситуацию асинхронными шаблонами.

Я, например, всегда стараюсь избегать опроса, но иногда я все равно провожу опрос, особенно когда фактический выигрыш от асинхронной обработки не так уж велик, например, при работе с некоторыми небольшими локальными данными (конечно, вы получаете немного быстрее, но пользователи не заметят разницы в подобном случае).Так что, ИМХО, есть место для обеих методологий.

Опрос клиента масштабируется не так хорошо, как уведомления сервера.Представьте себе тысячи клиентов, спрашивающих сервер "есть какие-нибудь новые данные?" каждые 5 секунд.Теперь представьте, что сервер ведет список клиентов для уведомления о новых данных.Уведомления сервера масштабируются лучше.

Я думаю, люди должны понимать, что в большинстве случаев на каком-то уровне выполняется опрос, даже в ситуациях, связанных с событиями или прерываниями, но вы изолированы от фактического кода, выполняющего опрос.Действительно, это самая желанная ситуация...изолируйте себя от реализации и просто разберитесь с событием.Даже если вы должны реализовать опрос самостоятельно, напишите код так, чтобы он был изолированным, а результаты обрабатывались независимо от реализации.

Его простой опрос плох - неэффективен, пустая трата ресурсов и т.д.Всегда существует какая-то форма подключения, которая в любом случае отслеживает какое-либо событие, даже если "опрос" не выбран.

Так зачем же стараться изо всех сил и проводить дополнительные опросы?

Обратные вызовы - лучший вариант - просто нужно побеспокоиться о том, чтобы связать обратный вызов с вашим текущим процессом.Кроме того, продолжается опрос, чтобы убедиться, что соединение все еще на месте, так или иначе.

Если ты продолжаешь звонить своей девушке, а она никогда не отвечает, тогда зачем продолжать звонить?Просто оставьте сообщение и подождите, пока она "перезвонит" ;)

Я иногда использую опрос для определенных ситуаций (например, в игре я бы опрашивал состояние клавиатуры в каждом кадре), но никогда в цикле, который выполняет ТОЛЬКО опрос, скорее я бы проводил опрос как проверку (изменился ли ресурс X?Если да, сделайте что-нибудь, в противном случае обработайте что-нибудь еще и проверьте еще раз позже).Однако, вообще говоря, я избегаю опроса в пользу асинхронных уведомлений.

Причины в том, что я не трачу ресурсы (процессорное время, что угодно) на ожидание того, что что-то произойдет (особенно если эти ресурсы могли бы ускорить это в первую очередь).В случаях, когда я использую опрос, я не сижу сложа руки в ожидании, я использую ресурсы в другом месте, так что это не проблема (по крайней мере, для меня).

Если вы проводите опрос на предмет изменений в файле, то я согласен с тем, что вам следует использовать уведомления файловой системы о том, когда это произойдет, которые сейчас доступны в большинстве операционных систем.

В базе данных вы могли бы запустить обновление / вставку, а затем вызвать свой внешний код, чтобы что-то сделать.Однако, возможно, у вас просто нет требований к мгновенным действиям.Например, вам может потребоваться только передать данные из базы данных A в базу данных B по другой сети в течение 15 минут.База данных B может быть недоступна из базы данных A, поэтому в конечном итоге вы выполняете опрос из базы данных B. Или как автономная программа, работающая рядом с базой данных B.

Кроме того, опрос - это очень простая в программировании вещь.Часто это первый шаг реализации, выполняемый при небольших временных ограничениях, и поскольку он работает достаточно хорошо, он остается.

Особенность опроса в том, что он работает!Он надежен и прост в реализации.

Затраты на объединение могут быть высокими - если вы сканируете базу данных на предмет изменений каждую минуту, когда происходит всего два изменения в день, вы потребляете много ресурсов для получения очень небольшого результата.

Однако проблема с любой технологией уведомлений заключается в том, что они намного сложнее в реализации и не только могут быть ненадежными, но и (и это большое "НО") вы не можете легко определить, когда они не работают.

Поэтому, если вы откажетесь от опроса по какой-либо другой технологии, убедитесь, что она пригодна для использования средними программистами и является сверхнадежной.

Я вижу здесь много ответов, но я думаю, что самый простой ответ - это ответ сам по себе:

Потому что (обычно) гораздо проще закодировать цикл опроса, чем создавать инфраструктуру для обратных вызовов.

Затем вы получаете более простой код, который, если позже он окажется узким местом, может быть легко понят и переработан / реорганизован во что-то другое.

Это не ответ на ваш вопрос.Но на самом деле, особенно в наше время, когда процессорные циклы дешевы, а пропускная способность велика, опрос на самом деле является довольно хорошим решением для некоторых задач.

Преимущества заключаются в следующем:

  • Дешево
  • Надежный
  • Поддающийся проверке
  • Гибкий

Я согласен, что избегать опросов - хорошая политика.Однако, ссылаясь на Пост Роберта, Я бы сказал, что простота опроса может сделать его лучшим подходом в случаях, когда упомянутые здесь проблемы не являются такой уж большой проблемой, поскольку асинхронный подход часто значительно менее удобочитаем и его сложнее поддерживать, не говоря уже об ошибках, которые могут вкрасться в его реализацию.

Как и во всем остальном, это зависит от обстоятельств.Большая система с высоким уровнем транзакций, над которой я работаю, в настоящее время использует уведомление с SQL (библиотека DLL, загруженная в SQL Server, которая вызывается расширенным SP из триггеров в определенных таблицах.Затем библиотека DLL уведомляет другие приложения о том, что есть над чем поработать).

Однако мы отходим от этого, потому что можем практически гарантировать, что работа будет вестись непрерывно.Поэтому, чтобы снизить сложность и фактически немного ускорить процесс, приложения будут обрабатывать свою работу и немедленно снова опрашивать базу данных на предмет новой работы.Если таковых не будет, он повторит попытку через небольшой промежуток времени.

Кажется, это работает быстрее и намного проще.Однако другая часть приложения, которая имеет гораздо меньший объем, не выигрывает от увеличения скорости при использовании этого метода - если только интервал опроса не очень мал, что приводит к проблемам с производительностью.Поэтому в этой части мы оставляем все как есть.Поэтому это хорошо, когда это уместно, но потребности у всех разные.

Вот хорошее резюме относительных достоинств push и pull: https://stpeter.im/index.php/2007/12/14/push-and-pull-in-application-architectures/

Я хотел бы обобщить это подробнее в этом ответе, но некоторые вещи лучше оставить без сокращений.

Когда вы думаете о SQL-опросе, еще во времена VB6 вы могли создавать наборы записей, используя ключевое слово WithEvents, которое было ранним воплощением асинхронного "прослушивания".

Лично я всегда искал бы способ использования реализации, управляемой событиями, перед опросом.В противном случае может помочь ручная реализация любого из следующих действий:

  • sql service broker / класс зависимостей
  • Какая-то технология очередей (RabbitMQ или аналогичная)
  • UDP-трансляция - интересный метод, который может быть создан с использованием нескольких прослушивателей узлов.Однако в некоторых сетях это не всегда возможно.

Некоторые из них могут потребовать небольшого изменения дизайна вашего проекта, но в корпоративном мире это может быть лучшим вариантом, чем служба опроса.

Согласен с большинством ответов, что асинхронность / обмен сообщениями обычно лучше.Я абсолютно согласен с ответом Роберта Гулда.Но я хотел бы добавить еще один момент.

Одним из дополнений является то, что опрос может убить двух зайцев одним выстрелом.В одном конкретном случае использования проект, в котором я участвовал, использовал очередь сообщений между базами данных, но опрашивал сервер приложений одну из баз данных.Поскольку сеть от сервера приложений к базе данных время от времени отключалась, опрос дополнительно использовался для уведомления приложения о проблемах с сетью.

В конце концов, используйте то, что делает самый здравый смысл для варианта использования с учетом возможности масштабирования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top