Grails: resolvendo o problema de queda de conexão com o MySQL

Você que trabalha com Grails e MySQL já topou com excessões como estas: “com.mysql.jdbc.CommunicationsException: Communications link failure“, “java.net.SocketException: Broken pipe” , “java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.” ?

Normalmente ocorrem após algumas horas de inatividade da sua aplicação. Normalmente acontecem porquê o MySQL fecha as conexões inativas, algumas das quais eram justamente as do seu projeto. Há duas soluções para o problema: uma porca e outra elegante.

A porca é simplesmente não fazer nada: ao mandar recarregar novamente a página será recriada a conexão com o MySQL e parecerá que o problema foi resolvido.

A elegante é alterar a seção dataSource do arquivo grails-app/conf/DataSource.groovy para que fique parecido com o exemplo abaixo:

dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
username = "seu_usuario"
password = "sua_senha"
properties {
 maxActive = 50
 maxIdle = 25
 minIdle = 5
 initialSize = 5
 minEvictableIdleTimeMillis = 60000
 timeBetweenEvictionRunsMillis = 60000
 maxWait = 10000
 validationQuery = "/* ping */"
 }
}

A diferença é a seção properties. Nela basta incluir as configurações do pool de conexões do Hibernate. Por deafult, o Hibernate utiliza como gerenciador de pool de conexões o C3P0 que, por sua vez, evita que você obtenha uma conexão inválida com o banco de dados.

Agora, explicando os parâmetros:

maxActive: número máximo de conexões abertas e ativas com o SGBD
maxIdle: número máximo de conexões em stand by que você quer manter
initialSize: número inicial de conexões com o banco de dados
minEvictableIdleTimeMillis: tempo mínimo em milisegundos para que o pool de conexões comece a fechar conexões em idle
timeBetweenEvictionRunsMillis: o tempo entre as limpezas de conexão em milisegundos
maxWait: tempo máximo de espera em milisegundos para se obter uma conexão ou de espera de resultado de uma conexão
validationQuery: qualquer comando a ser enviado para o SGBD apenas para verificar se a conexão está válida ou não.

E é isto: agora seus usuários (e você) não verão mais aquela maldita mensagem de erro ao acessar seu sistema pela manhã


Publicado

em

, , ,

por

Tags:

Comentários

11 respostas para “Grails: resolvendo o problema de queda de conexão com o MySQL”

  1. Avatar de wanderson santos
    wanderson santos

    Resolvemos este problema a pouco tempo desta forma.

    É como se o mysql fechasse uma conexao que tah na fila (pool) e ela nao saisse da fila.

    Parabens por compartilhar com todos! :)

    1. Avatar de admin
      admin

      Oi Wanderson, valeu!

      Na realidade, é exatamente isto que você descreveu que acontece. O MySQL tem um tempo limite de vida para todas as conexões estabelecidas (é possível alterar este tempo no arquivo my.cnf ou my.ini dependendo da sua distribuição do SGBD inclusive).

      O problema é que nem sempre podemos alterar estas configurações. Sendo assim, o que acontece: após um tempo x, o MySQL pensa (e ele está correto nesta lógica) que aquela conexão não tem mais utilidade e simplesmente a mata. O problema é que a aplicação cliente ainda acredita ter uma conexão válida. Sendo assim, no momento em que vai fazer uma consulta ou enviar um comando para o SGBD, da de cara com uma conexão inválida.

      Como nem sempre podemos definir o tempo de vida de uma conexão no servidor, esta é a melhor alternativa que conheço.

  2. Avatar de Bruno
    Bruno

    Esse problema só acontece com o MySQL ou acontece com o Postgres também?

    1. Avatar de admin
      admin

      Na realidade pode acontecer com qualquer SGBD

  3. Avatar de Bruno
    Bruno

    Entao é sempre bom ter essas configurações?!

    Muito bom, parabéns.

    1. Avatar de admin
      admin

      Altamente recomendado! Valeu!

  4. Avatar de djabaru
    djabaru

    nice muito bom tava ter esses bugs

  5. Avatar de jean
    jean

    é só colocar esse mesmo código no arquivo?
    ou tem que fazer alguma modificação?
    qual tempo a app pode ficar inativa sem da erro depois de usar esse codigo?

    1. Avatar de Kico (Henrique Lobo Weissmann)
      Kico (Henrique Lobo Weissmann)

      Só precisa alterar o driver caso seja um banco diferente do MySQL.

      A aplicação após isto pode ficar inativa o tempo que for.

  6. Avatar de Davi
    Davi

    Boa tarde,

    Como eu consigo colocar essa propriedades no hibernate?

    Utilizando o c3po ?

    1. Avatar de Kico (Henrique Lobo Weissmann)
      Kico (Henrique Lobo Weissmann)

      Oi Davi, estas dúvidas eu costmo resolver no Grails Brasil (http://www.grailsbrasil.com.br).
      Rola de você postar a dúvida por lá?

Deixe uma resposta

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.