Pergunta

Eu tenho um pool de conexões MySQL para um serviço de dados baseado na Web. Quando começa a atender uma solicitação, é necessário usar uma conexão do pool. O problema é que, se houver uma pausa significativa, pois essa conexão específica foi usada, o servidor poderá ter programado e fechou seu final. Eu gostaria de poder detectar isso no código de gerenciamento de pool.

O truque é o seguinte: o ambiente em que estou codificando me dá apenas uma API muito abstrata na conexão. Basicamente, posso executar apenas instruções SQL. Não tenho acesso ao soquete real ou acesso direto à API do cliente MySQL.

Então, a questão é: Qual é a instrução MySQL mais barata que posso executar na conexão para determinar se está funcionando. Por exemplo SELECT 1; Deveria trabalhar, mas estou me perguntando se há algo ainda mais barato? Talvez algo que nem sequer atravesse o fio, mas seja tratado na LIB do MySQL e responda efetivamente à mesma pergunta?

Esclarecimento: Não estou preocupado em verificar se o servidor MySQL estiver em execução, ou se a configuração do banco de dados for suficiente para responder às consultas. Se essas coisas estiverem inativas, o SQL subsequente executado será obtido e lidará com o erro apropriado. Estou realmente realmente preocupado se a conexão TCP estiver aberta ... já que se o servidor a fechar, o SQL do Serviço da Web receberá um erro que significa "apenas se reconectar e tentar novamente", e isso seria inconveniente para fazer uma vez em queda em a lama do código de serviço.

Fecho: o /* ping */ Hack é exatamente o tipo de coisa que eu estava procurando, mas infelizmente está disponível via JDBC. Lendo os documentos para esse hack, está claro que foi colocado lá para exatamente A mesma razão que eu queria. Para os curiosos, estou trabalhando em Haskel, usando HDBC e HDBC-MYSQL. Vou pedir ao autor do HDBC-MYSQL para adicionar uma maneira de ligar mysql_ping() diretamente ou através de um hack semelhante.

Vlad's DO 1 Também foi o tipo de coisa que eu estava atrás, e como o outro hack não está disponível fora do JDBC, eu o usarei.

Obrigado por toda a ótima discussão, especialmente @vlad!

Foi útil?

Solução

Você não conhecerá o estado real da conexão sem passar por cima do fio, e SELECT 1 é um candidato bom o suficiente (sem dúvida você pode criar um comando mais curto que leva menos tempo para analisar, mas comparado à rede ou até mesmo em latência de loopback, essas economias seriam insignificantes.)

Dito isto, eu argumentaria que pinging uma conexão antes da Verificar -o da piscina não é a melhor abordagem.

Você provavelmente deve simplesmente ter seu gerenciador de pool de conexão Aplicar sua própria política de Keep-Alive (Timeout) Para evitar ser desconectado pelo servidor (com pouco mais de um problema de conectividade interveniente, o que pode afetar você no meio das operações regulares de qualquer maneira - e que seu gerente de pool de conexões seria incapaz de ajudar de qualquer maneira), bem como Para não monopolizar o banco de dados (Pense em arquivos e uso de memória) desnecessariamente.

Portanto, é questionável, na minha opinião, que testes de valor para a condição de conectividade antes de verificar uma conexão do pool realmente tem. Pode valer a pena testar o status da conexão Antes de uma conexão ser verificada de volta à piscina, mas isso pode ser feito implicitamente, simplesmente marcando a conexão como suja quando surge um erro rígido do SQL (ou exceção equivalente) (a menos que a API que você esteja usando já exponha um is-bad-como chamado para você.)

Eu recomendaria:

  • Implementando uma políticos de Keep-Alive do lado do cliente
  • não executando nenhum cheque ao verificar as conexões da piscina
  • Realizando verificações sujas antes que uma conexão seja devolvida à piscina
  • Deixe o código do aplicativo lidar com outras condições de conexão excepcionais (sem tempo e)

ATUALIZAR

Apareceria em seus comentários que você realmente verdade Deseja fazer ping na conexão (presumo que isso seja porque você não tem controle total sobre, ou conhecimento de características de tempo limite no servidor MySQL ou equipamentos de rede intervenientes, como proxies etc.)

Nesse caso, você pode usar DO 1 como uma alternativa a SELECT 1; isso é marginalmente mais rápido - mais curto para analisar e não retorna dados reais (embora você vai Obtenha o TCP ackS, então você ainda fará a ida e volta que a conexão ainda está estabelecida.)

Atualização 2

Em relação a O post de Joshua, aqui estão traços de captura de pacotes para vários cenários:

SELECT 1;
13:51:01.463112 IP client.45893 > server.mysql: P 2270604498:2270604511(13) ack 2531191393 win 1460 <nop,nop,timestamp 2983462950 59680547>
13:51:01.463682 IP server.mysql > client.45893: P 1:57(56) ack 13 win 65306 <nop,nop,timestamp 59680938 2983462950>
13:51:01.463698 IP client.45893 > server.mysql: . ack 57 win 1460 <nop,nop,timestamp 2983462951 59680938>

DO 1;
13:51:27.415520 IP client.45893 > server.mysql: P 13:22(9) ack 57 win 1460 <nop,nop,timestamp 2983488906 59680938>
13:51:27.415931 IP server.mysql > client.45893: P 57:68(11) ack 22 win 65297 <nop,nop,timestamp 59681197 2983488906>
13:51:27.415948 IP client.45893 > server.mysql: . ack 68 win 1460 <nop,nop,timestamp 2983488907 59681197>

mysql_ping
14:54:05.545860 IP client.46156 > server.mysql: P 69:74(5) ack 78 win 1460 <nop,nop,timestamp 2987247459 59718745>
14:54:05.546076 IP server.mysql > client.46156: P 78:89(11) ack 74 win 65462 <nop,nop,timestamp 59718776 2987247459>
14:54:05.546092 IP client.46156 > server.mysql: . ack 89 win 1460 <nop,nop,timestamp 2987247459 59718776>

Como você pode ver, exceto pelo fato de que o mysql_ping O pacote é de 5 bytes em vez de DO 1;9 Bytes, o número de ida e volta (e, consequentemente, a latência induzida pela rede) é exatamente a mesma. O único custo extra que você está pagando DO 1 em oposição a mysql_ping é a análise de DO 1, o que é trivial.

Outras dicas

Resolvido

Eu li um muitoArtigo informativo sobre aam que ajudou
Basicamente, eu estava esperando muito da AAM e há também várias circunstâncias em que as coisas podem parecer trabalhar por um tempo / até certo ponto, que é o que parecia acontecer aqui.

Eu esqueci de definir as ligações do IIS para o site.

O domínio que eu estava usando foi um teste que repito para novos sites do SharePoint, conforme necessário, então foi configurado até certo ponto, e adicionando o mapeamento de acesso alternativo para o domínio de teste parece funcionar na maior parte, masfalhou no ponto que descrevi acima;Autenticar os detalhes do usuário do FBA de envio ao concluir um fluxo de trabalho.
Estranho.

"Conexão" neste caso tem vários significados. O MySQL ouve em um soquete- essa é a "conexão" no nível da rede. O MySQL mantém "conexões de banco de dados", que incluem um contexto para execução de consultas e outras despesas gerais.

Se você quiser apenas saber se o serviço está ouvindo, poderá executar uma chamada no nível da rede para ver se a porta (não sei o que é o padrão) está ouvindo o IP de destino. Se você deseja que o mecanismo MySQL responda, acho que seu SELECT 1 A ideia é boa- na verdade, não obtém dados do banco de dados, mas confirma que o mecanismo está girado e respondendo.

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