Pergunta

Tenho programas de clientes e servidores que agora se comunicam via TCP. Estou tentando usar filas de mensagens POSIX (nos casos em que o cliente e o servidor estão na mesma máquina, é claro). Minha esperança é que isso melhore o desempenho (especificamente por latência reduzida).

Eu trabalhei a maior parte, mas não tenho certeza de uma coisa: como estabelecer a "conexão". O servidor aceita conexões de vários clientes simultaneamente, por isso estou tentado a imitar a conexão TCP estabelecer processos como assim:

  1. O servidor abre uma fila com um nome bem conhecido e lê sobre ele continuamente (pode usar select(2) Como no TCP).
  2. O cliente abre três filas: dois com nomes arbitrários (incluindo alguma singularidade, como o PID, para evitar colisões) e um com o nome bem conhecido usado pelo servidor.
  3. O cliente publica uma mensagem "Connect" na fila do servidor, incluindo os nomes da fila do cliente (um é designado para o tráfego cliente a servidor e o outro para o Converse).
  4. O servidor abre as filas nomeadas na mensagem Connect do cliente e começa a ler (selecionar) do cliente para servidor.
  5. O cliente fecha a fila do servidor com o nome bem conhecido. A comunicação bidirecional prossegue usando as duas filas nomeadas pelo cliente (uma para cada direção).

Você provavelmente pode ver como esse esquema é semelhante ao método TCP comum, e isso não é acidente. No entanto, eu gostaria de saber:

  1. Você consegue pensar em uma maneira melhor de fazer isso?
  2. Você vê algum problema em potencial com meu método?
  3. Você tem outros pensamentos, inclusive sobre a probabilidade de usar filas de mensagens em vez de TCP na mesma máquina, realmente melhorará o desempenho (latência)?

Lembre -se de que não usei filas de mensagens POSIX antes (eu usei o IBM WebSphere MQ há algum tempo, mas isso é bastante diferente). A plataforma é Linux.

Foi útil?

Solução 2

Acabei implementando -o basicamente como descrevi, com alguns aprimoramentos:

  • Na etapa 2, usei o GUIDS para os nomes da fila em vez de incorporar o PID do cliente.
  • Na etapa 4, adicionei o envio de uma mensagem "aceitar" do servidor para o cliente.
  • Quando ambos os lados desejam encerrar a comunicação, ele envia uma mensagem "Desconectar".

O aperto de mão é mais simples que o TCP, mas parece suficiente.

Quanto à latência: é muito melhor. Aproximadamente 75% menos latência usando filas de mensagens POSIX em vez de TCP na mesma máquina. Minhas mensagens estão na ordem de 100 bytes cada.

Outras dicas

  1. Você consegue pensar em uma maneira melhor de fazer isso?

    Talvez dê uma olhada em Fifos (também conhecidos como Pipes de nome). Eles são como soquetes de rede, mas para a máquina local. Eles são unidirecionais, então você pode precisar criar dois, um para cada direção. Sua pergunta não tem nenhum motivo para Por quê Você está fazendo essa alteração especificamente. Não há nada de errado em usar soquetes para processo para processar a comunicação. Eles são bidirecionais, eficientes, amplamente suportados e oferecem a liberdade de separar os processos entre as máquinas posteriormente.

  2. Você vê algum problema em potencial com meu método?

    Sistema V Filas de mensagens e FIFO Pipes nomeados são absolutamente bons. Os tubos FIFO são como tubos regulares para que você possa ler () e gravar () com alterações mínimas de código. As filas de mensagens do sistema V exigem colocar os dados em uma estrutura e invocar MSGSND (). Qualquer abordagem seria boa, no entanto.

  3. Você tem outros pensamentos, inclusive sobre a probabilidade de usar filas de mensagens em vez de TCP na mesma máquina, realmente melhorará o desempenho (latência)?

    Meus outros pensamentos são que, como você disse, você precisa desenvolver uma técnica para que cada cliente tenha um identificador exclusivo. Uma abordagem seria adicionar o PID à estrutura que você passa ou negociar um ID exclusivo com o pai / mestre no início. A outra coisa a observar é que o benefício das filas de mensagens do Sistema V é que você ouve para mensagens "seletivas" para que você possa usar uma fila do servidor para todos os clientes, com cada cliente aguardando uma mensagem diferente.

    Não tenho idéia de qual técnica oferece a taxa de transferência mais ideal em seu software. Realmente pode não valer a pena usar as filas de mensagens do Sistema V, mas apenas você pode tomar essa decisão.

Philluminati

Comparei o desempenho do POSIX MQ e um par de soquetes TCP/IP.

O programa de demonstração possui dois threads, um para escrever e outro para leitura.

O resultado é que o POSIX MQ é mais rápido,

  • MQ 460000 TPS
  • SocketPair 400000 TPS

Eu conheci um problema semelhante, desenvolvo aplicativos em tempo real e preciso da técnica do IPC com a funcionalidade de soquetes semelhantes e a latência mínima.

Você comparou sua solução baseada em Posix-MQ apenas com soquetes locais ou soquetes TCP?

Obrigado

Como você fez isso quando o select () não funciona em filas de mensagens? O que é Sys V ou Posix? Por que fazer o esforço extra na criação da tabela de pesquisa GUID para PID quando o PID é garantido para ser único e o armazenamento menor (número inteiro)?

/blee/

Você também pode usar filas de mensagens para IPC em programas que residem em diferentes máquinas; nesses casos, você pode usar o ZerOMQ (http://www.zeromq.org) ou outras APIs da fila de mensagens, também sugiro que você as considere e testá -las também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top