Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pilares da Escalabilidade: Estratégias de Otimização e Melhoria de Performance

Rafael Ponte
September 06, 2023

Pilares da Escalabilidade: Estratégias de Otimização e Melhoria de Performance

Conheça os 3 pilares para escalar qualquer aplicação web e distribuída, partindo de passos mais simples e baratos até passos mais rebuscados e complexos.

(PS: melhorar descrição)

Rafael Ponte

September 06, 2023
Tweet

More Decks by Rafael Ponte

Other Decks in Technology

Transcript

  1. Se você não tem pré- requisito de desempenho ou throughput

    então você não tem problema de escala.
  2. https://www.youtube.com/watch?v=GBTdnfD6s5Q “ Eu não escrevi um livro sobre microservices, mas

    sim sobre como você arquiteta para Entrega Contínua. ” — Sam Newman
  3. JVM

  4. 2Gb

  5. db T = Tacq + Treq + Texec + Tres

    apresentação negócio persistência
  6. db T = Tacq + Treq + Texec + Tres

    + Tidle apresentação negócio persistência
  7. db T = Tacq + Treq + Texec + Tres

    + Tidle apresentação negócio persistência
  8. db T = Tacq + Treq + Texec + Tres

    + Tidle apresentação negócio persistência
  9. List<Produto> produtos = //... for (Produto p : produtos) {

    entityManager.persist(p); } Persistindo várias entidades
  10. INSERT INTO produto(nome, id) VALUES ('Prod.1', 1) INSERT INTO produto(nome,

    id) VALUES ('Prod.2', 2) INSERT INTO produto(nome, id) VALUES ('Prod.3', 3) INSERT INTO ... 3 roundtrips
  11. List<Produto> produtos = //... for (Produto p : produtos) {

    entityManager.persist(p); } Persistindo várias entidades
  12. List<Produto> produtos = //... for (Produto p : produtos) {

    p.setNome(p.getNome() .toUpperCase()); } Atualizando várias entidades
  13. UPDATE produto SET nome = ? WHERE id = ?

    Params: [('PROD.1', 1), ('PROD.2', 2), ('PROD.3', 3)] 1 roundtrip
  14. List<Produto> produtos = //... for (Produto p : produtos) {

    entityManager.remove(p); } Removendo várias entidades
  15. db T = Tacq + Treq + Texec + Tres

    + Tidle apresentação negócio persistência
  16. Processando os itens de uma nota NotaFiscal nf = entityManager

    .find(NotaFiscal.class, 42); 
 processaItensDaNota(nf);
  17. Processando os itens de uma nota NotaFiscal nf = entityManager

    .find(NotaFiscal.class, 42); 
 processaItensDaNota(nf);
  18. SELECT nf.* FROM NotaFiscal nf WHERE nf.id = 42 Hibernate

    executa 2 selects NotaFiscal nf = entityManger.find(NotaFiscal.class, 42);
  19. SELECT nf.* FROM NotaFiscal nf WHERE nf.id = 42 SELECT

    i.* FROM Item i WHERE i.nota_fiscal_id = 42 Hibernate executa 2 selects NotaFiscal nf = entityManger.find(NotaFiscal.class, 42); processaItensDaNota(nf);
  20. List<NotaFiscal> notas = dao.lista(); for (NotaFiscal nf : notas) {

    processaItensDaNota(nf); } Processando os itens de varias notas
  21. Processando os itens de varias notas List<NotaFiscal> notas = dao.lista();

    for (NotaFiscal nf : notas) { processaItensDaNota(nf); }
  22. Processando os itens de varias notas List<NotaFiscal> notas = dao.lista();

    for (NotaFiscal nf : notas) { processaItensDaNota(nf); }
  23. SELECT nf.* FROM NotaFiscal nf Hibernate executa n+1 selects List<NotaFiscal>

    notas = dao.lista(); for (NotaFiscal nf : notas) { processaItensDaNota(nf); } SELECT i.* FROM Item i WHERE i.nota_fiscal_id=? SELECT i.* FROM Item i WHERE i.nota_fiscal_id=? SELECT i.* FROM Item i WHERE i.nota_fiscal_id=? SELECT i.* FROM Item i WHERE i.nota_fiscal_id=? SELECT i.* FROM Item i WHERE i.nota_fiscal_id=? ...
  24. SELECT nf.*, i.* FROM NotaFiscal nf LEFT OUTER JOIN Item

    i ON nf.id = i.nota_fiscal_id
 Hibernate executa 1 select List<NotaFiscal> notas = dao.lista();
  25. entityManager
 .createQuery( "SELECT n FROM NotaFiscal n LEFT JOIN fetch

    n.itens")
 .getResultList(); Utilizando Join Fetch
  26. entityManager
 .createQuery( "SELECT n FROM NotaFiscal n LEFT JOIN fetch

    n.itens")
 .getResultList(); Utilizando Join Fetch habilita EAGER em mapeamentos LAZY
  27. List<NotaFiscal> notas = entityManager
 .createQuery( “SELECT n FROM NotaFiscal n

    WHERE n.tipo = 'DEVOLUCAO'")
 .getResultList(); DTO Projections
  28. List<NotaFiscal> notas = entityManager
 .createQuery( “SELECT n.numero, n.serie FROM NotaFiscal

    n WHERE n.tipo = 'DEVOLUCAO'")
 .getResultList(); DTO Projections
  29. List<NotaFiscal> notas = entityManager
 .createQuery( "SELECT n.numero, n.serie FROM NotaFiscal

    n WHERE n.tipo = 'DEVOLUCAO'") .getResultList(); DTO Projections
  30. List<?????> notas = entityManager
 .createQuery( "SELECT n.numero, n.serie FROM NotaFiscal

    n WHERE n.tipo = 'DEVOLUCAO'") .getResultList(); DTO Projections
  31. class Devolucao { Integer numero; String serie; public Devolucao(Integer n,

    String s) { this.numero = n; this.serie = s; } // getters e setters } Criando o DTO
  32. List<Devolucao> notas = entityManager
 .createQuery( "SELECT n.numero, n.serie FROM NotaFiscal

    n WHERE n.tipo = 'DEVOLUCAO'") .getResultList(); DTO Projections
  33. List<Devolucao> notas = entityManager
 .createQuery( “SELECT new Devolucao(n.numero, n.serie) FROM

    NotaFiscal n WHERE n.tipo = 'DEVOLUCAO'") .getResultList(); DTO Projections
  34. List<Devolucao> notas = entityManager
 .createQuery( “SELECT new Devolucao(n.numero, n.serie) FROM

    NotaFiscal n WHERE n.tipo = 'DEVOLUCAO'") .getResultList(); Paginação
  35. List<Devolucao> notas = entityManager
 .createQuery( “SELECT new Devolucao(n.numero, n.serie) FROM

    NotaFiscal n WHERE n.tipo = 'DEVOLUCAO'") .setMaxResults(100) .getResultList(); Paginação
  36. List<Devolucao> notas = entityManager
 .createQuery( “SELECT new Devolucao(n.numero, n.serie) FROM

    NotaFiscal n WHERE n.tipo = 'DEVOLUCAO'") .setMaxResults(100) .getResultList(); Paginação
  37. SELECT nf.numero, nf.serie FROM NotaFiscal nf WHERE nf.tipo = ‘DEVOLUCAO'

    LIMIT 100 SQL otimizado List<Devolucao> notas = //...
  38. db T = Tacq + Treq + Texec + Tres

    + Tidle apresentação negócio persistência
  39. EM

  40. SELECT nf.* FROM NotaFiscal nf WHERE nf.id = 42 Hibernate

    executa 1 select NotaFiscal nf = entityManger.find(NotaFiscal.class, 42);
  41. NotaFiscal nf1 = entityManager .find(NotaFiscal.class, 42); 
 NotaFiscal nf2 =

    entityManager .find(NotaFiscal.class, 42); NotaFiscal nf3 = entityManager .find(NotaFiscal.class, 42); Carregando uma nota por ID
  42. NotaFiscal nf1 = entityManager .find(NotaFiscal.class, 42); 
 NotaFiscal nf2 =

    entityManager .find(NotaFiscal.class, 42); NotaFiscal nf3 = entityManager .find(NotaFiscal.class, 42); Carregando uma nota por ID
  43. SELECT nf.* FROM NotaFiscal nf WHERE nf.id = 42 Hibernate

    executa 1 select NotaFiscal nf1 = entityManger.find(NotaFiscal.class, 42);
  44. SELECT nf.* FROM NotaFiscal nf WHERE nf.id = 42 Hibernate

    executa 1 select NotaFiscal nf1 = entityManger.find(NotaFiscal.class, 42); NotaFiscal nf2 = entityManger.find(NotaFiscal.class, 42); // sem SQL
  45. SELECT nf.* FROM NotaFiscal nf WHERE nf.id = 42 Hibernate

    executa 1 select NotaFiscal nf1 = entityManger.find(NotaFiscal.class, 42); NotaFiscal nf2 = entityManger.find(NotaFiscal.class, 42); NotaFiscal nf3 = entityManger.find(NotaFiscal.class, 42); // sem SQL // sem SQL
  46. @Entity @Cache(...) class Produto { @Id private Long id; private

    String nome; } #2 con fi guramos as entidades
  47. db T = Tacq + Treq + Texec + Tres

    + Tidle apresentação negócio persistência
  48. “There are only two hard things in Computer Science: cache

    invalidation and naming things.” — Phil Karlton
  49. @Controller public class PedidoController { @Autowired public PedidoService service; @PostMapping(path="/vendas/finaliza",

    ...) public void finalizaPedido(Pedido pedido) { // faz alguma validação de dados 
 service.finaliza(pedido); // demorado... } }
  50. @Controller public class PedidoController { @Autowired public PedidoService service; @PostMapping(path="/vendas/finaliza",

    ...) public void finalizaPedido(Pedido pedido) { // faz alguma validação de dados 
 service.finaliza(pedido); // demorado... } }
  51. @Service public class PedidoService { public void finaliza(Pedido pedido) {

    
 // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  52. @Service public class PedidoService { public void finaliza(Pedido pedido) {

    
 // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  53. @Service public class PedidoService { @Async public void finaliza(Pedido pedido)

    { 
 // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  54. @Controller public class PedidoController { @Autowired public PedidoService service; @PostMapping(path="/vendas/finaliza",

    ...) public void finalizaPedido(Pedido pedido) { // faz alguma validação de dados 
 service.finaliza(pedido); } }
  55. @Controller public class PedidoController { @Autowired public PedidoService service; @PostMapping(path="/vendas/finaliza",

    ...) public void finalizaPedido(Pedido pedido) { // faz alguma validação de dados 
 service.finaliza(pedido); } } IMEDIATO!
  56. @Controller public class PedidoController { @Autowired public PedidoService service; @PostMapping(path="/vendas/finaliza",

    ...) public void finalizaPedido(Pedido pedido) { // faz alguma validação de dados 
 service.finaliza(pedido); } }
  57. @Controller public class PedidoController { @Autowired public PedidoService service; @PostMapping(path="/vendas/finaliza",

    ...) public void finalizaPedido(Pedido pedido) { // faz alguma validação de dados 
 service.finaliza(pedido); } }
  58. @Controller public class PedidoController { @Autowired public JmsTemplate fila; @PostMapping(path="/vendas/finaliza",

    ...) public void finalizaPedido(Pedido pedido) { // faz alguma validação de dados 
 fila.convertAndSend("fila.pedidos", pedido); } }
  59. @Service public class PedidoService { @Async public void finaliza(Pedido pedido)

    { 
 // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  60. @Service public class PedidoService { @Async public void finaliza(Pedido pedido)

    { 
 // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  61. @Service public class PedidoService { @JmsListener(destination="fila.pedidos") public void finaliza(Pedido pedido)

    { 
 // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  62. @Controller public class PedidoController { @Autowired public JmsTemplate fila; @PostMapping(path="/vendas/finaliza",

    ...) public void finalizaPedido(Pedido pedido) { // faz alguma validação de dados 
 fila.convertAndSend("fila.pedidos", pedido); } } IMEDIATO!
  63. 1) tunamos a JVM; 2) tunanamos a camada de persistência;

    3) adicionamos caching; 4) adicionamos processamento assincrono;
  64. 1) tunamos a JVM; 2) tunamos a camada de persistência;

    3) adicionamos caching; 4) adicionamos processamento assincrono;
  65. 1) tunamos a JVM; 2) tunamos a camada de persistência;

    3) adicionamos caching; 4) adicionamos processamento assincrono;
  66. 1) tunamos a JVM; 2) tunamos a camada de persistência;

    3) adicionamos caching; 4) adicionamos processamento assincrono;
  67. X

  68. X

  69. =

  70. ip?

  71. ?

  72. ?