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

Arquitetura Java: Escalando do Monolito ao Microservices

Arquitetura Java: Escalando do Monolito ao Microservices

É muito comum evangelizarem que hoje em dia uma aplicação somente escala se utilizarmos microsserviç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ê!

(GRAVAÇÃO: https://youtu.be/uoLTYZL6qWo?list=PLHMMERsvy9EyWQPru4SrJAYHEGKfkjRgP&t=586)

Rafael Ponte

August 26, 2020
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. db T = Tacq + Treq + Texec + Tres

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

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

    executa 1 select NotaFiscal nf = entityManger.find(NotaFiscal.class, 42);
  37. 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
  38. 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
  39. SELECT nf.* FROM NotaFiscal nf WHERE nf.id = 42 Hibernate

    executa 1 select NotaFiscal nf1 = entityManger.find(NotaFiscal.class, 42);
  40. 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
  41. 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
  42. @Entity @Cache(...) class Produto { @Id private Long id; private

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

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

    invalidation and naming things.” — Phil Karlton
  45. @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... } }
  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); // demorado... } }
  47. @Service public class PedidoService { public void finaliza(Pedido pedido) {

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

    // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  49. @Service public class PedidoService { @Async public void finaliza(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); } }
  51. @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!
  52. @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); } }
  53. @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); } }
  54. @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); } }
  55. @Service public class PedidoService { @Async public void finaliza(Pedido pedido)

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

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

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

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

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

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

  64. X

  65. =

  66. ip?

  67. ?

  68. ?