List produtos = //...
for (Produto p : produtos) {
p.setNome(p.getNome()
.toUpperCase());
}
Atualizando várias entidades
Slide 149
Slide 149 text
Query : [“UPDATE produto SET nome = ? WHERE id = ?”]
Params: [(‘PROD.1', 1), (‘PROD.2', 2), (‘PROD.3', 3)]
1 roundtrip
Slide 150
Slide 150 text
List produtos = //...
for (Produto p : produtos) {
entityManager.remove(p);
}
Removendo várias entidades
Slide 151
Slide 151 text
Query : [“DELETE FROM produto WHERE id = ?”]
Params: [(1), (2), (3)]
1 roundtrip
Slide 152
Slide 152 text
quanto menos roundtrips ao
banco, menor o response time
Slide 153
Slide 153 text
AUTO-INCREMENTO
(batch_size não funciona)
Slide 154
Slide 154 text
db
T = Tacq + Treq + Texec + Tres + Tidle
apresentação
negócio
persistência
Slide 155
Slide 155 text
Use Consultas Planejadas
(DTO Projections)
Slide 156
Slide 156 text
@Entity
class NotaFiscal {
…
@OneToMany
List itens;
}
Slide 157
Slide 157 text
NotaFiscal nf = entityManager
.find(NotaFiscal.class, 42);
processaItensDaNota(nf);
Processando os itens de uma nota
Slide 158
Slide 158 text
Processando os itens de uma nota
NotaFiscal nf = entityManager
.find(NotaFiscal.class, 42);
processaItensDaNota(nf);
Slide 159
Slide 159 text
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);
Slide 160
Slide 160 text
List notas = dao.lista();
for (NotaFiscal nf : notas) {
processaItensDaNota(nf);
}
Processando os itens de varias notas
Slide 161
Slide 161 text
Processando os itens de varias notas
List notas = dao.lista();
for (NotaFiscal nf : notas) {
processaItensDaNota(nf);
}
Slide 162
Slide 162 text
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 notas = dao.lista();
for (NotaFiscal nf : notas) {
processaItensDaNota(nf);
}
Slide 163
Slide 163 text
são muitos hits ao banco
(Select N+1)
Slide 164
Slide 164 text
solução?
Slide 165
Slide 165 text
@Entity
class NotaFiscal {
…
@OneToMany(fetch=FetchType.EAGER)
List itens;
}
Utilizando FetchMode=EAGER
Slide 166
Slide 166 text
SELECT nf.*, i.*
FROM NotaFiscal nf
LEFT OUTER JOIN Item i
ON nf.id = i.nota_fiscal_id
Hibernate executa 1 select
List notas = dao.lista();
Slide 167
Slide 167 text
antes de definir um mapeamento
global deste tipo você precisa se
perguntar...
Slide 168
Slide 168 text
SEMPRE que uma nota é carregada,
todos seus itens também são
necessários?
Slide 169
Slide 169 text
não?
Slide 170
Slide 170 text
@Entity
class NotaFiscal {
…
@OneToMany(fetch=FetchType.LAZY)
List itens;
}
Utilizando FetchMode=LAZY
Slide 171
Slide 171 text
entityManager
.createQuery(
" SELECT n
FROM NotaFiscal n
LEFT JOIN fetch n.itens")
.getResultList();
Utilizando Join Fetch
Slide 172
Slide 172 text
entityManager
.createQuery(
" SELECT n
FROM NotaFiscal n
LEFT JOIN fetch n.itens")
.getResultList();
Utilizando Join Fetch
LAZY permite
mudar para EAGER
Slide 173
Slide 173 text
Opa! Não para aí…
Slide 174
Slide 174 text
SEMPRE que uma nota é carregada,
TODAS as colunas são
necessárias?
Slide 175
Slide 175 text
não?
Slide 176
Slide 176 text
List notas =
entityManager
.createQuery(
" SELECT n.numero, n.serie
FROM NotaFiscal n
WHERE n.tipo = 'DEVOLUCAO'")
.getResultList();
DTO Projections
Slide 177
Slide 177 text
List notas =
entityManager
.createQuery(
" SELECT n.numero, n.serie
FROM NotaFiscal n
WHERE n.tipo = 'DEVOLUCAO'")
.getResultList();
DTO Projections
Slide 178
Slide 178 text
List????> notas =
entityManager
.createQuery(
" SELECT n.numero, n.serie
FROM NotaFiscal n
WHERE n.tipo = 'DEVOLUCAO'")
.getResultList();
DTO Projections
Slide 179
Slide 179 text
class Devolucao {
Integer numero;
String serie;
public Devolucao(Integer n, String s) {
this.numero = n;
this.serie = s;
}
// getters e setters
}
Criando o DTO
Slide 180
Slide 180 text
List notas =
entityManager
.createQuery(
" SELECT n.numero, n.serie
FROM NotaFiscal n
WHERE n.tipo = 'DEVOLUCAO'")
.getResultList();
DTO Projections
Slide 181
Slide 181 text
List notas =
entityManager
.createQuery(
" SELECT new Devolucao(n.numero,
n.serie)
FROM NotaFiscal n
WHERE n.tipo = 'DEVOLUCAO'")
.getResultList();
DTO Projections
Slide 182
Slide 182 text
SELECT nf.numero, nf.serie
FROM NotaFiscal nf
WHERE nf.tipo = 'DEVOLUCAO'
SQL otimizado
List notas = //...
Slide 183
Slide 183 text
quanto menor a quantidade de
dados recuperados, menor o
response time
Slide 184
Slide 184 text
db
T = Tacq + Treq + Texec + Tres + Tidle
apresentação
negócio
persistência
Slide 185
Slide 185 text
Como otimizar minha query?
Slide 186
Slide 186 text
SQL Nativo
(deixe seu banco trabalhar)
Slide 187
Slide 187 text
Stored Procedures
(leve o processamento para os
dados)
Slide 188
Slide 188 text
DBA
(peça ajuda)
Slide 189
Slide 189 text
mesmo com todas essas
melhorias…
Slide 190
Slide 190 text
picos de acessos
podem aumentar
nosso response time
Slide 191
Slide 191 text
Caching
(aliviando o banco de dados)
Slide 192
Slide 192 text
NotaFiscal nf = entityManager
.find(NotaFiscal.class, 42);
Carregando uma nota por ID
Slide 193
Slide 193 text
SELECT nf.*
FROM NotaFiscal nf
WHERE nf.id = 42
Hibernate executa 1 select
NotaFiscal nf = entityManger.find(NotaFiscal.class, 42);
Slide 194
Slide 194 text
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
Slide 195
Slide 195 text
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
Slide 196
Slide 196 text
Banco de Dados
EM
Slide 197
Slide 197 text
Banco de Dados
EM
First Level Cache
Slide 198
Slide 198 text
Banco de Dados
EM EM EM EM
Slide 199
Slide 199 text
Banco de Dados
????
EM EM EM EM
Slide 200
Slide 200 text
Banco de Dados
Second Level Cache
EM EM EM EM
Slide 201
Slide 201 text
Banco de Dados
Second Level Cache
EM Session Session
First Level Cache
Session
EM EM EM
Slide 202
Slide 202 text
Banco de Dados
EntityManagerFactory
EM EM EM EM
Slide 203
Slide 203 text
persistence.xml
#1 habilitamos o cache
Slide 204
Slide 204 text
@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
class Produto {
@Id
private Long id;
private String nome;
}
#2 configuramos as entidades
db
T = Tacq + Treq + Texec + Tres + Tidle
apresentação
negócio
persistência
Slide 211
Slide 211 text
db
apresentação
negócio
persistência
Slide 212
Slide 212 text
db
apresentação
negócio
persistência
Slide 213
Slide 213 text
db
negócio
persistência
apresentação
Slide 214
Slide 214 text
“There are only two hard things in
Computer Science: cache invalidation
and naming things.”
— Phil Karlton
Slide 215
Slide 215 text
navegador
servidor db
requisição
resposta
Performance Consistência
Slide 216
Slide 216 text
Assincronicidade
(processa mais tarde)
Slide 217
Slide 217 text
@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...
}
}
Slide 218
Slide 218 text
@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...
}
}
Slide 219
Slide 219 text
@Service
public class PedidoService {
public void finaliza(Pedido pedido) {
// efetua pagamento
// dá baixa no estoque
// atualiza pedido
// envia email de confirmação
}
}
Slide 220
Slide 220 text
se a execução é custosa então é
um possível gargalo…
Slide 221
Slide 221 text
@Service
public class PedidoService {
@Async
public void finaliza(Pedido pedido) {
// efetua pagamento
// dá baixa no estoque
// atualiza pedido
// envia email de confirmação
}
}
Slide 222
Slide 222 text
Spring usa um
pool de threads
Slide 223
Slide 223 text
@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!!
}
}
Slide 224
Slide 224 text
mas poderíamos
usar uma fila…
Slide 225
Slide 225 text
@Service
public class PedidoService {
@Autowired
private JmsTemplate fila;
public void finaliza(Pedido pedido) {
fila.convertAndSend("fila.pedidos", pedido);
}
}
Slide 226
Slide 226 text
@Service
public class PedidoService {
@Autowired
private JmsTemplate fila;
public void finaliza(Pedido pedido) {
fila.convertAndSend("fila.pedidos", pedido);
}
}
Slide 227
Slide 227 text
e em algum momento um
processo consumiria a
fila…
Slide 228
Slide 228 text
@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
}
}
Slide 229
Slide 229 text
no fim nossa requisição
responderia
imediatamente
Slide 230
Slide 230 text
@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!!
}
}
Slide 231
Slide 231 text
Wow!!
Slide 232
Slide 232 text
1) tunamos a JVM;
2) tunanamos a camada de
persistência;
3) adicionamos caching;
4) adicionamos processamento
assincrono;
Slide 233
Slide 233 text
1) tunamos a JVM;
2) tunanamos a camada de
persistência;
3) adicionamos caching;
4) adicionamos processamento
assincrono;
Slide 234
Slide 234 text
1) tunamos a JVM;
2) tunanamos a camada de
persistência;
3) adicionamos caching;
4) adicionamos processamento
assincrono;
Slide 235
Slide 235 text
1) tunamos a JVM;
2) tunanamos a camada de
persistência;
3) adicionamos caching;
4) adicionamos processamento
assincrono;
Slide 236
Slide 236 text
Sistema
não aguenta?
Slide 237
Slide 237 text
Passo 2
(MELHORANDO A MÁQUINA)
Slide 238
Slide 238 text
navegador
servidor db
requisição
resposta
Slide 239
Slide 239 text
navegador
servidor db
requisição
resposta
Slide 240
Slide 240 text
cpu
memoria
Slide 241
Slide 241 text
No content
Slide 242
Slide 242 text
No content
Slide 243
Slide 243 text
X
Slide 244
Slide 244 text
No content
Slide 245
Slide 245 text
No content
Slide 246
Slide 246 text
No content
Slide 247
Slide 247 text
x 6
x 6
Slide 248
Slide 248 text
Mais
requisições?
Slide 249
Slide 249 text
No content
Slide 250
Slide 250 text
No content
Slide 251
Slide 251 text
No content
Slide 252
Slide 252 text
Escalabilidade Vertical
(scale up)
Slide 253
Slide 253 text
No content
Slide 254
Slide 254 text
No content
Slide 255
Slide 255 text
No content
Slide 256
Slide 256 text
No content
Slide 257
Slide 257 text
No content
Slide 258
Slide 258 text
No content
Slide 259
Slide 259 text
No content
Slide 260
Slide 260 text
X
Slide 261
Slide 261 text
Sistema
não aguenta?
Slide 262
Slide 262 text
Passo 3
(ADICIONANDO MAIS MÁQUINAS)
Slide 263
Slide 263 text
navegador
servidor db
requisição
resposta
Slide 264
Slide 264 text
navegador
servidor db
requisição
resposta
Slide 265
Slide 265 text
No content
Slide 266
Slide 266 text
=
Slide 267
Slide 267 text
No content
Slide 268
Slide 268 text
No content
Slide 269
Slide 269 text
No content
Slide 270
Slide 270 text
ip?
Slide 271
Slide 271 text
No content
Slide 272
Slide 272 text
No content
Slide 273
Slide 273 text
No content
Slide 274
Slide 274 text
200 reqs
Slide 275
Slide 275 text
200 reqs
100 reqs
100 reqs
Slide 276
Slide 276 text
Balanceador
de Carga
Slide 277
Slide 277 text
Balanceador
de Carga
Slide 278
Slide 278 text
Balanceador
de Carga
Slide 279
Slide 279 text
No content
Slide 280
Slide 280 text
Mais
requisições?
Slide 281
Slide 281 text
No content
Slide 282
Slide 282 text
No content
Slide 283
Slide 283 text
No content
Slide 284
Slide 284 text
No content
Slide 285
Slide 285 text
Cluster
Slide 286
Slide 286 text
No content
Slide 287
Slide 287 text
No content
Slide 288
Slide 288 text
Escalabilidade Horizontal
(scale out)
Slide 289
Slide 289 text
Apesar de mais
barata…
Slide 290
Slide 290 text
No content
Slide 291
Slide 291 text
(1a requisição)
Slide 292
Slide 292 text
(1a requisição)
Slide 293
Slide 293 text
Sessão
Slide 294
Slide 294 text
(2a requisição)
qual?
Slide 295
Slide 295 text
(2a requisição)
Slide 296
Slide 296 text
(2a requisição)
Slide 297
Slide 297 text
Sticky Session
Slide 298
Slide 298 text
—
Slide 299
Slide 299 text
Mas e se…
Slide 300
Slide 300 text
No content
Slide 301
Slide 301 text
No content
Slide 302
Slide 302 text
No content
Slide 303
Slide 303 text
No content
Slide 304
Slide 304 text
No content
Slide 305
Slide 305 text
No content
Slide 306
Slide 306 text
?
Slide 307
Slide 307 text
?
Slide 308
Slide 308 text
Falta
Redundância
Slide 309
Slide 309 text
Passo 4
(REPLICANDO ESTADO)
Slide 310
Slide 310 text
No content
Slide 311
Slide 311 text
(1a requisição)
Slide 312
Slide 312 text
(1a requisição)
Slide 313
Slide 313 text
(2a requisição)
Slide 314
Slide 314 text
(2a requisição)
qual?
Slide 315
Slide 315 text
(2a requisição)
Slide 316
Slide 316 text
(2a requisição)
Slide 317
Slide 317 text
No content
Slide 318
Slide 318 text
Session
Replication
Slide 319
Slide 319 text
No content
Slide 320
Slide 320 text
No content
Slide 321
Slide 321 text
No content
Slide 322
Slide 322 text
No content
Slide 323
Slide 323 text
Replica Estado
Slide 324
Slide 324 text
No content
Slide 325
Slide 325 text
Alta Disponibilidade
(high availability)
Slide 326
Slide 326 text
Mais
requisições?
Slide 327
Slide 327 text
No content
Slide 328
Slide 328 text
No content
Slide 329
Slide 329 text
No content
Slide 330
Slide 330 text
No content
Slide 331
Slide 331 text
Se tenho mais
máquinas…
Slide 332
Slide 332 text
No content
Slide 333
Slide 333 text
No content
Slide 334
Slide 334 text
No content
Slide 335
Slide 335 text
No content
Slide 336
Slide 336 text
Replicar sessão é
CARO
Slide 337
Slide 337 text
Passo 5
(REMOVENDO ESTADO)
Slide 338
Slide 338 text
No content
Slide 339
Slide 339 text
No content
Slide 340
Slide 340 text
No content
Slide 341
Slide 341 text
No content
Slide 342
Slide 342 text
No content
Slide 343
Slide 343 text
ONDE?
Slide 344
Slide 344 text
No content
Slide 345
Slide 345 text
No content
Slide 346
Slide 346 text
No content
Slide 347
Slide 347 text
No content
Slide 348
Slide 348 text
Cache Distribuído
Slide 349
Slide 349 text
Cache Distribuído
Slide 350
Slide 350 text
Cache Distribuído
Slide 351
Slide 351 text
No content
Slide 352
Slide 352 text
STATELESS
(shared nothing architecture)
Slide 353
Slide 353 text
No content
Slide 354
Slide 354 text
No content
Slide 355
Slide 355 text
No content
Slide 356
Slide 356 text
Mais
requisições?
Slide 357
Slide 357 text
No content
Slide 358
Slide 358 text
256GB
Slide 359
Slide 359 text
256GB 256GB
Slide 360
Slide 360 text
Recapitulando…
Slide 361
Slide 361 text
tunando sua aplicação
Slide 362
Slide 362 text
tunando sua aplicação
melhorando sua máquina
Slide 363
Slide 363 text
tunando sua aplicação
adicionando máquinas
melhorando sua máquina
Slide 364
Slide 364 text
tunando sua aplicação
replicando estado
adicionando máquinas
melhorando sua máquina
Slide 365
Slide 365 text
tunando sua aplicação
replicando estado
adicionando máquinas
melhorando sua máquina
removendo estado
Slide 366
Slide 366 text
Todas
plataformas
Slide 367
Slide 367 text
CACHE
Slide 368
Slide 368 text
CACHE
PROCESSAMENTO
ASSINCRONO
Slide 369
Slide 369 text
CACHE
BALANCEAMENTO
DE CARGA
PROCESSAMENTO
ASSINCRONO