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

Arquitetura Web: Escalando Sua Aplicação Além do Hype

Rafael Ponte
February 13, 2019

Arquitetura Web: Escalando Sua Aplicação Além do Hype

(Palestra ministrada no evento CEJS em OUT-2019)

É muito comum evangelizarem que hoje em dia uma aplicação somente escala se utilizarmos micro-serviços, containers, cloud computing e muitos outras tecnologias e práticas da moda, o famigerado HYPE.

Mas será mesmo? Já se perguntou como as aplicações escalavam ANTES desse hype todo? Que tipos de práticas e tecnologias eram utilizadas? Alias, será mesmo que meu sistema web precisa escalar para centenas ou milhares de usuários?

Nessa palestra vamos entender como podemos escalar nosso sistema web SEM se levar pelo hype, partindo de práticas mais simples e baratas até as mais rebuscadas e que precisam de um maior investimento. Se você entende pouco ou quase nada sobre como escalar uma aplicação web, então essa palestra é para você!

Rafael Ponte

February 13, 2019
Tweet

More Decks by Rafael Ponte

Other Decks in Technology

Transcript

  1. JVM

  2. 2Gb

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

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

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

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

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

    entityManager.persist(p); } Persistindo várias entidades
  8. 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
  9. List<Produto> produtos = //... for (Produto p : produtos) {

    entityManager.persist(p); } Persistindo várias entidades
  10. Query : ["INSERT INTO produto(nome, id) VALUES (?, ?)"] Params:

    [(‘Prod.1', 1), (‘Prod.2', 2), (‘Prod.3', 3)] 1 roundtrip
  11. Query : ["INSERT INTO produto(nome, id) VALUES (?, ?)"] Params:

    [('Prod.1', 1), ('Prod.2', 2), (‘Prod.3', 3)] 1 roundtrip
  12. List<Produto> produtos = //... for (Produto p : produtos) {

    p.setNome(p.getNome() .toUpperCase()); } Atualizando várias entidades
  13. Query : [“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. 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);
  18. List<NotaFiscal> notas = dao.lista(); for (NotaFiscal nf : notas) {

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

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

    for (NotaFiscal nf : notas) { processaItensDaNota(nf); }
  21. SELECT nf.* FROM NotaFiscal 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=? ... Hibernate executa n+1 selects List<NotaFiscal> notas = dao.lista(); for (NotaFiscal nf : notas) { processaItensDaNota(nf); }
  22. 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();
  23. entityManager
 .createQuery( " SELECT n FROM NotaFiscal n LEFT JOIN

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

    fetch n.itens")
 .getResultList(); Utilizando Join Fetch LAZY permite mudar para EAGER
  25. List<NotaFiscal> notas = entityManager
 .createQuery( " SELECT n FROM NotaFiscal

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

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

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

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

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

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

    FROM NotaFiscal n WHERE n.tipo = 'DEVOLUCAO'") .getResultList(); DTO Projections
  32. db T = Tacq + Treq + Texec + Tres

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

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

    executa 1 select NotaFiscal nf = entityManger.find(NotaFiscal.class, 42);
  35. 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
  36. 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
  37. 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
  38. @Entity @Cache(...) class Produto { @Id private Long id; private

    String nome; } #2 configuramos as entidades
  39. db T = Tacq + Treq + Texec + Tres

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

    invalidation and naming things.” — Phil Karlton
  41. @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... } }
  42. @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... } }
  43. @Service public class PedidoService { public void finaliza(Pedido pedido) {


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


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

    {
 // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  46. @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!! } }
  47. @Service public class PedidoService { @Autowired private JmsTemplate fila; public

    void finaliza(Pedido pedido) { fila.convertAndSend("fila.pedidos", pedido);
 } }
  48. @Service public class PedidoService { @Autowired private JmsTemplate fila; public

    void finaliza(Pedido pedido) { fila.convertAndSend("fila.pedidos", pedido);
 } }
  49. @Service public class ProcessadorDePedidos { @JmsListener(destination="fila.pedidos") public void processa(Pedido pedido)

    {
 // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  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); // imediato!! } }
  51. 1) tunamos a JVM; 2) tunanamos a camada de persistência;

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

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

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

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

  56. X

  57. =

  58. ip?

  59. ?

  60. ?