Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Arquitetura SINFO 1.1

26 vues

Publié le

Proposta para melhoria no gerenciamento do pool de conexões na arquitetura dos sistemas SIGs da SINFO/UFRN.

Publié dans : Logiciels
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Arquitetura SINFO 1.1

  1. 1. Arquitetura SINFO 1.1 André Rabelo Raphael Medeiros
  2. 2. Agenda ● Problemas ● O que foi feito? ● Comportamento da solução aplicada ● Impactos ● Mudanças necessárias por parte dos desenvolvedores ● Status atual ● Dúvidas?
  3. 3. Problemas ● Pool de conexões ○ Estouro do pool ■ Muitas conexões sendo requisitadas ao mesmo tempo, onde, toda a quantidade disponível no pool é utilizada ○ Lentidão ■ Quando o pool esta com todas as conexões disponíveis ocupadas, as novas requisições irão ficar a espera de que alguma conexão seja liberada ○ Travamento dos sistemas ■ O pool não possui mais conexões disponíveis, o sistema permanece tentando obter conexões, já com uma grande quantidade de requisições em espera por conexões, o sistema começa a falhar, não retornando resposta aos usuários e por sua vez travando o servidor de aplicação
  4. 4. O que foi feito? ● Mais de 5 abordagens diferentes ○ Tentativa (testes de carga) e Erro (travamento dos sistemas, não devolução do recurso) ● Criação de um Holder (DatabaseResourcesHolder) ○ Controlar conexões ○ Controlar sessões do hibernate ○ Fechamento dos recursos (conexões e sessões do hibernate) ■ ViewFilter ■ MobileFilter ■ TarefaSchedule ● Connection Proxy para não permitir o fechamento das conexões fora do Holder ● A solução é perfeita? ○ Relatórios do Jasper/iReport abrindo conexões através de métodos Helper
  5. 5. Comportamento da solução aplicada ● Pool de 10 conexões no máximo ○ SIPAC ○ Comum ○ LogDB ● 15 threads sendo executadas ○ 4 usuários ● 20 iterações ○ 3 URL’s visitadas ■ /login/ ■ /login.do ■ /telaInicial.do
  6. 6. Comportamento da solução aplicada
  7. 7. Comportamento da solução aplicada
  8. 8. Comportamento da solução aplicada
  9. 9. Comportamento da solução aplicada ● Houve estouro do Pool? ○ Sim, o teste aplicado foi para este fim, fazer o pool trabalhar no limite, assim, sem possibilidade de liberar conexões sempre que requisitado ● Houve lentidão? ○ Sim, no gráfico anterior reparamos que o pico máximo foi de 180.000 milissegundos (3 minutos), mas, o sistema não deixou de responder e devolver recursos ao pool ● Houve travamento do sistema? ○ Não, em nenhum momento o sistema deixou de responder, mesmo com todos os recursos do pool alocados, o sistema não chegou a travar e continuou respondendo e devolvendo os recursos não mais utilizados ao pool
  10. 10. Comportamento da solução aplicada ● Então quais os benefícios? ○ Não houve travamento nos testes aplicados ○ Reaproveitamento das conexões com banco de dados ○ Reaproveitamento das sessões do Hibernate ○ “Garantimos” a devolução da conexão ao Pool de conexões ● Como podemos melhorar? ○ Otimizações de consultas ○ Uso correto de mapeamentos ○ Boas práticas no geral
  11. 11. Impactos ● Objetivos ○ Controle de abertura de conexões e sessões do hibernate ○ Melhoria no desempenho dos sistemas ○ “Garantia” de devolução do recurso (conexão) ao pool ● Consequências ○ Transação, Conexão e Sessão do Hibernate ○ Método ‘dao.refresh’ e ‘JdbcTemplate’ ○ Mapeamentos SET no hibernate ○ Abertura de conexões em relatórios através de métodos *Helper ○ Métodos *NoFlush
  12. 12. Mudanças necessárias por parte dos desenvolvedores ● Entendimento melhor de cada escopo envolvido na camada de persistência ● Uso correto de mapeamentos do hibernate (Set/List) ● Uso adequado do método ‘dao.refresh’ ○ Dentro de uma sessão do hibernate ○ Informação alterada com uso do “createSQLQuery” ● Identificar e corrigir relatórios que abrem conexões por métodos *Helper ○ Buscar métodos (get na maioria das vezes) nas coleções que são passadas aos relatórios que fazem chamadas a métodos *Helper os quais abrem conexões com o banco de dados e executam consultas ● Utilização correta de métodos *NoFlush ○ Usar métodos ‘executeAndFlushClosingResources’
  13. 13. Entendimento melhor de cada escopo envolvido na camada de persistência
  14. 14. Uso adequado do método ‘dao.refresh’ e ‘JdbcTemplate’ ● Há várias situações nos sistemas em que uma entidade possui informações atualizadas via os métodos ‘update,’ ‘updateField’ e ‘updateFields’, os quais, executam um procedimento SQL nativo para atualizar estas informações diretamente no banco de dados.
  15. 15. Uso adequado do método ‘dao.refresh’ e ‘JdbcTemplate’ ● Muitas das vezes o desenvolvedor acaba de atualizar estas informações e em seguida as consulta usando o 'findByPrimaryKey', prática a qual, com as novas modificações na arquitetura, devem gerar erros pois estas informações não serão realmente consultadas ao banco de dados e sim a sessão do hibernate.
  16. 16. Uso adequado do método ‘dao.refresh’ e ‘JdbcTemplate’ ● Então para corrigir estes casos, indica-se o uso do método 'refresh', o qual faz uma atualização dos dados em sessão no hibernate em relação ao banco de dados, assim trazendo a informação mais atual para a sessão.
  17. 17. Uso adequado do método ‘dao.refresh’ e ‘JdbcTemplate’ ● Indica-se o uso do método 'findByPrimaryKey', quando for utilizado o JdbcTemplate para sincronização dos dados em sessão no hibernate em relação ao banco de dados, assim trazendo a informação mais atual para a sessão.
  18. 18. Uso adequado do método ‘dao.refresh’ e ‘JdbcTemplate’ ● Isto é uma prática para resolver os casos apenas trocando o método, mas uma melhor abordagem do código poderia resolver a situação e tornar o fluxo mais eficiente. ● Qual o objetivo de consultar novamente no banco de dados uma informação que conhecemos, esta a qual, acabamos de atualizar?
  19. 19. Uso correto de mapeamentos do hibernate (Set/List)
  20. 20. Uso correto de mapeamentos do hibernate (Set/List)
  21. 21. Uso correto de mapeamentos do hibernate (Set/List)
  22. 22. Uso correto de mapeamentos do hibernate (Set/List) ● Ao executar operações dentro de um processador(contexto transacional) o hibernate força uma sincronização das entidades na Session, causando o ClassCastException.
  23. 23. Uso correto de mapeamentos do hibernate (Set/List)
  24. 24. Uso correto de mapeamentos do hibernate (Set/List)
  25. 25. Uso correto de mapeamentos do hibernate (Set/List) ● Uso do Set (Interface) e suas Implementações ○ O Set quando instanciado como TreeSet não permite outra instanciação, apenas a primeira deve ser mantida; ○ Nos casos em que as coleções devem ser limpas para receber novos valores então o programador deve usar: set.clear(); set.addAll(new TreeSet<?>(Collection)); ● Mapeamentos no Hibernate ○ Mapeamentos que usam <set> devem possuir seus atributos definidos como Set, Collection não deve ser utilizado pois possibilita que o programador utilize a instancia de um ArrayList quando o Hibernate espera que seja um Set;
  26. 26. Identificar e corrigir relatórios que abrem conexões por métodos *Helper ● Existem situações onde coleções que possuem métodos de acesso a atributos fazem chamadas a classes ‘Helpers’, onde muitas delas, fazem chamadas a classes de acesso a dados ‘DAOs’, chamadas que na maioria das vezes abrem conexões com o banco de dados para que a informação necessária seja retornada.
  27. 27. Identificar e corrigir relatórios que abrem conexões por métodos *Helper
  28. 28. Identificar e corrigir relatórios que abrem conexões por métodos *Helper
  29. 29. Identificar e corrigir relatórios que abrem conexões por métodos *Helper ● Invocado no relatório HistoricoComponentesMatriculadosGraduacao.jasper.
  30. 30. Identificar e corrigir relatórios que abrem conexões por métodos *Helper ● No caso acima, o relatório no Jasper receberia uma coleção de históricos, onde estes, por sua vez, são iterados, e para cada histórico, sua coleção de “matriculasDiscente” também é iterada, quando o valor de “getComponenteHATotal()” for recuperado, este irá chamar um Helper, o qual chamará uma DAO, que abrirá uma conexão com o banco de dados. Neste caso, com as alterações feitas na arquitetura, esta conexão será aberta em uma thread a qual não temos o controle, impossibilitando o fechamento desta conexão, assim, possibilitando problemas com o pool de conexões.
  31. 31. Identificar e corrigir relatórios que abrem conexões por métodos *Helper ● Para que este problema seja resolvido, é necessário que TODOS os dados os quais o relatório necessite, sejam consultados antes do processamento do relatório, e assim, a coleção de históricos enviada ao relatório já vá com todos os seus dados populados. Estes casos exigem que, uma refatoração seja feita na consulta onde os dados são populados, antes do processamento do relatório pelo Jasper.
  32. 32. Utilização correta de métodos *NoFlush ● Processamento de inserções e atualizações de N registros por vez (em “lote”) ● Otimização: commit feito no final do processamento com o método GenericDAOImpl.close(). ● Usar métodos ‘AbstractController.executeAndFlushClosingResources(...)’
  33. 33. Utilização correta de métodos *NoFlush
  34. 34. Utilização correta de métodos *NoFlush
  35. 35. Utilização correta de métodos *NoFlush
  36. 36. Utilização correta de métodos *NoFlush
  37. 37. Status atual ● Enviado ao TRUNK do SVN para avaliação dos desenvolvedores ● Recebendo feedbacks sobre problemas identificados ● Será enviada para produção com o SIGRH ou SIPAC
  38. 38. Dúvidas? ● https://goo.gl/WTZGAM (Wiki SINFO - Soluções em Metodologias e Arquitetura Tecnológica) ● Raphael Medeiros ○ Skype: raphael.j.medeiros ● André Rabelo ○ Skype: andre.rabelo.pereira ?

×