Pergunta

Qual é a melhor maneira de configurar sua piscina com respeito a: -

  1. Quando você cria conexões?
  2. Quando você ligações estreitas, e faria você fechar todos eles?
  3. Você conexões de teste ainda são boas. Quando e como?
  4. Como você descobrir um número bom para o número máximo de conexões?
  5. Que tipo de monitoramento que você tem no local para garantir que os usuários da piscina são bem comportados? você pode parar um mau pedaço de código de tirar tudo?
  6. Você já escreveu sua própria piscina, ou usado uma biblioteca de terceiros?

Eu acredito que esta é uma questão agnóstico, mas os comentários sobre "características" de bancos de dados particulares / línguas são bem-vindos. Por exemplo, pode ser mais lento ou mais caro para ligar em alguns bancos de dados do que outros.

Para esclarecer, eu não pretendo escrever uma piscina a partir do zero, esta questão é mais sobre como configurar uma biblioteca existente que não pooling.

Foi útil?

Solução

Eu escrevi um pool de conexão para o banco de dados em Java quando era apenas um padrão de design e não uma biblioteca comum. Agora eu uso o que se construiu em Tomcat.

Eu usei um fio para monitorar vários aspectos da piscina e vários parâmetros para controlar seu comportamento ...

  1. minimumInPool = "3" ... Esses três primeiros são criados após o lançamento. A piscina nunca é permitida a cair abaixo de três.
  2. maximumIdleTimeBeforeRemoval = "60" ... Se uma conexão estiver inactivo durante uma hora, em seguida, soltá-lo e criar um novo. tempo ocioso provavelmente significa que há apenas o mínimo de três na piscina.
  3. maximumInUseTimeBeforeRemoval = "30" ... Se uma determinada ligação foi verificado por mais 30 minutos, então algo está provavelmente errado. Recuperá-lo, e matar a conexão.
  4. maximumTimeBeforeRemoval = "60" ... Removê-lo se ele é mais de 60 minutos de idade.
  5. maximumUsageBeforeRemoval = "1000" ... Removê-lo se tiver sido verificado mais de 1000 vezes.
  6. monitorInterval = "15" ... Verifique os parâmetros acima a cada 15 minutos.

Isso me serviu muito bem para um par de anos. A maior que eu já vi a piscina foi de 151 conexões durante uma espiada selvagem. Normalmente, a piscina estava em cerca de uma dúzia durante o uso pesado e ociosa até o mínimo de três nas primeiras horas da manhã.

Eu costumava motoristas finas JDBC da Oracle e conectado a um banco de dados Oracle.

Outras dicas

Aqui é a razão que eu usei para uma implementação recente.

  1. Tem dois tipos de conexões em seu pool de conexão. O primeiro está pronto, ou seja, aberto, mas não em uso por um cliente. A segunda é ativa, ou seja, em uso por um cliente.

  2. Tenha o seu pool de conexões manter um pequeno número de conexões prontas, mínimo de N e um máximo de M. N pode ser ajustado, dependendo da velocidade de pico em que os clientes solicitam conexões. Se o número de conexões prontas já cai para zero, você precisa de uma N. maior se o número é consistentemente alta (digamos, acima de 10), você precisa de um menor N.

  3. Quando um cliente quer uma conexão, dar-lhes um dos mais prontos (tornando-se ativo), em seguida, abra imediatamente um novo se agora há menos de N pronto (mas não faça o tempo de espera do cliente para este para completar, ou você vai perder a vantagem de pooling). Isto assegura que sempre será, pelo menos, N conexões prontas. Se nenhum estiver pronto quando o cliente quer um, eles vão ter que esperar enquanto você criar um novo.

  4. Ao terminar o cliente com uma conexão ativa, devolvê-lo ao estado de pronto se há menos de conexões prontas M. Caso contrário, fechá-lo. Isso você impede de ter mais de conexões prontas M.

  5. Periodicamente reciclar as conexões prontos para impedir conexões obsoletos. Se há mais de N conexões prontas, basta fechar a conexão mais antiga. Caso contrário, fechá-lo e re-abrir outra.

Isto tem a vantagem de ter o suficiente pronto e conexões jovens disponíveis no seu pool de conexão sem sobrecarregar o servidor.

Jakarta Commons DBCP já faz todas as coisas que você listou:

  • cria conexões conforme necessário e gerencia-los em uma piscina
  • pode fechar conexões se não tiverem sido usado por um determinado período de tempo
  • ele pode executar uma consulta em uma conexão antes de entregá-lo para fora, e se houver um erro, a conexão é jogado fora e um novo é criado. Ligações também podem ser testados periodicamente enquanto ocioso.
  • Você pode definir um limite para as conexões que serão criados e também do número mínimo de conexões para ter pronto. O limite de curso depende muito de sua aplicação.
  • Não sei como, mas DBCP sabe quando uma conexão não está sendo fechado e fecha-lo para você, lançando uma exceção para que você saiba o que aconteceu quando você vê o seu log.
  • DBCP tem um parâmetro de tempo limite que é muito útil. Se todas as ligações no conjunto estão sendo usado, ele vai esperar por esse período de tempo para uma conexão a ser devolvido para a piscina e se não há nenhum disponível quando o limite for atingido, você receberá um erro.

Você pode afinar a sua piscina, jogando com o número mínimo de conexões, o número máximo de conexões a ser criado, e o tempo limite. Um tempo limite maior vai permitir que você tenha um limite inferior de conexões, enquanto um tempo mais curto, provavelmente será necessário um número maior. Isso depende muito do que o seu aplicativo faz e como ele usa as ligações.

Eu concordo com Matt b que não devemos reinventar a roda.

No entanto usando Commons DBCP é discutível com base nas respostas de este e este perguntas. Não há melhores alternativas mencionadas como c3po ou Proxool .

Ou você pode usar rdbms mecanismo de conexão pooling dependente.

Eu não tenho certeza do que o contexto em que você está usando suas conexões, mas eu posso compartilhar o que parece funcionar para mim.

Eu uso o servidor SQL como o meu back-end e usar uma combinação de caching com ele para obter um melhor desempenho. Minha prática é manter a conexão aberta só se eu realmente precisar dele e não reunir conexões de modo que eles limpar imediatamente e eu posso ver no monitor de SQL Atividade exatamente o que está ativo e que não é. Cada conexão ocupa memória por isso é bom para mantê-lo a um rugido surdo quando eles não são necessários.

Antes de responder a conexão questão em aberto e próximo deixe-me dizer que o cache é realmente importante. Obtendo um objeto fora do cache vai economizar uma tonelada de tempo. Em alguns dos meus aplicativos asp.net quando o cache está em no dev eu descobri que eu mal posso medir a latência enquanto que com um DB chamá-lo pode levar de 15ms a 45ms para completar a chamada e isso não é mesmo considerando outro latência factores ou carga. O outro método que eu uso é a estrutura do objeto bom para os meus dados para que eu só fazer uma atualização DB se algo muda. Eu tenho implementado alguns métodos no meu objeto o Certifique-se de que eu tenho a fazer tão pouco IO possível.

Dito todos nós sabemos que precisamos de acesso e gravação para o nosso DB em algum momento para que eu siga dois princípios:

  1. Mantenha as portas e janelas fechadas para economizar energia. Uma conexão aberta no meio de um lugar que ele não está disponível em outro (ou a memória e outros recursos são mais limitados). Nós transformamos pooling fora porque resultou em melhor desempenho para nós.

  2. Eu faço tanto em lote ou de uma vez como eu posso quando a conexão está aberta. Isto é um pouco mais complicado então deixe-me explicar.

    • um método que eu usei é passar minha conexão objetos para baixo o tubo de modo que todos os objetos pode usar um objeto de conexão. Isso resulta em uma conexão ser aberta e fechada em vez de talvez 10 ou mais, dependendo da sua aplicação. Um bom exemplo disto é um dos nossos modelos de compra que tira proveito do poder do servidor SQL para a recolha de estatísticas e discutir os padrões de ordenação complicados. Não faz sentido manter abrir e fechar a conexão quando você está fazendo pesquisa de 200K + DB ou o que os aplicativos é para. A outra parte para isso é que quando eu uso objeto tento empacotar minhas atualizações para reduzir o tempo que eu manter o aberto conexão. Então, fazendo um SCOPE_IDENTITY no let chamada inserção é me cuidar de ambos minha inserção e uma pesquisa para a identificação única para adicionar ao meu objeto antes de cache-lo. De volta ao dia quando eu estava desenvolvendo asp aplicativos que eu realmente abrir a conexão assim que a página começou a carregar e, em seguida, fechá-lo depois. Eu não recomendo fazer mais isso. Agora, um dia há um grande benefício para esses tipos de abstrações e camadas que eu recomendaria qualquer iniciante programador tomar muita atenção a.

Os meus dois centavos:

Cache seus dados! Armazenar em cache seus dados! Armazenar em cache seus dados! Fazer tão pouco acesso DB possível quando você não pode cache e, em seguida, armazenar em cache seus dados!

Por que re-inventar a roda?

Alguém provavelmente já resolveu o problema, e melhor.

Se você é no mundo Java, você pode usar Commons DBCP .

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