Vários programas pequenos conectados via soquetes x um programa grande

8

Estou no início de um projeto que envolve a leitura de vários sensores e a fusão dos dados desses sensores. Ao todo, haverá 4 sensores conectados via USB e uma webcam, também conectados via USB.

Um de meus colegas é muito sincero sobre como é bom dividir programas em partes menores e fazer com que eles se comuniquem pela rede. Ele sugere que devemos ter um executável para cada sensor (ou câmera) e, em seguida, um aplicativo de controle central que se comunique com os outros.

Eu intuitivamente não gosto dessa idéia. O colega em questão trabalhou em outro projeto que usava essa abordagem e não tinha problemas com problemas difíceis de rastrear e depurar.

Não parece um projeto muito estatal e me parece um tanto deselegante. Gostaria de escrever uma biblioteca para lidar com cada sensor e talvez executá-los em threads separados.

Também deve ser salientado que os cálculos que precisamos fazer fornecerão atualizações para outro sistema a quase 1000Hz. Adicionar uma camada de comunicação de rede parece adicionar um gargalo em potencial.

Eu estaria interessado em ouvir as opiniões de outras pessoas sobre isso e talvez algumas referências sobre esse tipo de prática.

James
fonte
9
" não teve problemas com problemas difíceis de rastrear e depurar ", sem ter certeza de que uma solução multiencadeada será mais fácil de depurar. Não estou dizendo que o multithread está errado, mas nunca lembro de ouvir "Vamos usar uma solução multithread, que é muito mais fácil de depurar".
CdkMoose
3
Como usuário frequente de Erlang, esse "uso da rede / protocolo como camada básica de abstração" é frequentemente o meu modo padrão de pensar. Ele faz as coisas mais fáceis de depurar (você pode testar comportamentos completos em isolamento) e faz um sistema mais robusto (câmera # 1 de colocar algo em um estado estranho pode única câmera acidente nº 1 do código de manipulação, e nada espera outra coisa em que o código) e simplifica a adição de um sistema de supervisão. Essas características são muito difíceis de obter de outra maneira - mas, novamente, seu problema pode ser realmente trivial o suficiente para que nada disso importe.
zxq9 01/09/2015
1
Como você está executando 1000Hz em USB em primeiro lugar? Quais são exatamente seus requisitos de desempenho? Você considera os soquetes um gargalo de latência ou taxa de transferência?
Bergi 01/09/2015
1
Por que você acha que precisa de um "design com estado"? Seus sensores não são baseados em eventos?
Bergi 01/09/2015
Um programador teve um problema. Ele pensou consigo mesmo: "Eu sei, vou resolver isso com fios!" . agora tem problemas. dois ele
Toby Speight

Respostas:

13

Eu intuitivamente não gosto dessa idéia.

Bem, intuitivamente, gosto da ideia de dividir programas em partes menores. Mas se os diferentes processos executam sempre todos na mesma máquina, a comunicação em rede provavelmente não é a forma ideal de IPC. Para comunicação de alta velocidade entre processos, a memória compartilhada pode ser a melhor opção. Seja qual for a abordagem escolhida, você deve medir ou pelo menos estimar o desempenho antes de fazer qualquer julgamento.

O colega em questão trabalhou em outro projeto que usava essa abordagem e não tinha problemas com problemas difíceis de rastrear e depurar.

Você precisa verificar que tipo de problemas e onde estão as causas principais. Se eles tiveram problemas devido à concorrência, você encontrará os mesmos problemas (se não mais) ao tentar uma solução multiencadeada.

fornecer atualizações para outro sistema a quase 1000Hz

Se isso é "alta velocidade", depende da velocidade das máquinas de produção e do tamanho da operação envolvida em cada atualização. No que diz respeito ao desempenho, os sentimentos intestinais não são confiáveis, você precisa medir as coisas . Se o seu colega acredita que sua abordagem será rápida o suficiente, e você acredita que não, pelo menos um de vocês terá que provar ou falsificar a crença dele. Por exemplo, um de vocês pode implementar um pequeno protótipo para simular a comunicação entre processos e medir a velocidade. Todo o resto está olhando para uma tigela de vidro.

Doc Brown
fonte
9

Eles podem ou não ser relevantes para a sua aplicação, mas alguns benefícios para a solução de multiprocessos que você ainda não considerou são:

  • Controle de permissão mais refinado. Você pode ter permissões separadas para a webcam e os outros sensores.
  • Mais fácil para testar sensores isoladamente.
  • Mais fácil zombar de um sensor em tempo de execução.
  • É mais fácil fazer com que terceiros escrevam código para seus sensores sem precisar abrir seu código.
  • Uso de ferramentas como o wireshark para solução de problemas, tanto durante o desenvolvimento quanto em campo.
  • O único contexto que conheço onde "stateful" é visto como um atributo positivo é quando as partes com estado de um sistema são restritas a um escopo pequeno como um ator , o que parece apoiar mais o design do seu colega do que o seu.
  • É mais fácil liberar uma trava e reiniciar apenas o processo de um sensor sem precisar reiniciar o sistema inteiro.
  • Pode ser dimensionado apenas adicionando hardware.
  • A comunicação do soquete com a origem e o destino na mesma máquina é relativamente eficiente.

Desvantagens adicionais para a solução de múltiplos processos:

  • Lidar com a contrapressão é mais complexo.
  • Se você está basicamente transmitindo os dados brutos de cada sensor sem filtragem ou processamento, alterou o aplicativo do controlador de leitura de um driver USB para leitura de um driver de rede, sem nenhum ganho real de abstração.
Karl Bielefeldt
fonte
Se alguém usa uma arquitetura em que cada soquete tem um lado mestre e um lado escravo, e cada transmissão pelo mestre gera uma resposta imediata pelo escravo (mesmo que a resposta "ainda não esteja pronta"), e o mestre sempre espera pelo resposta, a contrapressão seria um problema?
Supercat 01/09
Essa seria uma maneira de lidar com isso, @supercat. Não é que a contrapressão seja incontrolável, é que muitas pessoas falham em explicá-la com antecedência, tornando o design mais simples do que realmente precisa ser.
Karl Bielefeldt
8

A abordagem que seu colega está defendendo é frequentemente chamada de arquitetura de microsserviços e está em voga nos dias de hoje. Tem várias vantagens em potencial :

  • Escalabilidade: pode facilitar a escalabilidade, simplesmente adicionando instâncias adicionais de máquinas / VM.
  • Robustez: com um design apropriado, pode ser tolerante a falhas nos processos individuais de microsserviços, perda de conectividade ou indisponibilidade.
  • Extensibilidade: o uso de tecnologias padrão da Web para fazer a interface entre microsserviços (normalmente solicitações HTTP REST com respostas Json ou XML) pode tornar relativamente fácil para terceiros ou clientes interagir com seu sistema e estendê-lo para suas próprias necessidades.

Ele também tem várias desvantagens:

  • Desempenho: geralmente você pagará um custo de desempenho pela comunicação entre processos. Isso pode ser muito significativo se você criar APIs de estilo REST http.
  • Complexidade: normalmente, você precisará de muito código extra para organizar os dados entre os processos versus apenas passar dados entre os threads em um único processo. Você também introduzirá dependências nas bibliotecas para comunicação em rede, suporte a http, etc.
  • Depuração: normalmente é mais complexo depurar um aplicativo composto por vários processos de comunicação independentes versus usar o depurador integrado de um IDE em um único processo.

Não sei bem o que você quer dizer quando diz que o design "não parece um design muito moderno". Geralmente "state-ful" é considerado uma característica ruim de um design e microsserviços "sem estado" são considerados um bom design.

Porém, considerando as informações sobre seus requisitos que você fornece em sua postagem, acho que um design baseado em microsserviços seria um exagero para o seu caso de uso e os benefícios não justificariam a complexidade adicional. Os benefícios das arquiteturas de microsserviços tendem a realmente entrar em jogo ao criar serviços da Web em maior escala que valorizam a escalabilidade, robustez e extensibilidade.

Os benefícios potenciais de uma arquitetura de microsserviços são realizados apenas com um design bem pensado. Na minha opinião, essa arquitetura requer um design mais inicial (principalmente quando se trata do protocolo de comunicação entre microsserviços) do que um único design de processo para que seja bem-sucedido na solução do problema em questão.

mattnewport
fonte
1
"normalmente você precisará de muito código extra para organizar os dados entre processos versus apenas passar dados entre os threads em um único processo" - existe uma troca aqui, porém, entre a quantidade de código que você escreve para passar mensagens, versus a simplicidade de design obtida com (por exemplo) processos sequenciais de comunicação. Se você acertar o design do CSP, não precisa necessariamente fazer diferença se os componentes são threads separados no mesmo processo ou processos separados, pois de qualquer maneira eles estão usando a mesma interface de mensagem com implementações diferentes.
Steve Jessop
Para adicionar o que @SteveJessop está dizendo sobre serialização / empacotamento - isso pode se tornar muito eficiente depois que as características de desempenho do sistema forem compreendidas. O caso comum de "uh, redes / soquetes são difíceis, vamos usar HTTP e XML" é quase o pior caso e pode ser amplamente aprimorado - mas é familiar o suficiente para a maioria de nós que é uma ótima maneira de invadir um sistema juntos que funciona agora . Ajustar algo que funciona (e, portanto, já é mensurável) é muito melhor do que tentar solucionar problemas de um design que ainda não existe na prática.
zxq9 01/09