Notas de leitura de programação de servidor de alto desempenho Linux

Família de protocolos TCP / IP

Protocolo TCP detalhado

Características do serviço TCP

  • Orientado para conexão, fluxo de bytes
  • Transmissão confiável
    Ambas as partes que usam o protocolo TCP para se comunicar devem primeiro estabelecer uma conexão antes de ler e gravar dados. Só então pode começar a leitura e gravação de dados. Ambas as partes devem alocar os recursos de kernel necessários para a conexão para gerenciar o estado da conexão e a transmissão de dados na conexão. A conexão TCP é full duplex. Ou seja, a leitura e a gravação de dados de ambas as partes podem ser realizadas por meio de uma conexão. Depois de concluir a troca de dados, ambas as partes devem se desconectar para liberar os recursos do sistema.

API básica de rede Linux

Leitura e gravação de dados

Leitura e gravação de dados TCP

#include<sys/types.h>
#include<sys/socket.h>
ssize_t recv(int sockfd,void *buf,size_t len,int flags);
ssize_t send(int sockfd,const void *buf,size_t len,int flags);

recv lê os dados acima de sockfg, os parâmetros buf e len especificam respectivamente a localização e o tamanho do buffer de leitura. Sinalizadores geralmente são definidos como 0. Quando recv é bem-sucedido, ele retorna o comprimento dos dados realmente lidos, que pode ser menor que o comprimento len, portanto, pode ser necessário chamar recv várias vezes para ler os dados completos. recv pode retornar 0, o que significa que o parceiro de comunicação foi fechado. Quando recv falha, ele retorna -1 e define errno.
send grava dados para sockfd. Os parâmetros buf e len especificam a localização e o tamanho do buffer de gravação, respectivamente. Quando o envio é bem-sucedido, ele retorna o comprimento dos dados realmente gravados e, quando falha, retorna -1 e define errno.

Funções I / O avançadas

função de tubo

A função de tubo pode ser usada para criar um tubo. Para alcançar a comunicação entre processos. Ele retorna 0 em caso de sucesso e -1 em caso de falha.

#include<unistd.h>
int pipe(int fd[2]);

Os dois descritores de arquivo fd [0] e fd [1] criados pela função pipe constituem as duas extremidades do pipe respectivamente. Os dados gravados em fd [1] podem ser lidos em fd [0]. Além disso, fd [0] só pode ler dados do tubo e fd [1] só pode gravar dados no tubo. Não pode ser usado ao contrário. Se você deseja obter uma transmissão de dados bidirecional, deve usar dois tubos. Por padrão, este par de descritores de arquivo está bloqueado. Neste momento, se você usar read para ler um cachimbo vazio. Então, a leitura será bloqueada. Até que haja dados legíveis no pipeline. Se você usar write para gravar dados em um pipe completo. Em seguida, a gravação também será bloqueada. Até que o pipeline tenha espaço livre suficiente disponível.
O próprio pipeline tem um limite de capacidade. Ele especifica se o aplicativo não lê dados do tubo. O número máximo de bytes de dados que podem ser gravados no tubo. A capacidade do tubo pode ser fcntlmodificada por meio de funções

#include<sys/types.h>
#include<sys/socket.h>
int socketpair(int domain,int type,int protocol,int fd[2]):

O domínio em socketpair só pode usar a família de protocolo de domínio local UNIX AF_UNIX, porque este pipe bidirecional só pode ser usado localmente. Neste momento, o fd pode ser lido ou escrito

funções dup e dup2

As funções dup e dup2 podem redirecionar a entrada padrão para um arquivo ou a saída padrão direta para uma conexão de rede.

#include<unistd.h>
int dup(int fd);
int dup2(int fd1,int fd2):

A função dup cria um novo descritor de arquivo. O novo descritor de arquivo e o descritor original fd apontam para o mesmo arquivo, canal ou conexão de rede. E o descritor de arquivo retornado por dup sempre leva o menor valor inteiro atualmente disponível no sistema. dup2 é semelhante a dup, mas retornará o primeiro valor inteiro não inferior a fd2. Ambos retornam -1 e setam errno quando a chamada falha.
Nota: O descritor de arquivo criado por dup e dup2 não herda os atributos do descritor de arquivo original. Por exemplo, close-on-exec e non-blocking.

Especificação do programa de servidor Linux

Estrutura de programação de servidor


Unidade de processamento de E / S de programa de servidor único : lida com conexões de cliente, lê e grava dados de rede,
unidade lógica: processo de negócios ou thread,
unidade de armazenamento de rede: banco de dados local,
fila de solicitação de arquivo ou cache : método de comunicação entre unidades, E / S de
cluster de servidor
Unidade de processamento: Como um servidor de acesso, realizando o balanceamento de carga
Unidade lógica: Servidor lógico
Unidade de armazenamento de rede: Fila de solicitação do servidor de banco de dados
: Conexão TCP permanente entre servidores

Unidade de processamento de E / S

O servidor gerencia o módulo de conexão do cliente.

Dever

Aguarde e aceite a nova conexão do cliente, aceite os dados do cliente e retorne a resposta do servidor ao cliente. No entanto, o envio e o recebimento de dados não são necessariamente realizados na unidade de processamento de E / S. Também pode ser executado em uma unidade lógica, e onde é executado depende do modo de processamento do evento. Para um cluster de servidor, a unidade de processamento de E / S é um servidor de acesso dedicado, que implementa o balanceamento de carga e seleciona o menos carregado de todos os servidores lógicos para atender a novos clientes.

Unidade lógica

Uma unidade lógica geralmente é um processo ou thread. Ele analisa e processa os dados do cliente e, em seguida, passa os resultados para a unidade de processamento de E / S ou diretamente para o cliente (o método usado depende do modo de processamento do evento). Para um cluster de servidor, a própria unidade lógica é um servidor lógico. Os servidores geralmente têm várias unidades lógicas. Para realizar o processamento paralelo de várias tarefas do cliente.

Unidade de armazenamento de rede

Pode ser banco de dados, cache e arquivo. Mesmo um servidor separado, mas não é necessário. Por exemplo, serviços de login como ssh e telent não precisam desta unidade.

Solicitar fila

É uma abstração da forma de comunicação entre as unidades. Quando a unidade de processamento de E / S recebe uma solicitação do cliente, ela precisa notificar uma unidade lógica de alguma forma para processar a solicitação. Da mesma forma, quando várias unidades lógicas acessam uma unidade de armazenamento ao mesmo tempo, algum mecanismo também é necessário para coordenar o tratamento das condições de corrida. A fila de solicitações geralmente é implementada como parte do pool. Para o cluster de servidor, a fila de solicitação é uma conexão TCP pré-estabelecida, estática e permanente entre cada servidor

Modelo I / O

O soquete é bloqueado por padrão quando é criado. Você pode passar o SOCK_NONBLOCKsinalizador para o segundo parâmetro da chamada de sistema de soquete ou defini-lo como sem bloqueio por meio do comando F_SETFL da chamada de sistema fcntl.
Bloquear
descritores de arquivo bloqueados de E / S. As chamadas do sistema executadas para este tipo de E / S podem ser suspensas pelo sistema operacional porque não podem ser concluídas imediatamente. Até que o evento de espera ocorra. Na API de soquete básico, as chamadas de sistema que podem ser bloqueadas são:

  • aceitar
  • enviar
  • recv
  • conectar descritor de arquivo
    sem bloqueio de E / S
    sem bloqueio. As chamadas de sistema executadas para este tipo de E / S sempre retornam imediatamente. Independentemente de o evento ter ocorrido. Se o evento não ocorrer imediatamente, a chamada do sistema também retornará.
    Resumo
    Obviamente, apenas operar E / S sem bloqueio (leitura, gravação, etc.) quando o evento ocorreu pode melhorar a eficiência do programa. Portanto, a E / S sem bloqueio geralmente precisa ser usada com outros mecanismos de E / S. Por exemplo, multiplexação de E / S e sinais SIGIO.

Multiplexação de E / S

O programa de aplicação registra um conjunto de eventos com o kernel por meio da função de multiplexação de E / S, e o kernel notifica o aplicativo sobre os eventos prontos por meio da função de multiplexação de E / S. As funções de multiplexação de E / S comumente usadas no Linux são select, poll e epoll_wait.
Nota: As próprias funções de multiplexação de E / S estão bloqueando. O motivo pelo qual podem melhorar a eficiência do programa é que têm a capacidade de monitorar vários eventos de E / S.
Eventos de I / O

Acho que você gosta

Origin blog.csdn.net/weixin_39308337/article/details/108522820
Recomendado
Clasificación