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. ARQUITETURA JAVA escalando do monolito ao microservices

  2. ahh o hype…

  3. Hype-Driven Development https://blog.daftcode.pl/hype-driven-development-3469fc2e9b22

  4. Desenvolvimento Orientado a Modinha https://desenvolvimentoparaweb.com/miscelanea/desenvolvimento-orientado-a-modinha-dom/

  5. Anatomia de um Hype https://desenvolvimentoparaweb.com/miscelanea/desenvolvimento-orientado-a-modinha-dom/ Retorno para "sanidade" Agora entendemos

    onde utilizar
 e seus prós e contras
  6. Anatomia de um Hype https://desenvolvimentoparaweb.com/miscelanea/desenvolvimento-orientado-a-modinha-dom/

  7. Anatomia de um Hype https://desenvolvimentoparaweb.com/miscelanea/desenvolvimento-orientado-a-modinha-dom/

  8. Anatomia de um Hype https://desenvolvimentoparaweb.com/miscelanea/desenvolvimento-orientado-a-modinha-dom/

  9. Anatomia de um Hype https://desenvolvimentoparaweb.com/miscelanea/desenvolvimento-orientado-a-modinha-dom/

  10. Anatomia de um Hype https://desenvolvimentoparaweb.com/miscelanea/desenvolvimento-orientado-a-modinha-dom/ Retorno para "sanidade" Agora entendemos

    onde utilizar
 e seus prós e contras
  11. None
  12. None
  13. None
  14. …e de todas as modas

  15. None
  16. https://deniseyu.io/art/

  17. https://deniseyu.io/art/

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

    então você não tem problema de escala.
  20. None
  21. Microservices não existe para escalar aplicações, mas sim para escalar

    times.
  22. None
  23. None
  24. None
  25. None
  26. o hype se retroalimenta

  27. E com microservices não seria diferente…

  28. Anatomia de um Hype https://desenvolvimentoparaweb.com/miscelanea/desenvolvimento-orientado-a-modinha-dom/ Retorno para "sanidade" Agora entendemos

    onde utilizar
 e seus prós e contras
  29. Anatomia de um Hype https://desenvolvimentoparaweb.com/miscelanea/desenvolvimento-orientado-a-modinha-dom/ Retorno para "sanidade" Agora entendemos

    onde utilizar
 e seus prós e contras
  30. https://www.infoq.com/presentations/microservices-panel-value/

  31. https://www.infoq.com/presentations/microservices-panel-value/ https://www.infoq.com/news/2020/05/monolith-decomposition-newman/

  32. https://www.youtube.com/watch?v=GBTdnfD6s5Q

  33. 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
  34. None
  35. The monolith to microservices SPECTRUM https://chrisscott.me/the-monolith-to-microservice-spectrum/

  36. The monolith to microservices SPECTRUM https://chrisscott.me/the-monolith-to-microservice-spectrum/

  37. The monolith to microservices SPECTRUM https://chrisscott.me/the-monolith-to-microservice-spectrum/

  38. The monolith to microservices SPECTRUM https://chrisscott.me/the-monolith-to-microservice-spectrum/

  39. Um bom arquiteto escolhe tecnologias por suas DESVANTAGENS

  40. https://twitter.com/argentinomota/status/1222941731424960515?s=20

  41. podemos escalar SEM o hype?

  42. podemos escalar SEM o hype?

  43. podemos escalar SEM o hype?

  44. podemos escalar SEM o hype?

  45. “ Monolito não escala! Uma aplicação só escala com Microservices!

  46. Rafael Ponte @rponte

  47. None
  48. Fortaleza - Terra do Sol

  49. None
  50. ARQUITETURA JAVA escalando do monolito ao microservices

  51. Como escalar minha app para MILHARES de usuários?

  52. Loja Virtual

  53. None
  54. Revisitando a Web…

  55. servidor

  56. servidor

  57. navegador servidor

  58. navegador servidor requisição

  59. navegador servidor db requisição

  60. navegador servidor db requisição resposta

  61. navegador servidor db requisição resposta

  62. 2 conceitos importantes

  63. Performance X Escalabilidade

  64. tempo de resposta (response time) performance

  65. tempo de resposta (response time) performance

  66. navegador servidor db requisição resposta

  67. navegador servidor db requisição resposta tempo resposta

  68. navegador servidor db requisição resposta tempo resposta: 100ms

  69. operações / unidade_tempo (throughput) escalabilidade

  70. operações / unidade_tempo (throughput) escalabilidade

  71. usuários / minuto (throughput) escalabilidade

  72. usuários / segundo (throughput) escalabilidade

  73. usuários / segundo (throughput) escalabilidade

  74. requisições / segundo (throughput) escalabilidade

  75. navegador servidor db requisição resposta

  76. navegador servidor db requisição resposta tempo resposta: 100ms

  77. servidor db requisição resposta tempo resposta: 100ms

  78. servidor db requisição resposta tempo resposta: 100ms

  79. servidor db requisição resposta tempo resposta: 1s

  80. servidor db requisição resposta tempo resposta: 7s

  81. servidor db requisição resposta tempo resposta: 24s

  82. servidor db requisição resposta tempo resposta: 0

  83. nossa aplicação não escala mais do que: 80 req/s

  84. navegador servidor db requisição resposta throughput: 80 req/s

  85. navegador servidor db requisição resposta throughput: 250 req/s

  86. navegador servidor db requisição resposta throughput: 1000 req/s

  87. PASSOS 5 RESUMINDO EM

  88. Passo 1 (TUNANDO A APLICAÇÃO)

  89. navegador servidor db requisição resposta

  90. navegador servidor db requisição resposta

  91. None
  92. None
  93. None
  94. None
  95. None
  96. None
  97. JVM

  98. None
  99. 2Gb

  100. 2Gb ???

  101. 2Gb 256Mb

  102. 2Gb ??Mb

  103. 2Gb 2Gb

  104. 2Gb 2Gb =

  105. 2Gb 2Gb = X

  106. 2Gb 1Gb

  107. 2Gb 1Gb -Xms256m -Xmx1024m 
 -XX:MaxPermSize=192m

  108. 2Gb 1Gb -Xms256m -Xmx1024m 
 -XX:MaxPermSize=192m

  109. 2Gb 1Gb -Xms256m -Xmx1024m 
 -XX:MaxPermSize=192m minimo != maximo

  110. 2Gb 1Gb -Xms1024m -Xmx1024m 
 -XX:MaxPermSize=192m minimo = maximo

  111. 2Gb 1Gb -Xms1024m -Xmx1024m 
 -XX:MaxPermSize=192m Heap Size

  112. 2Gb 1Gb -Xms1024m -Xmx1024m 
 -XX:MaxPermSize=192m

  113. 2Gb 1Gb -Xms1024m -Xmx1024m 
 -XX:MaxPermSize=192m PermGen Size

  114. 2Gb 1Gb

  115. 2Gb 1Gb -Xms1024m -Xmx1024m 
 -XX:MaxPermSize=192m memoria

  116. 2Gb 1Gb -Xms1024m -Xmx1024m 
 -XX:MaxPermSize=192m -server modo servidor memoria

  117. 2Gb 1Gb -Xms1024m -Xmx1024m 
 -XX:MaxPermSize=192m -XX:+UseConcMarkSweepGC
 -XX:+CMSParallelRemarkEnabled -server modo

    servidor memoria coletor de lixo (GC)
  118. Ganhou fôlego, mas…

  119. navegador servidor db requisição resposta

  120. servidor Aplicação

  121. servidor

  122. servidor Produto.java Venda.java BancoDeDados.java FinalizarCompra.java Pagamento.java carrinhoDeCompras.jsp index.jsp site.css app.js

    GravaProduto.java EnviaEmail.java GravaProdutoServlet.java finalizar-compra.jsp
  123. servidor

  124. servidor

  125. servidor

  126. Divisão de Camadas

  127. servidor

  128. servidor modelo

  129. servidor modelo telas

  130. servidor modelo acesso a dados telas

  131. servidor apresentação negócio persistência camadas

  132. servidor apresentação negócio persistência controle das telas camadas

  133. servidor apresentação negócio persistência controle das telas logica de negocio

    camadas
  134. servidor apresentação negócio persistência controle das telas logica de negocio

    acesso a banco e dados camadas
  135. servidor apresentação negócio persistência camadas

  136. servidor apresentação negócio persistência camadas

  137. servidor apresentação negócio persistência camadas

  138. servidor apresentação negócio persistência camadas

  139. servidor apresentação negócio persistência camadas

  140. servidor apresentação negócio persistência camadas

  141. navegador servidor db requisição resposta

  142. navegador servidor db requisição resposta tempo resposta: 1000ms

  143. navegador servidor db requisição resposta tempo resposta: 1000ms 700ms

  144. navegador servidor db requisição resposta tempo resposta: 1000ms 700ms

  145. servidor db

  146. db apresentação negócio persistência

  147. db apresentação negócio persistência Transaction Response Time

  148. db T = apresentação negócio persistência

  149. db T = Tacq apresentação negócio persistência

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

  151. db T = Tacq + Treq + Texec apresentação negócio

    persistência
  152. db T = Tacq + Treq + Texec + Tres

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

    + Tidle apresentação negócio persistência
  154. quanto menor o transaction response time, maior o throughput

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

    + Tidle apresentação negócio persistência
  156. navegador servidor db

  157. navegador servidor db 1 requisição 1 conexão

  158. navegador servidor db 10 requisições 10 conexões

  159. navegador servidor db 100 requisições 100 conexões

  160. navegador servidor db 1000 requisições 1000 conexões

  161. navegador servidor db 1001 requisições 0 conexões

  162. Criar conexões é CARO!

  163. navegador db app

  164. navegador db app

  165. navegador db app

  166. navegador db app ini=5

  167. db app ini=5

  168. db app … max=30 ini=5

  169. db app … max=30 ini=5

  170. db app min=3 max=30 ini=5

  171. navegador db connection pool app min=3 max=30 ini=5 …

  172. quanto mais rápido obter uma conexão, menor o response time

  173. mas qual o tamanho ideal do pool?

  174. https://mobile.twitter.com/Nick_Craver/status/969043553711218691

  175. mensure!

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

    + Tidle apresentação negócio persistência
  177. Habilite o Batch Size

  178. @Entity public class Produto { @Id @GeneratedValue private Integer id;

    private String nome; // outros atributos }
  179. List<Produto> produtos = //... for (Produto p : produtos) {

    entityManager.persist(p); } Persistindo várias entidades
  180. 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
  181. <property name="hibernate.jdbc.batch_size" value="5" /> persistence.xml

  182. List<Produto> produtos = //... for (Produto p : produtos) {

    entityManager.persist(p); } Persistindo várias entidades
  183. INSERT INTO produto(nome, id) VALUES (?, ?) Params: [('Prod.1', 1),

    ('Prod.2', 2), ('Prod.3', 3)] 1 roundtrip
  184. Params: [('Prod.1', 1), ('Prod.2', 2), (‘Prod.3', 3)] 1 roundtrip INSERT

    INTO produto(nome, id) VALUES (?, ?)
  185. Para UPDATE e DELETE também

  186. List<Produto> produtos = //... for (Produto p : produtos) {

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

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

    entityManager.remove(p); } Removendo várias entidades
  189. DELETE FROM produto WHERE id = ? Params: [(1), (2),

    (3)] 1 roundtrip
  190. quanto menos roundtrips ao banco, menor o response time

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

    + Tidle apresentação negócio persistência
  192. Use Consultas Planejadas (DTO Projections)

  193. @Entity class NotaFiscal { … @OneToMany List<Item> itens; }

  194. NotaFiscal nf = entityManager .find(NotaFiscal.class, 42); 
 processaItensDaNota(nf); Processando os

    itens de uma nota
  195. Processando os itens de uma nota NotaFiscal nf = entityManager

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

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

    executa 2 selects NotaFiscal nf = entityManger.find(NotaFiscal.class, 42);
  198. 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);
  199. List<NotaFiscal> notas = dao.lista(); for (NotaFiscal nf : notas) {

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

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

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

    notas = dao.lista();
  203. 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=? ...
  204. são muitos hits ao banco (Select N+1)

  205. são muitos hits ao banco (Select N+1)

  206. solução?

  207. @Entity class NotaFiscal { … @OneToMany(fetch=FetchType.EAGER) List<Item> itens; } Utilizando

    FetchMode=EAGER
  208. 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();
  209. antes de definir um mapeamento global deste tipo você precisa

    se perguntar...
  210. SEMPRE que uma Nota é carregada, todos seus Itens também

    são necessários?
  211. não?

  212. @Entity class NotaFiscal { … @OneToMany(fetch=FetchType.LAZY) List<Item> itens; } Utilizando

    FetchMode=LAZY
  213. entityManager
 .createQuery( "SELECT n FROM NotaFiscal n LEFT JOIN fetch

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

    n.itens")
 .getResultList(); Utilizando Join Fetch habilita EAGER em mapeamentos LAZY
  215. Opa! Não para aí…

  216. SEMPRE que uma Nota é carregada, TODAS as colunas são

    necessárias?
  217. não?

  218. List<NotaFiscal> notas = entityManager
 .createQuery( “SELECT n FROM NotaFiscal n

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

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

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

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

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

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

    NotaFiscal n WHERE n.tipo = 'DEVOLUCAO'") .getResultList(); DTO Projections
  225. SELECT nf.numero, nf.serie FROM NotaFiscal nf WHERE nf.tipo = 'DEVOLUCAO'

    SQL otimizado List<Devolucao> notas = //...
  226. quanto menor a quantidade de dados recuperados, menor o response

    time
  227. db T = Tacq + Treq + Texec + Tres

    + Tidle apresentação negócio persistência
  228. Como otimizar minha query?

  229. SQL Nativo (deixe seu banco trabalhar)

  230. Stored Procedures (leve o processamento para os dados)

  231. None
  232. DBA (peça ajuda)

  233. mesmo com todas essas melhorias…

  234. …PICOS de acessos podem aumentar nosso response time

  235. Caching (aliviando o banco de dados)

  236. NotaFiscal nf = entityManager .find(NotaFiscal.class, 42); 
 Carregando uma nota

    por ID
  237. None
  238. EM

  239. Banco de Dados EM

  240. Banco de Dados EM NotaFiscal nf = entityManager .find(NotaFiscal.class, 42);

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

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

    executa 1 select NotaFiscal nf1 = entityManger.find(NotaFiscal.class, 42);
  245. 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
  246. 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
  247. Banco de Dados EM

  248. Banco de Dados EM First Level Cache

  249. Banco de Dados EM

  250. Banco de Dados EM EM EM EM

  251. Banco de Dados ???? EM EM EM EM

  252. Banco de Dados Second Level Cache EM EM EM EM

  253. Banco de Dados Second Level Cache EM Session Session Session

    EM EM EM First Level Cache
  254. Banco de Dados EntityManagerFactory EM EM EM EM

  255. <property name="hibernate.cache.second_level_cache" value="true" /> persistence.xml #1 habilitamos o cache

  256. @Entity @Cache(...) class Produto { @Id private Long id; private

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

    + Tidle apresentação negócio persistência
  258. a consulta mais rápida é aquela que nem chega no

    banco de dados
  259. db apresentação negócio persistência

  260. db apresentação negócio persistência

  261. db negócio persistência apresentação

  262. “There are only two hard things in Computer Science: cache

    invalidation and naming things.” — Phil Karlton
  263. navegador servidor db requisição resposta Performance Consistência

  264. E se houver um processamento PESADO?

  265. @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... } }
  266. @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... } }
  267. @Service public class PedidoService { public void finaliza(Pedido pedido) {

    // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  268. navegador servidor db

  269. navegador servidor db

  270. navegador servidor db

  271. se a execução é custosa então ela é um possível

    gargalo…
  272. Assincronicidade (processa mais tarde)

  273. @Service public class PedidoService { public void finaliza(Pedido pedido) {

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

    { // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  275. Spring usa um pool de threads

  276. @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); } }
  277. @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!
  278. …e se além de custosa ela também for em grande

    quantidade?
  279. poderíamos usar uma fila…

  280. navegador servidor db

  281. navegador servidor db X

  282. navegador servidor db fila

  283. navegador servidor db fila

  284. navegador servidor db fila

  285. navegador servidor db fila

  286. navegador servidor db fila

  287. @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); } }
  288. @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); } }
  289. @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); } }
  290. e em algum momento um processo consumiria a fila…

  291. navegador servidor db fila

  292. navegador servidor db fila consumidor

  293. servidor db fila consumidor navegador

  294. servidor db fila consumidor navegador

  295. servidor db fila consumidor navegador

  296. @Service public class PedidoService { @Async public void finaliza(Pedido pedido)

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

    { // efetua pagamento // dá baixa no estoque // atualiza pedido // envia email de confirmação } }
  298. @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 } }
  299. no fim nossa requisição continuaria respondendo imediatamente

  300. @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!
  301. Wow!!

  302. 1) tunamos a JVM; 2) tunanamos a camada de persistência;

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

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

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

    3) adicionamos caching; 4) adicionamos processamento assincrono;
  306. Sistema não aguenta?

  307. Passo 2 (MELHORANDO A MÁQUINA)

  308. navegador servidor db requisição resposta

  309. navegador servidor db requisição resposta

  310. cpu memoria

  311. None
  312. None
  313. X

  314. None
  315. None
  316. None
  317. x 6 x 6

  318. Mais requisições?

  319. None
  320. None
  321. None
  322. Escalabilidade Vertical (scale up)

  323. None
  324. None
  325. None
  326. None
  327. None
  328. None
  329. None
  330. X

  331. Sistema não aguenta?

  332. Passo 3 (ADICIONANDO MAIS MÁQUINAS)

  333. navegador servidor db requisição resposta

  334. navegador servidor db requisição resposta

  335. None
  336. None
  337. =

  338. None
  339. None
  340. None
  341. ip?

  342. None
  343. None
  344. None
  345. 200 reqs

  346. 200 reqs 100 reqs 100 reqs

  347. Balanceador de Carga

  348. Balanceador de Carga

  349. Balanceador de Carga

  350. None
  351. Mais requisições?

  352. None
  353. None
  354. None
  355. None
  356. Cluster

  357. None
  358. None
  359. Escalabilidade Horizontal (scale out)

  360. Apesar de mais barata…

  361. None
  362. (1a requisição)

  363. (1a requisição)

  364. Sessão

  365. (2a requisição) qual?

  366. (2a requisição)

  367. (2a requisição)

  368. Sticky Session

  369. Mas e se…

  370. None
  371. None
  372. None
  373. None
  374. None
  375. None
  376. None
  377. None
  378. None
  379. ?

  380. ?

  381. Falta Redundância

  382. Passo 4 (REPLICANDO ESTADO)

  383. None
  384. (1a requisição)

  385. (1a requisição)

  386. (2a requisição)

  387. (2a requisição) qual?

  388. (2a requisição)

  389. (2a requisição)

  390. None
  391. Session Replication

  392. None
  393. None
  394. None
  395. None
  396. Replica Estado

  397. None
  398. Alta Disponibilidade (high availability)

  399. Mais requisições?

  400. None
  401. None
  402. None
  403. None
  404. Se tenho mais máquinas…

  405. None
  406. None
  407. None
  408. None
  409. Replicar sessão é CARO

  410. Passo 5 (REMOVENDO ESTADO)

  411. None
  412. None
  413. None
  414. None
  415. X X X X X

  416. None
  417. ONDE?

  418. None
  419. None
  420. None
  421. None
  422. None
  423. Cache Distribuído

  424. Cache Distribuído

  425. Cache Distribuído

  426. None
  427. STATELESS (shared nothing architecture)

  428. None
  429. None
  430. None
  431. Mais requisições?

  432. None
  433. 256GB

  434. 256GB 256GB

  435. Recapitulando…

  436. tunando sua aplicação

  437. tunando sua aplicação melhorando sua máquina

  438. tunando sua aplicação adicionando máquinas melhorando sua máquina

  439. tunando sua aplicação replicando estado adicionando máquinas melhorando sua máquina

  440. tunando sua aplicação replicando estado adicionando máquinas melhorando sua máquina

    removendo estado
  441. Todas plataformas

  442. None
  443. CACHE

  444. CACHE PROCESSAMENTO ASSINCRONO

  445. CACHE BALANCEAMENTO DE CARGA PROCESSAMENTO ASSINCRONO

  446. Não escala ainda…

  447. None
  448. None
  449. e só então…

  450. None
  451. OBRIGADO!

  452. @rponte Rafael Ponte