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.
Índice
Os dois pools do PHServer
Toda requisição usa duas bases de dados:
- 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.
- 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:
- O pool procura uma conexão livre na lista da base.
- 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.
- 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.
- 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.
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.
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:
| 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) euPHSPoolConexoesUtils.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.RetornaConexaoPoole é devolvida quando oTPHSRequestConexaoé liberado. Libere sempre em um blocofinally: 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.