Múltiples programas pequeños conectados a través de sockets versus un programa grande

8

Estoy al comienzo de un proyecto que implica leer varios sensores y fusionar los datos de esos sensores. En total, habrá 4 sensores conectados a través de USB y una cámara web, también conectados a través de USB.

Uno de mis colegas habla mucho sobre lo bueno que es dividir los programas en partes más pequeñas y hacer que se comuniquen a través de la red. Sugiere que deberíamos tener un ejecutable para cada sensor (o cámara) y luego una aplicación de control central que se comunique con los demás.

Intuitivamente no me gusta esta idea. El colega en cuestión trabajó en otro proyecto que utilizó ese enfoque y no tuvo fin de problemas que fueron difíciles de rastrear y depurar.

No parece un diseño muy completo y me parece algo poco elegante. Me gustaría escribir una biblioteca para tratar con cada sensor y tal vez ejecutarlos en hilos separados.

También debe señalarse que los cálculos que tenemos que hacer proporcionarán actualizaciones a otro sistema a casi 1000Hz. Agregar una capa de comunicaciones de red parece agregar un posible cuello de botella.

Me interesaría escuchar las opiniones de otras personas sobre esto y quizás algunas referencias sobre este tipo de práctica.

James
fuente
99
" no tenía fin de problemas que eran difíciles de rastrear y depurar ", no estoy seguro de que una solución multiproceso sea más fácil de depurar. No digo que multihilo está mal, simplemente no recuerdo haber escuchado "Usemos una solución multihilo, eso es mucho más fácil de depurar".
cdkMoose
3
Como usuario frecuente de Erlang, este "uso de la red / protocolo como la capa básica de abstracción" es a menudo mi modo predeterminado de pensar. Se hace cosas hacen más fácil de depurar (se puede probar el funcionamiento completo de forma aislada) y hace que un sistema más robusto (cámara # 1 poner algo en un estado extraño sólo puede cámara de choque con el nº 1 de manipulación de código, y nada espera más en ese código) y simplifica la adición de un sistema de supervisión. De lo contrario, es muy difícil lograr estos rasgos, pero, de nuevo, su problema podría ser realmente tan trivial que nada de esto importa.
zxq9
1
¿Cómo estás ejecutando 1000Hz en USB en primer lugar? ¿Cuáles son exactamente sus requisitos de rendimiento? ¿Considera que los enchufes se convierten en una latencia o un cuello de botella de rendimiento?
Bergi
1
¿Por qué crees que necesitas un "diseño con estado"? ¿Sus sensores no están basados ​​en eventos?
Bergi
Un programador tuvo un problema. Pensó para sí mismo: "Lo sé, lo resolveré con hilos". . Ahora tiene problemas. dos él
Toby Speight

Respuestas:

13

Intuitivamente no me gusta esta idea.

Bueno, intuitivamente, me gusta la idea de dividir los programas en partes más pequeñas. Pero si los diferentes procesos se ejecutan siempre en la misma máquina, la comunicación en red probablemente no sea la forma óptima de IPC. Para la comunicación de alta velocidad entre procesos, la memoria compartida podría ser la mejor opción. Pero sea cual sea el enfoque que elija, debe medir o al menos estimar el rendimiento antes de hacer cualquier juicio.

El colega en cuestión trabajó en otro proyecto que utilizó ese enfoque y no tuvo fin de problemas que fueron difíciles de rastrear y depurar.

Debe verificar qué tipo de problemas y dónde estaban las causas raíz. Si tuvieron problemas debido a la concurrencia, se encontrará con los mismos problemas (si no más) cuando intente una solución de subprocesos múltiples.

proporcionar actualizaciones a otro sistema a casi 1000Hz

Si eso es "alta velocidad", depende de la velocidad de las máquinas de producción y del tamaño de la operación involucrada en cada actualización. Cuando se trata de rendimiento, las sensaciones intestinales son extremadamente poco confiables, debe medir las cosas . Si su colega cree que su enfoque será lo suficientemente rápido, y usted cree que no lo hará, al menos uno de ustedes tendrá que probar o falsificar su creencia. Por ejemplo, uno de ustedes podría implementar un pequeño prototipo para simular la comunicación entre procesos y medir la velocidad. Todo lo demás está mirando en un recipiente de vidrio.

Doc Brown
fuente
9

Pueden o no ser relevantes para su aplicación, pero algunos beneficios de la solución multiproceso que no parece haber considerado son:

  • Control de permisos más detallado. Puede tener permisos separados para la cámara web y los otros sensores.
  • Más fácil de probar sensores en forma aislada.
  • Es más fácil burlarse de un sensor en tiempo de ejecución.
  • Es más fácil hacer que terceros escriban código para sus sensores sin tener que abrir su código.
  • Uso de herramientas como wireshark para la resolución de problemas, tanto durante el desarrollo como en el campo.
  • El único contexto que conozco donde "estado" se ve como un atributo positivo es cuando las partes con estado de un sistema están restringidas a un ámbito pequeño como un actor , que parece apoyar más el diseño de su colega que el suyo.
  • Es más fácil liberar un bloqueo y reiniciar el proceso de un solo sensor sin tener que reiniciar todo el sistema.
  • Puede escalar simplemente agregando hardware.
  • La comunicación de socket con la fuente y el destino en la misma máquina es relativamente eficiente.

Inconvenientes adicionales a la solución multiproceso:

  • Lidiar con la contrapresión es más complejo.
  • Si esencialmente solo pasa los datos en bruto de cada sensor sin ningún tipo de filtrado o procesamiento, acaba de cambiar la aplicación de su controlador de la lectura de un controlador USB a la lectura de un controlador de red, sin ninguna ganancia real en la abstracción.
Karl Bielefeldt
fuente
Si se usa una arquitectura en la que cada socket tiene un lado maestro y un lado esclavo y cada transmisión del maestro genera una respuesta inmediata por parte del esclavo (incluso si la respuesta "aún no está lista"), y el maestro siempre espera al esclavo respuesta, ¿sería un problema la contrapresión?
supercat
Esa sería una forma de manejarlo, @supercat. No es que la contrapresión sea inmanejable, es que mucha gente no puede explicarla por adelantado, lo que hace que el diseño se vea más simple de lo que realmente necesita ser.
Karl Bielefeldt
8

El enfoque que defiende su colega a menudo se denomina arquitectura de microservicios y está muy de moda en estos días. Tiene una serie de ventajas potenciales :

  • Escalabilidad: puede hacer que sea relativamente fácil escalar simplemente agregando máquinas adicionales / instancias de VM.
  • Robustez: con un diseño apropiado, puede hacerse tolerante a los procesos individuales de microservicios que se bloquean, pierden conectividad o dejan de estar disponibles.
  • Extensibilidad: el uso de tecnologías web estándar para interactuar entre microservicios (por lo general, solicitudes HTTP REST con respuestas Json o XML) puede hacer que sea relativamente fácil para terceros o clientes interactuar con su sistema y extenderlo para sus propias necesidades.

También tiene una serie de desventajas:

  • Rendimiento: generalmente pagará un costo de rendimiento por la comunicación entre procesos. Esto puede ser muy significativo si crea API de estilo http REST.
  • Complejidad: por lo general, necesitará una gran cantidad de código adicional para ordenar los datos entre procesos frente a simplemente pasar datos entre subprocesos en un solo proceso. También introducirá dependencias en las bibliotecas para la comunicación de red, soporte http, etc.
  • Depuración: por lo general, es más complejo depurar una aplicación compuesta por múltiples procesos de comunicación independientes en lugar de utilizar el depurador integrado de un IDE en un solo proceso.

No estoy seguro de lo que quieres decir cuando dices que el diseño "no parece un diseño muy completo". En general, "con estado" se considera una mala característica de un diseño y los microservicios "sin estado" se consideran buen diseño.

Sin embargo, dada la información sobre sus requisitos que proporciona en su publicación, creo que un diseño basado en microservicios sería excesivo para su caso de uso y los beneficios no justificarían la complejidad adicional. Los beneficios de las arquitecturas de microservicios tienden a entrar realmente en juego cuando se crean servicios web a mayor escala que otorgan una importancia superior a la escalabilidad, robustez y extensibilidad.

Los beneficios potenciales de una arquitectura de microservicios solo se obtienen con un diseño bien pensado. En mi opinión, dicha arquitectura requiere un diseño más avanzado (particularmente cuando se trata del protocolo para la comunicación entre microservicios) que un diseño de proceso único para tener éxito en la resolución del problema en cuestión.

Mattnewport
fuente
1
"por lo general, necesitará una gran cantidad de código adicional para ordenar los datos entre procesos en lugar de simplemente pasar datos entre hilos en un solo proceso". Sin embargo, aquí hay una compensación, entre la cantidad de código que escribe para pasar mensajes, frente a la simplicidad de diseño que obtiene de (p. ej.) la comunicación de procesos secuenciales. Si obtiene el diseño CSP "correcto", entonces no necesariamente tiene que haber diferencia si los componentes son hilos separados en el mismo proceso, o procesos separados, ya que de cualquier manera están usando la misma interfaz de mensajes con diferentes implementaciones.
Steve Jessop
Para agregar a lo que @SteveJessop está diciendo acerca de la serialización / clasificación, esto puede hacerse muy eficiente más adelante una vez que se entiendan las características de rendimiento del sistema. El caso común de "uh, las redes / sockets son difíciles, usemos HTTP y XML" es casi el peor de los casos, y puede mejorarse enormemente, pero es lo suficientemente familiar para la mayoría de nosotros que es una excelente manera de piratear un sistema juntos eso funciona ahora mismo . Ajustar algo que funciona (y por lo tanto ya es medible) es mucho mejor que tratar de solucionar un diseño que aún no existe en la práctica.
zxq9