Um servidor de soquete e um servidor de jogos devem ser processos separados?

14

Suponha um jogo simples de cliente / servidor padrão. Para o servidor, vale a pena ter um processo separado que escute conexões e mensagens de clientes e envie os dados por soquetes locais ou stdin para outro processo que execute o servidor de jogo real?

A outra opção seria fazer as duas coisas em um único processo. Enfileirar mensagens recebidas e executá-las na ordem correta, não deve haver um problema de interrupção.

Gostaria de saber se os recursos extras para separar as duas "atividades" realmente valem a pena. Como devo decidir? Eu gostaria de ouvir quaisquer prós / contras.

luleksde
fonte
11
Como as duas partes se comunicam? Tomadas?
vz0
Você se propõe alterar o "ouvinte" para usar uma técnica de comunicação diferente ou adicionar opções para usar mais de um tipo de comunicação cliente-servidor (por exemplo, se clientes móveis precisassem se comunicar de maneira diferente)? Nesse caso, pode valer a pena separá-lo para que você possa trocar os módulos de entrada / saída conforme necessário.
Jon História
@ JonStory Sim, eu faço. Mesmo com dois ouvintes diferentes, ainda assim pode ser um processo único, mas depois de ler todas as respostas aqui e pensar um pouco mais sobre isso, decidi que valerá a pena ter processos separados. Para este projeto em particular, o cliente principal será um navegador javascript, mas pretendo adicionar um aplicativo cliente móvel nativo no futuro.
Luleksde

Respostas:

17

Do ponto de vista do design da API, ao decidir fazer vários programas de comunicação separados ou apenas um, a questão é: cada programa pode funcionar significativamente sem os outros? A resposta variará de acordo com o seu projeto e preferências.

Se eles não puderem , não vale a pena pensar. Claramente, eles estão tão fortemente vinculados que não são realmente processos separados.

Se eles podem , e você puder ver vários componentes para substituí-los no futuro, uma abstração de processo fornecida pelo sistema operacional pode ajudar.

O quanto isso ajuda depende do resto da sua pilha de tecnologia. Por exemplo, Erlang já modela internamente as coisas como processos, para que você não obtenha muito benefício conceitual ao dividi-la em processos de SO também. A menos que você esteja pensando em reescrever essas partes do servidor em um idioma diferente. Os componentes internos de um programa C ++ são tipicamente acoplados muito mais apertados e, portanto, são mais difíceis de trocar, portanto, dividi-los em diferentes processos do sistema operacional pode poupar o trabalho mais tarde, se você puder prever esses rearranjos.

Anko
fonte
11

vale a pena ter um processo separado que escute conexões e mensagens de clientes e envie os dados por soquetes locais ou stdin para outro processo que execute o servidor de jogo real?

Para responder se vale a pena, você primeiro deve se perguntar qual é o problema que está tentando resolver, adicionando um serviço de fila dedicado. Se resolver esse problema, vale a pena; se não resolver um problema ou se você não tiver um problema para resolver, provavelmente não o será.

Vamos ver algumas razões pelas quais alguns servidores usam uma arquitetura de várias camadas:

  1. Balanceamento de carga - o balanceamento de carga faz sentido se você deseja espalhar sua carga de trabalho para várias máquinas operárias. Se o seu programa tiver gargalos que você deseja resolver simplesmente com vários processos simultâneos de trabalho na mesma máquina, é melhor a longo prazo realmente resolver o gargalo, mas como solução alternativa a curto prazo, os processos de trabalho geradores podem ser práticos.
  2. Separação de privilégios - Talvez você não queira uma violação de segurança no servidor de bate-papo para obter automaticamente acesso ao servidor de jogos ou vice-versa. Se o seu servidor de jogos estiver separado do servidor de bate-papo no jogo, você poderá configurar o servidor de jogos e o servidor de bate-papo para viver em um domínio de segurança separado (por exemplo, executar como usuário diferente, com privilégios de acesso diferentes, limites de processo diferentes, etc.).
  3. Atualização de tempo de inatividade zero - se você deseja obter uma atualização de tempo de inatividade zero, é necessário ter várias camadas e configurar o sistema de modo que, quando você desligar um servidor para manutenção, suas solicitações serão redirecionadas para outros servidores na mesma camada para garantir a continuidade serviço.
  4. Limite de interrupção - se você atingir o limite do soquete, o limite do descritor de arquivo, um bloqueio global de intérpretes, etc., poderá contornar esse limite executando vários processos. Outra maneira de resolver isso é alterar o limite, mas nem sempre é fácil, pois você pode precisar recompilar o kernel, ou pode haver implicações de segurança ou desempenho.
  5. Limitando o vazamento de recursos - você deseja escrever um software que não vaze recursos, mas mesmo em linguagens totalmente gerenciadas por lixo, isso é extremamente difícil em processos de longa duração e, pior, difícil de replicar em um ambiente de desenvolvimento. Uma arquitetura multicamada permite matar e reaparecer os servidores de jogos após certo período de tempo ou número de solicitações para limitar os danos causados ​​por vazamentos de recursos, sem interromper o serviço.
Lie Ryan
fonte
5

Eu concordo com a catraca. Contanto que você tenha um único servidor de jogos, não vale a pena.

No entanto, essa arquitetura pode ser útil quando você precisar ampliar horizontalmente. Quando um servidor de jogos não é mais suficiente e você precisa distribuir seu jogo em vários servidores de jogos por motivos de desempenho, a arquitetura do "servidor de soquete" pode ser facilmente adaptada para transformar o servidor de soquete em um balanceador de carga que roteia automaticamente as conexões para um dos muitos back-end servidor.

Mas quando você não tem certeza de que precisará disso, é provável que o excesso de engenharia desenvolva dois aplicativos de servidor separados neste momento.

Philipp
fonte
4

Provavelmente não, a maioria dos idiomas possui soquetes assíncronos que permitem o uso de várias conexões por vez sem bloquear enquanto os dados estão aguardando. Isso muda a parte "socket server" para o OS / kernel.

Com um servidor de soquete explícito, você terá o custo de algumas cópias extras ao passar os dados pelo soquete local; uma coisa que matará a escalabilidade é cópias extras onde você não precisa delas.

catraca arrepiante
fonte
11
A menos que você já saiba que seu servidor terá requisitos de escalabilidade muito altos, não me preocuparia com o desempenho neste estágio. A sobrecarga de copiar alguns dados na memória é muito pequena em comparação com o envio de dados pela Internet.
Anko