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

F853760c988228c4a153333407e64f09?s=47 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ê!

F853760c988228c4a153333407e64f09?s=128

Rafael Ponte

February 13, 2019
Tweet

Transcript

  1. ARQUITETURA WEB escalando sua aplicação além do hype

  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. None
  15. None
  16. None
  17. None
  18. Um bom arquiteto escolhe tecnologias por suas desvantagens

  19. None
  20. podemos escalar SEM o hype…

  21. Rafael Ponte @rponte

  22. None
  23. Fortaleza - Terra do Sol

  24. ARQUITETURA WEB escalando sua aplicação além do hype

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

  26. Loja Virtual

  27. None
  28. Revisitando a Web…

  29. servidor

  30. servidor

  31. navegador servidor

  32. navegador servidor requisição

  33. navegador servidor db requisição

  34. navegador servidor db requisição resposta

  35. navegador servidor db requisição resposta

  36. 2 conceitos importantes

  37. Performance 
 X 
 Escalabilidade

  38. tempo de resposta (response time)

  39. navegador servidor db requisição resposta

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

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

  42. operações / unidade_tempo (throughput)

  43. usuários / minuto (throughput)

  44. usuários / segundo (throughput)

  45. usuários / segundo (throughput)

  46. requisições / segundo (throughput)

  47. navegador servidor db requisição resposta

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

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

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

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

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

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

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

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

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

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

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

  59. PASSOS 5 RESUMINDO EM

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

  61. navegador servidor db requisição resposta

  62. navegador servidor db requisição resposta

  63. None
  64. None
  65. None
  66. None
  67. None
  68. None
  69. JVM

  70. None
  71. 2Gb

  72. 2Gb ???

  73. 2Gb 256Mb

  74. 2Gb ??Mb

  75. 2Gb 2Gb

  76. 2Gb 2Gb =

  77. 2Gb 2Gb = X

  78. 2Gb 1Gb

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

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

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

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

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

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

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

  86. 2Gb 1Gb

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

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

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

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

  91. navegador servidor db requisição resposta

  92. servidor Aplicação

  93. servidor

  94. 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
  95. servidor

  96. servidor

  97. servidor

  98. Divisão de Camadas

  99. servidor

  100. servidor modelo

  101. servidor modelo telas

  102. servidor modelo acesso a dados telas

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

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

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

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

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

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

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

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

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

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

  113. navegador servidor db requisição resposta

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

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

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

  117. servidor db

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  134. Criar conexões é CARO!

  135. navegador db app

  136. navegador db app

  137. navegador db app

  138. navegador db app ini=5

  139. db app ini=5

  140. db app … max=30 ini=5

  141. db app … max=30 ini=5

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

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

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

  145. mas qual o tamanho ideal do pool?

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

  147. mensure!

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

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

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

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

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

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

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

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

    [('Prod.1', 1), ('Prod.2', 2), (‘Prod.3', 3)] 1 roundtrip
  157. Para UPDATE e DELETE também

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

    p.setNome(p.getNome() .toUpperCase()); } Atualizando várias entidades
  159. Query : [“UPDATE produto SET nome = ? WHERE id

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

    entityManager.remove(p); } Removendo várias entidades
  161. Query : [“DELETE FROM produto WHERE id = ?”] Params:

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

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

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

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

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

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

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

    .find(NotaFiscal.class, 42); 
 processaItensDaNota(nf);
  169. 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);
  170. List<NotaFiscal> notas = dao.lista(); for (NotaFiscal nf : notas) {

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

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

    for (NotaFiscal nf : notas) { processaItensDaNota(nf); }
  173. 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); }
  174. são muitos hits ao banco (Select N+1)

  175. solução?

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

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

    se perguntar...
  179. SEMPRE que uma nota é carregada, todos seus itens também

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

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

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

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

    fetch n.itens")
 .getResultList(); Utilizando Join Fetch LAZY permite mudar para EAGER
  184. Opa! Não para aí…

  185. SEMPRE que uma nota é carregada, TODAS as colunas são

    necessárias?
  186. não?

  187. List<NotaFiscal> notas = entityManager
 .createQuery( " SELECT n FROM NotaFiscal

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

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

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

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

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

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

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

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

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

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

  198. SQL Nativo (deixe seu banco trabalhar)

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

  200. None
  201. DBA (peça ajuda)

  202. mesmo com todas essas melhorias…

  203. picos de acessos podem aumentar nosso response time

  204. Caching (aliviando o banco de dados)

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

    por ID
  206. None
  207. EM

  208. Banco de Dados EM

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

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

    executa 1 select NotaFiscal nf = entityManger.find(NotaFiscal.class, 42);
  211. 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
  212. 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
  213. 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
  214. Banco de Dados EM

  215. Banco de Dados EM First Level Cache

  216. Banco de Dados EM

  217. Banco de Dados EM EM EM EM

  218. Banco de Dados ???? EM EM EM EM

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

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

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

  222. <property name="hibernate.cache.second_level_cache" value="true" /> <property name="hibernate.cache.region.factory_class" value="net.sf...EhCacheRegionFactory" /> persistence.xml #1

    habilitamos o cache
  223. @Entity @Cache(...) class Produto { @Id private Long id; private

    String nome; } #2 configuramos as entidades
  224. <cache name="br.com.app.model.Produto" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="10000" overflowToDisk="true" memoryStoreEvictionPolicy="LRU" /> ehcache.xml

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

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

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

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

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

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

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

  232. E se houver processamento pesado?

  233. @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... } }
  234. @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... } }
  235. @Service public class PedidoService { public void finaliza(Pedido pedido) {


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

  237. navegador servidor db

  238. navegador servidor db

  239. se a execução é custosa então é um possível gargalo…

  240. Assincronicidade (processa mais tarde)

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


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

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

  244. @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!! } }
  245. e se além de custosa ela também for em grande

    quantidade…
  246. poderíamos usar uma fila…

  247. navegador servidor db

  248. navegador servidor db X

  249. navegador servidor db fila

  250. @Service public class PedidoService { @Autowired private JmsTemplate fila; public

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

    void finaliza(Pedido pedido) { fila.convertAndSend("fila.pedidos", pedido);
 } }
  252. e em algum momento um processo consumiria a fila…

  253. navegador servidor db fila

  254. navegador servidor db fila consumidor

  255. servidor db fila consumidor navegador

  256. servidor db fila consumidor navegador

  257. servidor db fila consumidor navegador

  258. @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 } }
  259. no fim nossa requisição responderia imediatamente

  260. @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!! } }
  261. Wow!!

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

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

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

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

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

  267. Passo 2
 (MELHORANDO A MÁQUINA)

  268. navegador servidor db requisição resposta

  269. navegador servidor db requisição resposta

  270. cpu memoria

  271. None
  272. None
  273. X

  274. None
  275. None
  276. None
  277. x 6 x 6

  278. Mais requisições?

  279. None
  280. None
  281. None
  282. Escalabilidade Vertical (scale up)

  283. None
  284. None
  285. None
  286. None
  287. None
  288. None
  289. None
  290. X

  291. Sistema 
 não aguenta?

  292. Passo 3
 (ADICIONANDO MAIS MÁQUINAS)

  293. navegador servidor db requisição resposta

  294. navegador servidor db requisição resposta

  295. None
  296. None
  297. =

  298. None
  299. None
  300. None
  301. ip?

  302. None
  303. None
  304. None
  305. 200 reqs

  306. 200 reqs 100 reqs 100 reqs

  307. Balanceador de Carga

  308. Balanceador de Carga

  309. Balanceador de Carga

  310. None
  311. Mais requisições?

  312. None
  313. None
  314. None
  315. None
  316. Cluster

  317. None
  318. None
  319. Escalabilidade Horizontal (scale out)

  320. Apesar de mais barata…

  321. None
  322. (1a requisição)

  323. (1a requisição)

  324. Sessão

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

  326. (2a requisição)

  327. (2a requisição)

  328. Sticky Session

  329. Mas e se…

  330. None
  331. None
  332. None
  333. None
  334. None
  335. None
  336. None
  337. None
  338. None
  339. ?

  340. ?

  341. Falta Redundância

  342. Passo 4
 (REPLICANDO ESTADO)

  343. None
  344. (1a requisição)

  345. (1a requisição)

  346. (2a requisição)

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

  348. (2a requisição)

  349. (2a requisição)

  350. None
  351. Session Replication

  352. None
  353. None
  354. None
  355. None
  356. Replica Estado

  357. None
  358. Alta Disponibilidade (high availability)

  359. Mais requisições?

  360. None
  361. None
  362. None
  363. None
  364. Se tenho mais máquinas…

  365. None
  366. None
  367. None
  368. None
  369. Replicar sessão é CARO

  370. Passo 5
 (REMOVENDO ESTADO)

  371. None
  372. None
  373. None
  374. None
  375. X X X X X

  376. None
  377. ONDE?

  378. None
  379. None
  380. None
  381. None
  382. None
  383. Cache Distribuído

  384. Cache Distribuído

  385. Cache Distribuído

  386. None
  387. STATELESS (shared nothing architecture)

  388. None
  389. None
  390. None
  391. Mais requisições?

  392. None
  393. 256GB

  394. 256GB 256GB

  395. Recapitulando…

  396. tunando sua aplicação

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

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

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

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

    removendo estado
  401. Todas plataformas

  402. None
  403. CACHE

  404. CACHE PROCESSAMENTO ASSINCRONO

  405. CACHE BALANCEAMENTO DE CARGA PROCESSAMENTO ASSINCRONO

  406. Não escala ainda…

  407. None
  408. None
  409. e só então…

  410. None
  411. OBRIGADO!

  412. @rponte http://triadworks.com.br/ @triadworks