Pool de Conexões

O pool de conexões é o conjunto de conexões com o banco de dados que o PHServer mantém abertas e reaproveita entre as requisições.

Abrir uma conexão com o banco é uma operação cara: envolve rede, autenticação e preparação da sessão no servidor de banco. Sem pool, cada requisição pagaria esse custo para abrir uma conexão e fechá-la logo em seguida. Com o pool, a maior parte das requisições pega uma conexão que já está aberta e a devolve ao terminar, pronta para a próxima. O resultado é menos tempo de resposta e menos carga no banco, principalmente quando muitos usuários trabalham ao mesmo tempo.

Os dois pools do PHServer

Toda requisição usa duas bases de dados:

  1. A base do PHServerConf, onde ficam as sessões, as configurações do servidor e o log. É nela que o PHServer consulta a sessão informada na requisição e descobre em qual base do PHERP o usuário está trabalhando.
  2. A base do PHERP daquela sessão, onde o procedimento da requisição é executado.

Por isso o servidor mantém dois pools:

Pool Usado para Organização Limite de conexões
ServerConf sessões, configurações e log uma lista única ServerConf › Configurações › seção Serviço › Pool de Conexões (ServerConf)
ERP procedimentos das requisições uma lista para cada base de dados cadastrada ServerConf › Bases de Dados › cadastro da base › Pool de Conexões

No pool do ERP, cada base tem a própria lista: as conexões da base ERP_MATRIZ nunca atendem a ERP_FILIAL, e cada base tem o próprio limite e o próprio tempo de permanência.

Como uma conexão é entregue

Quando uma requisição precisa de uma conexão com a sua base:

  1. O pool procura uma conexão livre na lista da base.
  2. Se a conexão livre está parada há 30 segundos ou mais, ela é testada antes de ser entregue (um ping no banco). Se não responder, por exemplo porque o banco reiniciou ou a rede caiu, ela é descartada e o pool procura outra.
  3. Se não há conexão livre e a lista ainda não chegou ao limite, o pool abre uma conexão nova, que passa a fazer parte da lista.
  4. Se a lista já está no limite, a requisição não espera e não recebe erro: o PHServer abre uma conexão avulsa (fora do pool), usada só naquela requisição e fechada quando ela termina.

O pool começa vazio: as conexões são abertas conforme a demanda, até o limite, e não antecipadamente.

Fluxo de entrega de uma conexão: procura livre, testa se parada há 30 segundos ou mais, abre nova se couber no pool ou abre conexão avulsa se o pool estiver cheio

Pool cheio: conexões fora do pool

Conexão avulsa em um pico eventual é normal. Mas cada uma custa a abertura de uma conexão e deixa a requisição mais lenta. Quando elas acontecem, o PHServer conta as ocorrências e, na varredura seguinte, grava no log um aviso com a quantidade, o limite atual e onde aumentá-lo.

Se as conexões fora do pool aparecem com frequência, aumente o Pool de Conexões da base.

Devolução da conexão

Ao fim da requisição a conexão volta para o pool. Antes de ser reaproveitada, o PHServer verifica:

  • Transação aberta: se a rotina terminou sem confirmar nem desfazer a transação, ela é desfeita (rollback) e registrada no log como TRANSACAO_ABERTA (alerta), com a base, a sessão e a rotina.
  • Consulta ainda presa à conexão: é registrada no log como VAZAMENTO_QUERY (erro) e desvinculada. A conexão continua utilizável.
  • Conexão avulsa: é fechada.
  • Conexão com mais de 60 minutos de vida, ou que não pôde ser limpa: é fechada, e o pool abre outra quando precisar. A renovação periódica evita que conexões muito antigas acumulem memória no servidor de banco.

As demais voltam livres para a lista.

Fechamento das conexões paradas

A cada 5 minutos o PHServer faz uma varredura nas listas de cada base:

  • fecha as conexões livres que passaram do tempo de permanência configurado para a base;
  • fecha as conexões com mais de 60 minutos de vida;
  • grava o aviso de conexões fora do pool, se houve.

O tempo de permanência é contado a partir da última vez em que a conexão foi entregue a uma requisição. Como a varredura roda a cada 5 minutos, uma conexão parada pode ficar aberta até cerca de 5 minutos além da permanência. Com permanência 0, toda conexão livre é fechada na varredura seguinte.

Conexões em uso nunca são fechadas pela varredura.

Ciclo de vida de uma conexão: em uso, livre no pool e fechada, com os motivos de cada transição

Configuração

Onde Campo O que define Padrão
ServerConf › Bases de Dados (cadastro de cada base) Pool de Conexões Número máximo de conexões no pool daquela base. Com 0, a base fica sem pool e toda conexão é avulsa. 5
Minutos Permanência Pool Por quanto tempo uma conexão livre fica aberta, esperando a próxima requisição. 5
ServerConf › Configurações › Serviço Pool de Conexões (ServerConf) Número máximo de conexões no pool do ServerConf. 100
Minutos Permanência Pool (ServerConf) Permanência no pool do ServerConf. 5

Os valores são lidos quando o serviço PHServer inicia. Depois de alterar qualquer um deles, ou de cadastrar uma base nova, reinicie o serviço.

Valores fixos, não configuráveis:

Comportamento Valor
Intervalo da varredura de conexões paradas 5 minutos
Tempo parada a partir do qual a conexão é testada antes do uso 30 segundos
Vida máxima de uma conexão 60 minutos

Como dimensionar

  • Comece pelo padrão e acompanhe a coluna Fora do pool no painel do ServerConf (veja abaixo). Se ela cresce todo dia, aumente o Pool de Conexões da base.
  • O limite vale por processo. Relatórios e processos executados em subprocesso têm o próprio par de pools, com os mesmos limites. Em uma base, o número total de conexões pode chegar ao limite do serviço principal mais o limite de cada subprocesso ativo, além das avulsas. Garanta que o servidor de banco aceite essa quantidade de conexões simultâneas.
  • Os agendamentos usam conexão própria e não ocupam vagas do pool.

Acompanhamento no ServerConf

O card Conexões dos pools, no Dashboard do ServerConf, mostra o estado de cada lista:

Card Conexões dos pools no dashboard do ServerConf, com as colunas Base, Uso do pool, Em uso, abertas e limite, Pico, Fora do pool e Transação aberta

Coluna Significado
Base Uma linha por base que já pediu conexão desde que o serviço subiu, mais a lista do ServerConf. Embaixo do nome, a permanência configurada.
Uso do pool Laranja: em uso. Clara: abertas e paradas. Cinza: vagas até o limite. Contorno vermelho: pool cheio.
Em uso / abertas / limite Conexões atendendo agora, conexões abertas no pool e o limite configurado. +N avulsas agora indica conexões fora do pool ainda em uso.
Pico Maior uso simultâneo registrado, incluindo as avulsas.
Fora do pool Conexões avulsas abertas desde a última varredura; embaixo, o total desde que o serviço subiu.
Transação aberta Avisos TRANSACAO_ABERTA gravados no log nas últimas 24 horas.

O card mostra o processo principal do serviço. Os subprocessos têm pools próprios e só entram na coluna Transação aberta, que soma os avisos de todos os processos.

Problemas comuns

Sintoma Causa provável O que fazer
Fora do pool sempre acima de zero O limite da base é pequeno para o movimento. Aumentar o Pool de Conexões da base e reiniciar o serviço. Conferir o limite de conexões do servidor de banco.
Em uso no limite e não volta a baixar Uma rotina não está devolvendo a conexão. Como a varredura não fecha conexões em uso, a vaga só é liberada quando o serviço reinicia. Abrir chamado informando a base e o horário, para a rotina ser identificada.
Transação aberta acima de zero Uma rotina terminou sem confirmar nem desfazer a transação. O pool desfez, mas a operação pode ter ficado incompleta. Consultar no log os avisos TRANSACAO_ABERTA: eles indicam a base, a sessão e a rotina.
Alterei o Pool de Conexões e nada mudou Os valores só são lidos na inicialização. Reiniciar o serviço PHServer.
O banco reiniciou e as requisições voltaram a funcionar sozinhas Comportamento esperado. Nada: conexões paradas há 30 segundos ou mais são testadas antes do uso e substituídas se não responderem.

Para desenvolvedores

  • Implementação: uPHSPoolConexoes.pas (TPHSPoolConexoes, TPHSRequestConexao, TThreadLiberaConexoes) e uPHSPoolConexoesUtils.pas (TPHSListaConexoes, TPHSConexao). O pool é próprio do PHServer; o pool nativo do FireDAC não é usado.
  • Nas classes de negócio, a conexão do ERP vem de TPHServerClass.RetornaConexaoPool e é devolvida quando o TPHSRequestConexao é liberado. Libere sempre em um bloco finally: uma conexão não devolvida ocupa a vaga até o serviço reiniciar.
  • Toda transação iniciada deve terminar com commit ou rollback na própria rotina. O pool desfaz o que sobrar, mas registra alerta no log.
  • Feche as consultas antes de devolver a conexão; consulta presa gera VAZAMENTO_QUERY.
  • Rotas de longa duração (SSE de notificações e presença) não usam o pool do ERP, para não segurar vagas.