c# - ¿Qué pasa con las encuestas?
.net asp.net (17)
He escuchado a algunos desarrolladores decir recientemente que simplemente están sondeando cosas (bases de datos, archivos, etc.) para determinar cuándo algo ha cambiado y luego ejecutar una tarea, como una importación.
Estoy realmente en contra de esta idea y creo que utilizar tecnología disponible como Remoting , WCF , etc. sería mucho mejor que la votación.
Sin embargo, me gustaría identificar las razones por las que otras personas prefieren un enfoque sobre el otro y, lo que es más importante, ¿cómo puedo convencer a los demás de que las encuestas son incorrectas hoy en día?
¡Lo que pasa con las encuestas es que funciona! Es confiable y simple de implementar.
Los costos de la puesta en común pueden ser altos: si está escaneando una base de datos para ver los cambios cada minuto cuando solo hay dos cambios al día, está consumiendo una gran cantidad de recursos para obtener un resultado muy pequeño.
Sin embargo, el problema con cualquier tecnología de notificación es que son mucho más complejos de implementar y no solo pueden no ser confiables sino que (y esto es un gran PERO) no se puede saber fácilmente cuando no están funcionando.
Por lo tanto, si cancela el sondeo para otra tecnología, asegúrese de que sea utilizable por los programadores promedio y sea extremadamente confiable.
Como con todo, depende. Un gran sistema de alta transacción en el que trabajo actualmente usa una notificación con SQL (una DLL cargada dentro de SQL Server a la que un SP extendido llama desde disparadores en ciertas tablas. La DLL luego notifica a otras aplicaciones que hay trabajo por hacer).
Sin embargo, nos estamos alejando de esto porque prácticamente podemos garantizar que habrá trabajo para hacer continuamente. Por lo tanto, para reducir la complejidad y acelerar un poco las cosas, las aplicaciones procesarán su trabajo y volverán a sondear el DB de nuevo para un nuevo trabajo. Si no hay ninguno lo intentará de nuevo después de un pequeño intervalo.
Esto parece funcionar más rápido y es mucho más simple. Sin embargo, otra parte de la aplicación que tiene un volumen mucho más bajo no se beneficia de un aumento de velocidad con este método, a menos que el intervalo de sondeo sea muy pequeño, lo que conduce a problemas de rendimiento. Así que lo dejamos como está para esta parte. Por lo tanto, es bueno cuando es apropiado, pero las necesidades de todos son diferentes.
Creo que la gente debería darse cuenta de que, en la mayoría de los casos, en algún nivel se están realizando encuestas, incluso en situaciones de evento o interrupción, pero estás aislado del código real que realiza el sondeo. Realmente, esta es la situación más deseable ... aislarse de la implementación y simplemente tratar con el evento. Incluso si debe implementar la encuesta usted mismo, escriba el código para que esté aislado y los resultados se resuelvan independientemente de la implementación.
El sondeo es fácil de hacer, muy fácil, es tan fácil como cualquier código de procedimiento. No sondear significa que ingresas al mundo de la programación asincrónica, que no es tan fácil como un cerebro muerto, e incluso puede llegar a ser desafiante a veces.
Y como con todo en cualquier sistema, la ruta de menor resistencia normalmente se toma con mayor frecuencia, por lo que siempre habrá programadores que utilizarán encuestas, incluso grandes programadores, porque a veces no hay necesidad de complicar las cosas con patrones asincrónicos.
Por mi parte siempre prospero para evitar el sondeo, pero a veces realizo encuestas de todos modos, especialmente cuando las ganancias reales del manejo asincrónico no son tan buenas, como cuando se actúa en contra de algunos datos locales pequeños (por supuesto, se obtiene un poco más rápido, pero los usuarios no notará la diferencia en un caso como este). Así que hay espacio para ambas metodologías en mi humilde opinión.
Es simple: el sondeo es malo, ineficiente, desperdicio de recursos, etc. Siempre hay alguna forma de conectividad que monitorea un evento de algún tipo, incluso si no se elige "votación".
Entonces, ¿por qué hacer un esfuerzo adicional y poner encuestas adicionales en su lugar?
Las retrollamadas son la mejor opción; solo tiene que preocuparse por vincular la devolución de llamada con su proceso actual. Subyacente, hay encuestas para ver que la conexión todavía está en su lugar de todos modos.
Si sigues llamando / llamando a tu novia y ella nunca responde, ¿por qué seguir llamando? Solo deja un mensaje y espera hasta que ella ''vuelva a llamar'';)
Esto no responde tu pregunta. Pero de forma realista, especialmente en este "día y edad" donde los ciclos de los procesadores son baratos y el ancho de banda es grande, las encuestas son en realidad una solución bastante buena para algunas tareas.
Los beneficios son:
- Barato
- De confianza
- Testable
- Flexible
Hay dos razones por las cuales las encuestas pueden considerarse malas por principio.
Es un desperdicio de recursos. Es muy probable que verifique un cambio mientras no haya ocurrido ningún cambio. La duración de los ciclos de CPU / ancho de banda en esta acción no da como resultado un cambio y, por lo tanto, podría haberse gastado mejor en otra cosa.
El sondeo se realiza en un determinado intervalo. Esto significa que no sabrá que se ha producido un cambio hasta la próxima vez que pase el intervalo.
Sería mejor ser notificado de los cambios. De esta forma, no está buscando cambios que no se han producido y sabrá de un cambio tan pronto como reciba la notificación.
Si está buscando cambios en un archivo, acepto que debe usar las notificaciones del sistema de archivos que están disponibles para cuando esto sucede, que ahora están disponibles en la mayoría de los sistemas operativos.
En una base de datos, puede activar la actualización / inserción y luego llamar a su código externo para hacer algo. Sin embargo, puede ser que no tenga un requisito para acciones instantáneas. Por ejemplo, puede que solo necesite obtener datos de la Base de datos A en la Base de datos B en una red diferente en 15 minutos. Puede que no se pueda acceder a la base de datos B desde la base de datos A, por lo que terminará realizando el sondeo desde, o como un programa independiente que se ejecuta cerca de la base de datos B.
Además, el sondeo es algo muy simple de programar. A menudo es una implementación de primer paso realizada cuando las restricciones de tiempo son cortas, y debido a que funciona lo suficientemente bien, se mantiene.
Veo muchas respuestas aquí, pero creo que la respuesta más simple es la respuesta en sí:
Porque (normalmente) es mucho más simple codificar un ciclo de sondeo que crear la infraestructura para las devoluciones de llamada.
Luego, obtienes un código más simple que, si resulta ser un cuello de botella más tarde, puede ser fácilmente entendido y rediseñado / refactorizado en otra cosa.
El sondeo de clientes no se escala tan bien como las notificaciones del servidor. Imagine que miles de clientes le preguntan al servidor "¿Datos nuevos?" cada 5 segundos. Ahora imagine que el servidor mantiene una lista de clientes para notificar nuevos datos. La notificación del servidor se escala mejor.
Aquí hay un buen resumen de los méritos relativos de tirar y tirar: https://stpeter.im/index.php/2007/12/14/push-and-pull-in-application-architectures/
Desearía poder resumirlo más en esta respuesta, pero es mejor dejar algunas cosas sin resolver.
El sondeo no es "incorrecto" como tal.
Mucho depende de cómo se implementa y con qué propósito. Si realmente te preocupa la notificación inmediata de un cambio, es muy eficiente. Su código se encuentra en un círculo cerrado, constantemente sondeando (preguntando) a un recurso si ha cambiado / actualizado. Esto significa que se le notificará tan pronto como sea posible que algo es diferente. Pero su código no está haciendo otra cosa y hay una sobrecarga en términos de muchas llamadas al objeto en cuestión.
Si le preocupa menos la notificación inmediata, puede aumentar el intervalo entre las encuestas, y esto también puede funcionar bien, pero elegir el intervalo correcto puede ser difícil. Demasiado tiempo y es posible que te pierdas los cambios críticos, demasiado cortos y vuelvas a los problemas del primer método.
Las alternativas, como interrupciones o mensajes, etc. pueden proporcionar un mejor compromiso en estas situaciones. Se le notifica un cambio tan pronto como sea prácticamente posible, pero esta demora no es algo que usted controle, sino que depende de que el componente sea oportuna para transmitir los cambios de estado.
¿Qué está "mal" con las encuestas?
- Puede ser acaparamiento de recursos.
- Puede ser limitante (especialmente si tiene muchas cosas que desea saber sobre / encuesta).
- Puede ser excesivo.
Pero...
- No es intrínsecamente incorrecto.
- Puede ser muy efectivo.
- Es muy simple.
Utilizo el sondeo de vez en cuando para ciertas situaciones (por ejemplo, en un juego, sondearía el estado del teclado en cada fotograma), pero nunca en un bucle que SÓLO hace el sondeo, en vez de eso, lo haría como un control (¿ha cambiado el recurso X? sí, haz algo, de lo contrario procesa otra cosa y vuelve a verificar más tarde). En términos generales, evito las encuestas a favor de las notificaciones asincrónicas.
Las razones son que no gasto recursos (tiempo de CPU, lo que sea) esperando que ocurra algo (especialmente si esos recursos podrían acelerar esa cosa en primer lugar). En los casos en los que utilizo encuestas, no me quedo esperando inactivo, utilizo los recursos en otra parte, por lo que no es un problema (para mí, al menos).
Ejemplos de cosas que usan encuestas en este día y edad:
- Los clientes de correo electrónico sondean los mensajes nuevos (incluso con IMAP).
- Los lectores de RSS sondean los cambios en los feeds.
- Los motores de búsqueda sondean los cambios en las páginas que indexan.
- Los usuarios de sondean nuevas preguntas al presionar ''actualizar'' ;-)
- Los clientes de Bittorrent sondean el rastreador (y entre ellos, creo, con DHT) por los cambios en el enjambre.
- Spinlocks en sistemas multi-core puede ser la sincronización más eficiente entre núcleos, en casos donde el retraso es demasiado corto para que haya tiempo para programar otro hilo en este núcleo, antes de que el otro núcleo haga lo que estamos esperando.
A veces simplemente no hay forma de obtener notificaciones asíncronas: por ejemplo, para reemplazar RSS con un sistema push, el servidor debería conocer a todos los que leen el feed y tener una forma de contactarlos. Esta es una lista de correo, precisamente una de las cosas que RSS fue diseñado para evitar. De ahí el hecho de que la mayoría de mis ejemplos son aplicaciones de red, donde es más probable que esto sea un problema.
Otras veces, las encuestas son lo suficientemente baratas como para funcionar incluso cuando hay una notificación asincrónica.
Para un archivo local, la notificación de cambios es probablemente la mejor opción en principio. Por ejemplo, es posible que (quizás) evite que el disco gire hacia abajo si lo golpea constantemente, aunque de nuevo el sistema operativo podría almacenar en caché. Y si está sondeando cada segundo en un archivo que solo cambia una vez por hora, puede estar ocupando innecesariamente el 0.001% (o lo que sea) de la potencia de procesamiento de su máquina. Esto suena pequeño, pero ¿qué sucede cuando hay 100.000 archivos que necesita sondear?
En la práctica, sin embargo, es probable que la sobrecarga sea insignificante, sea lo que sea que haga, lo que hace que sea difícil entusiasmarse con el cambio de código que actualmente funciona. Lo mejor es tener cuidado con los problemas específicos que el sondeo causa en el sistema que desea cambiar; si encuentra alguno, eleve los mismos en lugar de intentar hacer un argumento general contra todos los sondeos. Si no encuentras ninguno, entonces no puedes arreglar lo que no está roto ...
Al pensar en el sondeo de SQL, en el día de VB6 solía ser capaz de crear conjuntos de registros utilizando la palabra clave WithEvents, que fue una encarnación temprana de la "escucha" asíncrona.
Personalmente, siempre buscaría una forma de utilizar una implementación impulsada por eventos antes de la votación. En su defecto, una implementación manual de cualquiera de los siguientes podría ayudar:
- sql service broker / clase de dependencia
- Algún tipo de tecnología de cola (RabbitMQ o similar)
- Transmisión UDP: técnica interesante que se puede construir con múltiples oyentes de nodos. Sin embargo, no siempre es posible en algunas redes.
Algunos de estos pueden requerir un ligero rediseño de su proyecto, pero en un mundo empresarial podría ser la mejor ruta a seguir en lugar de un servicio de votación.
De acuerdo con la mayoría de las respuestas que Async / Messaging suele ser mejor. Estoy absolutamente de acuerdo con la respuesta de Robert Gould. Pero me gustaría agregar un punto más.
Una adición es que la votación puede matar dos pájaros de un tiro. En un caso de uso particular, un proyecto en el que participé utilizó una cola de mensajes entre bases de datos, pero el sondeo de un servidor de aplicaciones a una de las bases de datos. Debido a que la red desde el servidor de la aplicación a la base de datos estaba ocasionalmente inactiva, el sondeo se utilizó adicionalmente para notificar a la aplicación los problemas de la red.
Al final, use lo que tenga más sentido para el caso de uso con capacidad de escala en mente.
Estoy de acuerdo en que evitar las encuestas es una buena política. Sin embargo, en referencia a la publicación de Robert , diría que la simplicidad de las encuestas puede hacer que sea un mejor enfoque en casos donde los problemas mencionados aquí no son un problema tan grande, ya que el enfoque asincrónico a menudo es considerablemente menos legible y más difícil de mantener. sin mencionar los errores que pueden introducirse en su implementación.