SlideShare una empresa de Scribd logo
1 de 46
Practical
non-blocking microservices
in Java 8
Michał Baliński
System Architect
Oleksandr Goldobin
System Architect
Cloud of microservices for secure IoT
gateway backing
service
core
service
gateway
gateway
core
service
backing
service
The demand and characteristics of our domain
Crowded IoT environment
Slow, long lived connections
Big amount of concurrent connections
Scalability and resilience
Rather I/O intensive than CPU intensive
OTA Gateway – Use Case
TSM
Trusted
Service
Manager
OTA Gateway – Use Case
TSM
Trusted
Service
Manager
Security Module
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
HTTP
1. submit
scripts
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
HTTP
1. submit
scripts
HTTP
2. encrypt
scripts
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
HTTP
1. submit
scripts
HTTP
2. encrypt
scripts
TCP
3. store
scripts
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
HTTP
1. submit
scripts
HTTP
2. encrypt
scripts
TCP
4. submition
response
3. store
scripts
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
HTTP
1. submit
scripts
HTTP
2. encrypt
scripts
TCP
4. submition
response
HTTP
5. poll
scripts
3. store
scripts
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
HTTP
1. submit
scripts
HTTP
2. encrypt
scripts
TCP
3. store
scripts
4. submition
response
HTTP
5. poll
scripts
6. search
scripts
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
HTTP
1. submit
scripts
HTTP
2. encrypt
scripts
TCP
3. store
scripts
4. submition
response
HTTP
5. poll
scripts
6. search
scripts
7. response
with scripts
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
HTTP HTTP
HTTP
TCP
OTA Gateway – Use Case
OTA
(Over-the-Air)
Gateway
TSM
Trusted
Service
Manager
Security Module
DB
Log
Storage
HTTP HTTP
HTTP
TCP File I/OMonitoring
System
HTTP
Let’s test blocking approach!
OTA Gateway Blocking - technologies
25 February 2017 17
TSM
DB Log
Storage
HTTP
TCP STDOUT
OTA
Gateway
JAX-RS
Logback
appender
Security Module
JAX-RS
Jedis
JAX-RS Client
OTA Gateway – Blocking - test
OTA
(Over-the-Air)
Gateway
send
2 scripts per
request
Security Module
DB
Log
Storage
HTTP HTTP
HTTP
TCP File I/O
emulated
latency
200 ms
expected
latency
< 450 ms
verified with
throughput
over 7k req/s
Blocking – 1k threads
OTA
(Over-the-Air)
Gateway
send
2 scripts per
request
Security Module
DB
Log
Storage
HTTP HTTP
HTTP
TCP File I/O
emulated
latency
200 ms
max 1000
connections
max 1000
threads
expected
latency
< 450 ms
Blocking – 1k threads
500 req/s 1000 req/s 1500 req/s 2000 req/s
The drawbacks of classic synchronous I/O
One thread per connection
Threads waiting instead of running
Context switches
Resource wasting (~1 MB per thread - 64bit)
Let’s switch from blocking to non-blocking
OTA Gateway Non-blocking - technologies
25 February 2017 23
TSM
DB Log
Storage
HTTP
TCP STDOUT
OTA
Gateway
JAX-RS 2.0
Logback
async
appender
Async Http Client 2
(Netty)
Security Module
JAX-RS 2.0
Lettuce
(Netty)
Non-blocking – 16 threads
OTA
(Over-the-Air)
Gateway
send
2 scripts per
request
Security Module
DB
Log
Storage
HTTP HTTP
HTTP
TCP File I/O
emulated
latency
200 ms
no limit for
connections
max 16
threads
expected
latency
< 450 ms
Non-blocking – 16 threads
1k req/s 2k req/s 2.5k req/s 3k req/s
Blocking Non-blocking
1000 threads 56 threads
1.2 GB 0.5 GB
~1.2k r/s 2.5k r/s
Let’s talk about challenges
OTA Gateway Blocking – sequence diagram
OTA
Gateway
TSM
Security
Module DB Logs
loop
1. submit
scripts
2. encrypt
script
3a. store
script
4. submition
response
3b. count
scripts
OTA Gateway Non-blocking – sequence diagram
OTA
Gateway
TSM
Security
Module DB Logs
loop
1. submit
scripts
2. encrypt
script
3a. store
script
4. submition
response
3b. count
scripts
OTA Non-blocking – realityOTA
Gateway
TSM
Security
Module DB Logs
„loopedprocessingchain”
1. submit
scripts
4. submition
response
3b. count
scripts
HTTP
Server
2. encrypt
script
3a. store
script
Logging
DB
Client
Security
Client
Code. Bird view
3125 February 2017
package org.demo.ota.blocking.rest;
@Path("se")
public class ScriptSubmissionResource extends Application {
private static final Logger log = LoggerFactory.getLogger(ScriptSubmissionResource.class);
private static final ResourceMetrics METRICS = new ResourceMetrics("ota_submission");
private SecureModuleClient secureModuleClient = SecureModuleClient.instance();
private ScriptStorageClient scriptStorageClient = ScriptStorageClient.instance();
@POST
@Path("/{seId}/scripts")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public long submitScripts(@PathParam("seId") String seId, List<Script> scripts) {
MDC.put("flow", "submission");
MDC.put("se", seId);
return METRICS.instrument(() -> {
log.debug("Processing {} scripts submission", scripts.size(), seId);
for (int i = 0; i < scripts.size(); i++) {
final Script script = scripts.get(i);
log.debug("Encrypting {} script", i);
final String encryptedPayload = secureModuleClient.encrypt(seId, script.getPayload());
script.setPayload(encryptedPayload);
log.debug("Storing encrypted script {}", i);
scriptStorageClient.storeScript(seId, script);
}
long numberOfScripts = scriptStorageClient.numberOfScriptsForSe(seId);
log.debug("Request processed", seId);
return numberOfScripts;
});
}
@Override
public Set<Object> getSingletons() {
return Collections.singleton(this);
}
}
package org.demo.ota.nonblocking.rest;
@Path("se")
public class ScriptSubmissionResource extends Application {
private static final Logger log = LoggerFactory.getLogger(ScriptSubmissionResource.class);
private static final ResourceMetrics METRICS = new ResourceMetrics("ota_submission");
private SecureModuleClient secureModuleClient = SecureModuleClient.instance();
private ScriptStorageClient scriptStorageClient = ScriptStorageClient.instance();
@POST
@Path("/{seId}/scripts")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public void submitScripts(
@PathParam("seId") String seId,
List<Script> scripts,
@Suspended final AsyncResponse asyncResponse
) {
final DiagnosticContext diagnosticContext = new DiagnosticContext("submission", seId);
METRICS.instrumentStage(() -> {
log.debug("{} Processing {} scripts submission", diagnosticContext, scripts.size());
return
encryptAndStoreAllScripts(diagnosticContext, seId, scripts)
.thenCompose(
ignore -> scriptStorageClient.numberOfScriptsForSe(seId)
);
})
.whenComplete((numberOfScripts, e) -> {
if (e != null) {
asyncResponse.resume(e);
} else {
log.debug("{} Request processed", diagnosticContext);
asyncResponse.resume(numberOfScripts);
}
});
}
private CompletionStage<Void> encryptAndStoreAllScripts(
final DiagnosticContext diagnosticContext,
final String seId,
final List<Script> scripts
) {
CompletionStage<Void> stage = null; // <- non final field, potential concurrent access bug!
for (int i = 0; i < scripts.size(); i++) {
final int scriptIndex = i;
final Script script = scripts.get(scriptIndex);
if (stage == null) {
stage = encryptAndStoreSingleScript(diagnosticContext, seId, scriptIndex, script);
} else {
stage = stage.thenCompose(ignore ->
encryptAndStoreSingleScript(diagnosticContext, seId, scriptIndex, script));
}
}
return stage;
}
private CompletionStage<Void> encryptAndStoreSingleScript(
final DiagnosticContext diagnosticContext,
final String seId,
final int scriptIndex,
final Script script
) {
log.debug("{} Encrypting script {}", diagnosticContext, scriptIndex);
return secureModuleClient
.encrypt(seId, script.getPayload())
.thenCompose(
encryptedPayload -> {
log.debug("{} Storing encrypted script {}", diagnosticContext, scriptIndex);
return scriptStorageClient.storeScript(seId, new Script(encryptedPayload));
}
);
}
@Override
public Set<Object> getSingletons() {
return new HashSet<>(Collections.singletonList(this));
}
}
Code. Blocking. Submission 1
25 February 2017 32
@POST
@Path("/{seId}/scripts")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public
long submitScripts(@PathParam("seId") String seId, List<Script> scripts) {
MDC.put("flow", "submission"); //  Setting diagnostic context
MDC.put("se", seId);
return METRICS.instrument(() -> { //  Instrumenting with metrics
//...
Code. Blocking. Submission 2
25 February 2017 33
log.debug("Processing {} scripts submission", scripts.size(), seId);
for (int i = 0; i < scripts.size(); i++) {  Cycle through the
scripts
final Script script = scripts.get(i);
log.debug("Encrypting {} script", i);
final String encryptedPayload = secureModuleClient
.encrypt(seId, script.getPayload());  Encrypting the script
script.setPayload(encryptedPayload);
log.debug("Storing encrypted script {}", i);
scriptStorageClient.storeScript(seId, script);  Saving the script into
DB
}
long numberOfScripts =
scriptStorageClient.numberOfScriptsForSe(seId);  Getting current number
of scripts in DB
log.debug("Request processed", seId);
return numberOfScripts;
Code. Non-blocking. Submission 1
25 February 2017 34
@POST
@Path("/{seId}/scripts")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public void submitScripts(
@PathParam("seId") String seId,
List<Script> scripts,
@Suspended final AsyncResponse asyncResponse
) {
final DiagnosticContext diagnosticContext =
new DiagnosticContext("submission", seId);  Creating diagnostic
context
METRICS.instrumentStage(() -> {  Instrumenting with metrics
Code. Non-blocking. Submission 1
25 February 2017 35
@POST
@Path("/{seId}/scripts")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public void submitScripts(
@PathParam("seId") String seId,
List<Script> scripts,
@Suspended final AsyncResponse asyncResponse
) {
final DiagnosticContext diagnosticContext =
new DiagnosticContext("submission", seId);  Creating diagnostic
context
METRICS.instrumentStage(() -> {  Instrumenting with metrics
Code. Non-blocking. Submission 2
25 February 2017 36
METRICS.instrumentStage(() -> {
log.debug(
"{} Processing {} scripts submission",
diagnosticContext,
scripts.size());
return
encryptAndStoreAllScripts(diagnosticContext, seId, scripts)
.thenCompose(
ignore ->
scriptStorageClient.numberOfScriptsForSe(seId)
);
})
.whenComplete((numberOfScripts, e) -> {
if (e != null) {
asyncResponse.resume(e);
} else {
log.debug("{} Request processed", diagnosticContext);
asyncResponse.resume(numberOfScripts);
}
});
Code. Non-blocking. Submission 3
25 February 2017 37
private CompletionStage<Void> encryptAndStoreAllScripts(
final DiagnosticContext diagnosticContext,
final String seId,
final List<Script> scripts
) {
CompletionStage<Void> stage = null; // <- non final field, potential
// concurrent access bug!
for (int i = 0; i < scripts.size(); i++) {  Cycle through the
scripts
final int scriptIndex = i;
final Script script = scripts.get(scriptIndex);
if (stage == null) {
stage = encryptAndStoreSingleScript(
diagnosticContext, seId, scriptIndex, script);
} else {
stage = stage.thenCompose(ignore ->
encryptAndStoreSingleScript(
diagnosticContext, seId, scriptIndex, script));
}
}
return stage;
}
Code. Non-blocking. Submission 4
25 February 2017 38
private CompletionStage<Void> encryptAndStoreSingleScript(
final DiagnosticContext diagnosticContext,
final String seId,
final int scriptIndex,
final Script script
) {
log.debug("{} Encrypting script {}", diagnosticContext, scriptIndex);
return secureModuleClient
.encrypt(seId, script.getPayload())  Encrypting the script
.thenCompose(
encryptedPayload -> {
log.debug(
"{} Storing encrypted script {}",
diagnosticContext,
scriptIndex);
return
scriptStorageClient.storeScript(  Saving the script into seId,
the DB
new Script(encryptedPayload));
}
);
}
Code. Blocking. Integration
25 February 2017 39
private final JedisPool pool;
public void storeScript(String seId, Script script) {
try (Jedis jedis = pool.getResource()) {
jedis.rpush(seId, script.getPayload());
}
}
public long numberOfScriptsForSe(String seId) {
try (Jedis jedis = pool.getResource()) {
return jedis.llen(seId);
}
}
public Optional<Script> nextScript(String seId) {
try (Jedis jedis = pool.getResource()) {
return Optional.ofNullable(jedis.lpop(seId)).map(Script::new);
}
}
public String encrypt(String keyDiversifier, String payload) {
// ...
}
Code. Non-Blocking. Integration
25 February 2017 40
private final RedisAsyncCommands<String, String> commands;
public CompletionStage<Void> storeScript(String seId, Script script) {
return commands
.rpush(seId, script.getPayload())
.thenApply(ignore -> null);
}
public CompletionStage<Long> numberOfScriptsForSe(String seId) {
return commands.llen(seId);
}
public CompletionStage<Optional<String>> nextScript(String seId) {
return commands.lpop(seId).thenApply(Optional::ofNullable);
}
public CompletionStage<String> encrypt(String keyDiversifier, String payload) {
// ...
}
Diagnostics in non-blocking systems
No clear stack traces, need for good logs
Name your threads properly
MDC becomes useless (thread locals)
Explicitly pass debug context to trace flows
Be prepared for debuging non-obvious errors
NIO technology landscape
JDK 1.4
NIO
JDK 1.7
NIO.2
JAX-RS 2.x
Servlet API 3.x
Lessons learned, part 1
Vanila Java 8 for NIO µ-services
Netty best for custom protocols in NIO
Unit tests should be synchronous
Load/stress testing is a must
Make bulkheading and plan your resources
Lessons learned, part 2
Functional programming patterns for readability
Immutability as 1-st class citizen
Scala may be good choice ;-)
Conclusion
Non-blocking processing can really
save your resources (== money)
But!
Weight all pros and cons and use non-blocking processing
only if you really need it.
Thank you.
Michał Baliński
m.balinski@oberthur.com
Oleksandr Goldobin
o.goldobin@oberthur.com
goldobin
@goldobin
balonus
@MichalBalinski
Readings:
• https://github.com/balonus/blocking-vs-nonblocking-demo
• C10k Problem, C10M Problem, Asynchronous I/O
• Boost application performance using asynchronous I/O (M. Tim Jones, 2006)
• Zuul 2 : The Netflix Journey to Asynchronous, Non-Blocking Systems (Netflix, 2016)
• Thousands of Threads and Blocking I/O: The Old Way to Write Java Servers Is New
Again (and Way Better) (Paul Tyma, 2008)
• Why Non-Blocking? (Bozhidar Bozhanov, 2011)

Más contenido relacionado

La actualidad más candente

Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!Jakub Kubrynski
 
Understanding java streams
Understanding java streamsUnderstanding java streams
Understanding java streamsShahjahan Samoon
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
 
Streaming with Spring Cloud Stream and Apache Kafka - Soby Chacko
Streaming with Spring Cloud Stream and Apache Kafka - Soby ChackoStreaming with Spring Cloud Stream and Apache Kafka - Soby Chacko
Streaming with Spring Cloud Stream and Apache Kafka - Soby ChackoVMware Tanzu
 
What is REST API? REST API Concepts and Examples | Edureka
What is REST API? REST API Concepts and Examples | EdurekaWhat is REST API? REST API Concepts and Examples | Edureka
What is REST API? REST API Concepts and Examples | EdurekaEdureka!
 
DWARF Data Representation
DWARF Data RepresentationDWARF Data Representation
DWARF Data RepresentationWang Hsiangkai
 
Hibernate presentation
Hibernate presentationHibernate presentation
Hibernate presentationManav Prasad
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOPDzmitry Naskou
 

La actualidad más candente (20)

Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
 
Understanding java streams
Understanding java streamsUnderstanding java streams
Understanding java streams
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Streaming with Spring Cloud Stream and Apache Kafka - Soby Chacko
Streaming with Spring Cloud Stream and Apache Kafka - Soby ChackoStreaming with Spring Cloud Stream and Apache Kafka - Soby Chacko
Streaming with Spring Cloud Stream and Apache Kafka - Soby Chacko
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
What is REST API? REST API Concepts and Examples | Edureka
What is REST API? REST API Concepts and Examples | EdurekaWhat is REST API? REST API Concepts and Examples | Edureka
What is REST API? REST API Concepts and Examples | Edureka
 
Hibernate in Action
Hibernate in ActionHibernate in Action
Hibernate in Action
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
Spring MVC Framework
Spring MVC FrameworkSpring MVC Framework
Spring MVC Framework
 
DWARF Data Representation
DWARF Data RepresentationDWARF Data Representation
DWARF Data Representation
 
File system node js
File system node jsFile system node js
File system node js
 
Sequelize
SequelizeSequelize
Sequelize
 
Hibernate presentation
Hibernate presentationHibernate presentation
Hibernate presentation
 
Spring batch overivew
Spring batch overivewSpring batch overivew
Spring batch overivew
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
JavaFX Overview
JavaFX OverviewJavaFX Overview
JavaFX Overview
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
 
GraalVm and Quarkus
GraalVm and QuarkusGraalVm and Quarkus
GraalVm and Quarkus
 

Similar a Practical non blocking microservices in java 8

JDD 2016 - Michał Balinski, Oleksandr Goldobin - Practical Non Blocking Micro...
JDD 2016 - Michał Balinski, Oleksandr Goldobin - Practical Non Blocking Micro...JDD 2016 - Michał Balinski, Oleksandr Goldobin - Practical Non Blocking Micro...
JDD 2016 - Michał Balinski, Oleksandr Goldobin - Practical Non Blocking Micro...PROIDEA
 
Computer network (4)
Computer network (4)Computer network (4)
Computer network (4)NYversity
 
Non-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.jsNon-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.jsMarcus Frödin
 
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)Ontico
 
Hands on with CoAP and Californium
Hands on with CoAP and CaliforniumHands on with CoAP and Californium
Hands on with CoAP and CaliforniumJulien Vermillard
 
Alexander Timorin, Alexander Tlyapov - SCADA deep inside protocols, security ...
Alexander Timorin, Alexander Tlyapov - SCADA deep inside protocols, security ...Alexander Timorin, Alexander Tlyapov - SCADA deep inside protocols, security ...
Alexander Timorin, Alexander Tlyapov - SCADA deep inside protocols, security ...DefconRussia
 
Shmoocon 2013 - OpenStack Security Brief
Shmoocon 2013 - OpenStack Security BriefShmoocon 2013 - OpenStack Security Brief
Shmoocon 2013 - OpenStack Security Briefopenfly
 
SCADA deep inside:protocols and software architecture
SCADA deep inside:protocols and software architectureSCADA deep inside:protocols and software architecture
SCADA deep inside:protocols and software architectureqqlan
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATSKit Chan
 
Scaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersScaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersoazabir
 
OpenStack Security Project
OpenStack Security ProjectOpenStack Security Project
OpenStack Security ProjectTravis McPeak
 
Iot Conference Berlin M2M,IoT, device management: one protocol to rule them all?
Iot Conference Berlin M2M,IoT, device management: one protocol to rule them all?Iot Conference Berlin M2M,IoT, device management: one protocol to rule them all?
Iot Conference Berlin M2M,IoT, device management: one protocol to rule them all?Julien Vermillard
 
SREcon Europe 2016 - Full-mesh IPsec network at Hosted Graphite
SREcon Europe 2016 - Full-mesh IPsec network at Hosted GraphiteSREcon Europe 2016 - Full-mesh IPsec network at Hosted Graphite
SREcon Europe 2016 - Full-mesh IPsec network at Hosted GraphiteHostedGraphite
 
Top Ten Java Defense for Web Applications v2
Top Ten Java Defense for Web Applications v2Top Ten Java Defense for Web Applications v2
Top Ten Java Defense for Web Applications v2Jim Manico
 
Стек Linux HTTPS/TCP/IP для защиты от HTTP-DDoS-атак
Стек Linux HTTPS/TCP/IP для защиты от HTTP-DDoS-атакСтек Linux HTTPS/TCP/IP для защиты от HTTP-DDoS-атак
Стек Linux HTTPS/TCP/IP для защиты от HTTP-DDoS-атакPositive Hack Days
 
Swift Install Workshop - OpenStack Conference Spring 2012
Swift Install Workshop - OpenStack Conference Spring 2012Swift Install Workshop - OpenStack Conference Spring 2012
Swift Install Workshop - OpenStack Conference Spring 2012Joe Arnold
 

Similar a Practical non blocking microservices in java 8 (20)

JDD 2016 - Michał Balinski, Oleksandr Goldobin - Practical Non Blocking Micro...
JDD 2016 - Michał Balinski, Oleksandr Goldobin - Practical Non Blocking Micro...JDD 2016 - Michał Balinski, Oleksandr Goldobin - Practical Non Blocking Micro...
JDD 2016 - Michał Balinski, Oleksandr Goldobin - Practical Non Blocking Micro...
 
Pycon - Python for ethical hackers
Pycon - Python for ethical hackers Pycon - Python for ethical hackers
Pycon - Python for ethical hackers
 
Computer network (4)
Computer network (4)Computer network (4)
Computer network (4)
 
Non-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.jsNon-blocking I/O, Event loops and node.js
Non-blocking I/O, Event loops and node.js
 
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
 
Hands on with CoAP and Californium
Hands on with CoAP and CaliforniumHands on with CoAP and Californium
Hands on with CoAP and Californium
 
Alexander Timorin, Alexander Tlyapov - SCADA deep inside protocols, security ...
Alexander Timorin, Alexander Tlyapov - SCADA deep inside protocols, security ...Alexander Timorin, Alexander Tlyapov - SCADA deep inside protocols, security ...
Alexander Timorin, Alexander Tlyapov - SCADA deep inside protocols, security ...
 
Shmoocon 2013 - OpenStack Security Brief
Shmoocon 2013 - OpenStack Security BriefShmoocon 2013 - OpenStack Security Brief
Shmoocon 2013 - OpenStack Security Brief
 
SCADA deep inside:protocols and software architecture
SCADA deep inside:protocols and software architectureSCADA deep inside:protocols and software architecture
SCADA deep inside:protocols and software architecture
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATS
 
ReplacingSquidWithATS
ReplacingSquidWithATSReplacingSquidWithATS
ReplacingSquidWithATS
 
Scaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersScaling asp.net websites to millions of users
Scaling asp.net websites to millions of users
 
OpenStack Security Project
OpenStack Security ProjectOpenStack Security Project
OpenStack Security Project
 
Iot Conference Berlin M2M,IoT, device management: one protocol to rule them all?
Iot Conference Berlin M2M,IoT, device management: one protocol to rule them all?Iot Conference Berlin M2M,IoT, device management: one protocol to rule them all?
Iot Conference Berlin M2M,IoT, device management: one protocol to rule them all?
 
Scala at Netflix
Scala at NetflixScala at Netflix
Scala at Netflix
 
The basics of fluentd
The basics of fluentdThe basics of fluentd
The basics of fluentd
 
SREcon Europe 2016 - Full-mesh IPsec network at Hosted Graphite
SREcon Europe 2016 - Full-mesh IPsec network at Hosted GraphiteSREcon Europe 2016 - Full-mesh IPsec network at Hosted Graphite
SREcon Europe 2016 - Full-mesh IPsec network at Hosted Graphite
 
Top Ten Java Defense for Web Applications v2
Top Ten Java Defense for Web Applications v2Top Ten Java Defense for Web Applications v2
Top Ten Java Defense for Web Applications v2
 
Стек Linux HTTPS/TCP/IP для защиты от HTTP-DDoS-атак
Стек Linux HTTPS/TCP/IP для защиты от HTTP-DDoS-атакСтек Linux HTTPS/TCP/IP для защиты от HTTP-DDoS-атак
Стек Linux HTTPS/TCP/IP для защиты от HTTP-DDoS-атак
 
Swift Install Workshop - OpenStack Conference Spring 2012
Swift Install Workshop - OpenStack Conference Spring 2012Swift Install Workshop - OpenStack Conference Spring 2012
Swift Install Workshop - OpenStack Conference Spring 2012
 

Más de Michal Balinski

Aplikacje w chmurze (prywatnej) z perspektywy Deva i Opsa
Aplikacje w chmurze (prywatnej) z perspektywy Deva i OpsaAplikacje w chmurze (prywatnej) z perspektywy Deva i Opsa
Aplikacje w chmurze (prywatnej) z perspektywy Deva i OpsaMichal Balinski
 
Integracja Red Hat JBoss Fuse w przetwarzaniu płatności
Integracja Red Hat JBoss Fuse w przetwarzaniu płatnościIntegracja Red Hat JBoss Fuse w przetwarzaniu płatności
Integracja Red Hat JBoss Fuse w przetwarzaniu płatnościMichal Balinski
 
Automatyzacja deploymentów aplikacji enterprise w AWS
Automatyzacja deploymentów aplikacji enterprise w AWSAutomatyzacja deploymentów aplikacji enterprise w AWS
Automatyzacja deploymentów aplikacji enterprise w AWSMichal Balinski
 
Superkomputery i Symulacje (HPC) - AMG.net, NCBJ, WFiIS UŁ
Superkomputery i Symulacje (HPC) - AMG.net, NCBJ, WFiIS UŁSuperkomputery i Symulacje (HPC) - AMG.net, NCBJ, WFiIS UŁ
Superkomputery i Symulacje (HPC) - AMG.net, NCBJ, WFiIS UŁMichal Balinski
 
Projektowanie systemów IT w chmurach obliczeniowych (AMG.net Tech Cafe)
Projektowanie systemów IT w chmurach obliczeniowych (AMG.net Tech Cafe)Projektowanie systemów IT w chmurach obliczeniowych (AMG.net Tech Cafe)
Projektowanie systemów IT w chmurach obliczeniowych (AMG.net Tech Cafe)Michal Balinski
 
Scalable web applications in the cloud
Scalable web applications in the cloudScalable web applications in the cloud
Scalable web applications in the cloudMichal Balinski
 

Más de Michal Balinski (6)

Aplikacje w chmurze (prywatnej) z perspektywy Deva i Opsa
Aplikacje w chmurze (prywatnej) z perspektywy Deva i OpsaAplikacje w chmurze (prywatnej) z perspektywy Deva i Opsa
Aplikacje w chmurze (prywatnej) z perspektywy Deva i Opsa
 
Integracja Red Hat JBoss Fuse w przetwarzaniu płatności
Integracja Red Hat JBoss Fuse w przetwarzaniu płatnościIntegracja Red Hat JBoss Fuse w przetwarzaniu płatności
Integracja Red Hat JBoss Fuse w przetwarzaniu płatności
 
Automatyzacja deploymentów aplikacji enterprise w AWS
Automatyzacja deploymentów aplikacji enterprise w AWSAutomatyzacja deploymentów aplikacji enterprise w AWS
Automatyzacja deploymentów aplikacji enterprise w AWS
 
Superkomputery i Symulacje (HPC) - AMG.net, NCBJ, WFiIS UŁ
Superkomputery i Symulacje (HPC) - AMG.net, NCBJ, WFiIS UŁSuperkomputery i Symulacje (HPC) - AMG.net, NCBJ, WFiIS UŁ
Superkomputery i Symulacje (HPC) - AMG.net, NCBJ, WFiIS UŁ
 
Projektowanie systemów IT w chmurach obliczeniowych (AMG.net Tech Cafe)
Projektowanie systemów IT w chmurach obliczeniowych (AMG.net Tech Cafe)Projektowanie systemów IT w chmurach obliczeniowych (AMG.net Tech Cafe)
Projektowanie systemów IT w chmurach obliczeniowych (AMG.net Tech Cafe)
 
Scalable web applications in the cloud
Scalable web applications in the cloudScalable web applications in the cloud
Scalable web applications in the cloud
 

Último

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAnitaRaj43
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 

Último (20)

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 

Practical non blocking microservices in java 8

  • 1. Practical non-blocking microservices in Java 8 Michał Baliński System Architect Oleksandr Goldobin System Architect
  • 2. Cloud of microservices for secure IoT gateway backing service core service gateway gateway core service backing service
  • 3. The demand and characteristics of our domain Crowded IoT environment Slow, long lived connections Big amount of concurrent connections Scalability and resilience Rather I/O intensive than CPU intensive
  • 4. OTA Gateway – Use Case TSM Trusted Service Manager
  • 5. OTA Gateway – Use Case TSM Trusted Service Manager Security Module
  • 6. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB
  • 7. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB HTTP 1. submit scripts
  • 8. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB HTTP 1. submit scripts HTTP 2. encrypt scripts
  • 9. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB HTTP 1. submit scripts HTTP 2. encrypt scripts TCP 3. store scripts
  • 10. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB HTTP 1. submit scripts HTTP 2. encrypt scripts TCP 4. submition response 3. store scripts
  • 11. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB HTTP 1. submit scripts HTTP 2. encrypt scripts TCP 4. submition response HTTP 5. poll scripts 3. store scripts
  • 12. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB HTTP 1. submit scripts HTTP 2. encrypt scripts TCP 3. store scripts 4. submition response HTTP 5. poll scripts 6. search scripts
  • 13. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB HTTP 1. submit scripts HTTP 2. encrypt scripts TCP 3. store scripts 4. submition response HTTP 5. poll scripts 6. search scripts 7. response with scripts
  • 14. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB HTTP HTTP HTTP TCP
  • 15. OTA Gateway – Use Case OTA (Over-the-Air) Gateway TSM Trusted Service Manager Security Module DB Log Storage HTTP HTTP HTTP TCP File I/OMonitoring System HTTP
  • 17. OTA Gateway Blocking - technologies 25 February 2017 17 TSM DB Log Storage HTTP TCP STDOUT OTA Gateway JAX-RS Logback appender Security Module JAX-RS Jedis JAX-RS Client
  • 18. OTA Gateway – Blocking - test OTA (Over-the-Air) Gateway send 2 scripts per request Security Module DB Log Storage HTTP HTTP HTTP TCP File I/O emulated latency 200 ms expected latency < 450 ms verified with throughput over 7k req/s
  • 19. Blocking – 1k threads OTA (Over-the-Air) Gateway send 2 scripts per request Security Module DB Log Storage HTTP HTTP HTTP TCP File I/O emulated latency 200 ms max 1000 connections max 1000 threads expected latency < 450 ms
  • 20. Blocking – 1k threads 500 req/s 1000 req/s 1500 req/s 2000 req/s
  • 21. The drawbacks of classic synchronous I/O One thread per connection Threads waiting instead of running Context switches Resource wasting (~1 MB per thread - 64bit)
  • 22. Let’s switch from blocking to non-blocking
  • 23. OTA Gateway Non-blocking - technologies 25 February 2017 23 TSM DB Log Storage HTTP TCP STDOUT OTA Gateway JAX-RS 2.0 Logback async appender Async Http Client 2 (Netty) Security Module JAX-RS 2.0 Lettuce (Netty)
  • 24. Non-blocking – 16 threads OTA (Over-the-Air) Gateway send 2 scripts per request Security Module DB Log Storage HTTP HTTP HTTP TCP File I/O emulated latency 200 ms no limit for connections max 16 threads expected latency < 450 ms
  • 25. Non-blocking – 16 threads 1k req/s 2k req/s 2.5k req/s 3k req/s
  • 26. Blocking Non-blocking 1000 threads 56 threads 1.2 GB 0.5 GB ~1.2k r/s 2.5k r/s
  • 27. Let’s talk about challenges
  • 28. OTA Gateway Blocking – sequence diagram OTA Gateway TSM Security Module DB Logs loop 1. submit scripts 2. encrypt script 3a. store script 4. submition response 3b. count scripts
  • 29. OTA Gateway Non-blocking – sequence diagram OTA Gateway TSM Security Module DB Logs loop 1. submit scripts 2. encrypt script 3a. store script 4. submition response 3b. count scripts
  • 30. OTA Non-blocking – realityOTA Gateway TSM Security Module DB Logs „loopedprocessingchain” 1. submit scripts 4. submition response 3b. count scripts HTTP Server 2. encrypt script 3a. store script Logging DB Client Security Client
  • 31. Code. Bird view 3125 February 2017 package org.demo.ota.blocking.rest; @Path("se") public class ScriptSubmissionResource extends Application { private static final Logger log = LoggerFactory.getLogger(ScriptSubmissionResource.class); private static final ResourceMetrics METRICS = new ResourceMetrics("ota_submission"); private SecureModuleClient secureModuleClient = SecureModuleClient.instance(); private ScriptStorageClient scriptStorageClient = ScriptStorageClient.instance(); @POST @Path("/{seId}/scripts") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) public long submitScripts(@PathParam("seId") String seId, List<Script> scripts) { MDC.put("flow", "submission"); MDC.put("se", seId); return METRICS.instrument(() -> { log.debug("Processing {} scripts submission", scripts.size(), seId); for (int i = 0; i < scripts.size(); i++) { final Script script = scripts.get(i); log.debug("Encrypting {} script", i); final String encryptedPayload = secureModuleClient.encrypt(seId, script.getPayload()); script.setPayload(encryptedPayload); log.debug("Storing encrypted script {}", i); scriptStorageClient.storeScript(seId, script); } long numberOfScripts = scriptStorageClient.numberOfScriptsForSe(seId); log.debug("Request processed", seId); return numberOfScripts; }); } @Override public Set<Object> getSingletons() { return Collections.singleton(this); } } package org.demo.ota.nonblocking.rest; @Path("se") public class ScriptSubmissionResource extends Application { private static final Logger log = LoggerFactory.getLogger(ScriptSubmissionResource.class); private static final ResourceMetrics METRICS = new ResourceMetrics("ota_submission"); private SecureModuleClient secureModuleClient = SecureModuleClient.instance(); private ScriptStorageClient scriptStorageClient = ScriptStorageClient.instance(); @POST @Path("/{seId}/scripts") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) public void submitScripts( @PathParam("seId") String seId, List<Script> scripts, @Suspended final AsyncResponse asyncResponse ) { final DiagnosticContext diagnosticContext = new DiagnosticContext("submission", seId); METRICS.instrumentStage(() -> { log.debug("{} Processing {} scripts submission", diagnosticContext, scripts.size()); return encryptAndStoreAllScripts(diagnosticContext, seId, scripts) .thenCompose( ignore -> scriptStorageClient.numberOfScriptsForSe(seId) ); }) .whenComplete((numberOfScripts, e) -> { if (e != null) { asyncResponse.resume(e); } else { log.debug("{} Request processed", diagnosticContext); asyncResponse.resume(numberOfScripts); } }); } private CompletionStage<Void> encryptAndStoreAllScripts( final DiagnosticContext diagnosticContext, final String seId, final List<Script> scripts ) { CompletionStage<Void> stage = null; // <- non final field, potential concurrent access bug! for (int i = 0; i < scripts.size(); i++) { final int scriptIndex = i; final Script script = scripts.get(scriptIndex); if (stage == null) { stage = encryptAndStoreSingleScript(diagnosticContext, seId, scriptIndex, script); } else { stage = stage.thenCompose(ignore -> encryptAndStoreSingleScript(diagnosticContext, seId, scriptIndex, script)); } } return stage; } private CompletionStage<Void> encryptAndStoreSingleScript( final DiagnosticContext diagnosticContext, final String seId, final int scriptIndex, final Script script ) { log.debug("{} Encrypting script {}", diagnosticContext, scriptIndex); return secureModuleClient .encrypt(seId, script.getPayload()) .thenCompose( encryptedPayload -> { log.debug("{} Storing encrypted script {}", diagnosticContext, scriptIndex); return scriptStorageClient.storeScript(seId, new Script(encryptedPayload)); } ); } @Override public Set<Object> getSingletons() { return new HashSet<>(Collections.singletonList(this)); } }
  • 32. Code. Blocking. Submission 1 25 February 2017 32 @POST @Path("/{seId}/scripts") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) public long submitScripts(@PathParam("seId") String seId, List<Script> scripts) { MDC.put("flow", "submission"); //  Setting diagnostic context MDC.put("se", seId); return METRICS.instrument(() -> { //  Instrumenting with metrics //...
  • 33. Code. Blocking. Submission 2 25 February 2017 33 log.debug("Processing {} scripts submission", scripts.size(), seId); for (int i = 0; i < scripts.size(); i++) {  Cycle through the scripts final Script script = scripts.get(i); log.debug("Encrypting {} script", i); final String encryptedPayload = secureModuleClient .encrypt(seId, script.getPayload());  Encrypting the script script.setPayload(encryptedPayload); log.debug("Storing encrypted script {}", i); scriptStorageClient.storeScript(seId, script);  Saving the script into DB } long numberOfScripts = scriptStorageClient.numberOfScriptsForSe(seId);  Getting current number of scripts in DB log.debug("Request processed", seId); return numberOfScripts;
  • 34. Code. Non-blocking. Submission 1 25 February 2017 34 @POST @Path("/{seId}/scripts") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) public void submitScripts( @PathParam("seId") String seId, List<Script> scripts, @Suspended final AsyncResponse asyncResponse ) { final DiagnosticContext diagnosticContext = new DiagnosticContext("submission", seId);  Creating diagnostic context METRICS.instrumentStage(() -> {  Instrumenting with metrics
  • 35. Code. Non-blocking. Submission 1 25 February 2017 35 @POST @Path("/{seId}/scripts") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) public void submitScripts( @PathParam("seId") String seId, List<Script> scripts, @Suspended final AsyncResponse asyncResponse ) { final DiagnosticContext diagnosticContext = new DiagnosticContext("submission", seId);  Creating diagnostic context METRICS.instrumentStage(() -> {  Instrumenting with metrics
  • 36. Code. Non-blocking. Submission 2 25 February 2017 36 METRICS.instrumentStage(() -> { log.debug( "{} Processing {} scripts submission", diagnosticContext, scripts.size()); return encryptAndStoreAllScripts(diagnosticContext, seId, scripts) .thenCompose( ignore -> scriptStorageClient.numberOfScriptsForSe(seId) ); }) .whenComplete((numberOfScripts, e) -> { if (e != null) { asyncResponse.resume(e); } else { log.debug("{} Request processed", diagnosticContext); asyncResponse.resume(numberOfScripts); } });
  • 37. Code. Non-blocking. Submission 3 25 February 2017 37 private CompletionStage<Void> encryptAndStoreAllScripts( final DiagnosticContext diagnosticContext, final String seId, final List<Script> scripts ) { CompletionStage<Void> stage = null; // <- non final field, potential // concurrent access bug! for (int i = 0; i < scripts.size(); i++) {  Cycle through the scripts final int scriptIndex = i; final Script script = scripts.get(scriptIndex); if (stage == null) { stage = encryptAndStoreSingleScript( diagnosticContext, seId, scriptIndex, script); } else { stage = stage.thenCompose(ignore -> encryptAndStoreSingleScript( diagnosticContext, seId, scriptIndex, script)); } } return stage; }
  • 38. Code. Non-blocking. Submission 4 25 February 2017 38 private CompletionStage<Void> encryptAndStoreSingleScript( final DiagnosticContext diagnosticContext, final String seId, final int scriptIndex, final Script script ) { log.debug("{} Encrypting script {}", diagnosticContext, scriptIndex); return secureModuleClient .encrypt(seId, script.getPayload())  Encrypting the script .thenCompose( encryptedPayload -> { log.debug( "{} Storing encrypted script {}", diagnosticContext, scriptIndex); return scriptStorageClient.storeScript(  Saving the script into seId, the DB new Script(encryptedPayload)); } ); }
  • 39. Code. Blocking. Integration 25 February 2017 39 private final JedisPool pool; public void storeScript(String seId, Script script) { try (Jedis jedis = pool.getResource()) { jedis.rpush(seId, script.getPayload()); } } public long numberOfScriptsForSe(String seId) { try (Jedis jedis = pool.getResource()) { return jedis.llen(seId); } } public Optional<Script> nextScript(String seId) { try (Jedis jedis = pool.getResource()) { return Optional.ofNullable(jedis.lpop(seId)).map(Script::new); } } public String encrypt(String keyDiversifier, String payload) { // ... }
  • 40. Code. Non-Blocking. Integration 25 February 2017 40 private final RedisAsyncCommands<String, String> commands; public CompletionStage<Void> storeScript(String seId, Script script) { return commands .rpush(seId, script.getPayload()) .thenApply(ignore -> null); } public CompletionStage<Long> numberOfScriptsForSe(String seId) { return commands.llen(seId); } public CompletionStage<Optional<String>> nextScript(String seId) { return commands.lpop(seId).thenApply(Optional::ofNullable); } public CompletionStage<String> encrypt(String keyDiversifier, String payload) { // ... }
  • 41. Diagnostics in non-blocking systems No clear stack traces, need for good logs Name your threads properly MDC becomes useless (thread locals) Explicitly pass debug context to trace flows Be prepared for debuging non-obvious errors
  • 42. NIO technology landscape JDK 1.4 NIO JDK 1.7 NIO.2 JAX-RS 2.x Servlet API 3.x
  • 43. Lessons learned, part 1 Vanila Java 8 for NIO µ-services Netty best for custom protocols in NIO Unit tests should be synchronous Load/stress testing is a must Make bulkheading and plan your resources
  • 44. Lessons learned, part 2 Functional programming patterns for readability Immutability as 1-st class citizen Scala may be good choice ;-)
  • 45. Conclusion Non-blocking processing can really save your resources (== money) But! Weight all pros and cons and use non-blocking processing only if you really need it.
  • 46. Thank you. Michał Baliński m.balinski@oberthur.com Oleksandr Goldobin o.goldobin@oberthur.com goldobin @goldobin balonus @MichalBalinski Readings: • https://github.com/balonus/blocking-vs-nonblocking-demo • C10k Problem, C10M Problem, Asynchronous I/O • Boost application performance using asynchronous I/O (M. Tim Jones, 2006) • Zuul 2 : The Netflix Journey to Asynchronous, Non-Blocking Systems (Netflix, 2016) • Thousands of Threads and Blocking I/O: The Old Way to Write Java Servers Is New Again (and Way Better) (Paul Tyma, 2008) • Why Non-Blocking? (Bozhidar Bozhanov, 2011)

Notas del editor

  1. Michał
  2. Alex Our products are operating in pretty "crowded" environment The clients of our services are: from the one site: service providers like MNO or Banks from the other site: crowds of devices like secure elements in mobile and IoT devices those devices maintaining SLOOOW, long living connections The demand of the market is to process pretty big amount of concurrent connections in a secure way We also should be scalable and resilient -> micro-services architecture The microservices in IT are generally performing some kind of gateway role: receive request request other web services/database for some data synchronize and process responses respond (or not) to the caller So primarily they are IO intensive rather then CPU intensive The most CPU intensive part is actually marshalling/unmarshaling of requests/responses
  3. Michał
  4. Michał
  5. Michał
  6. Michał
  7. Michał
  8. Michał
  9. Michał
  10. Michał
  11. Michał
  12. Michał
  13. Michał
  14. Alex
  15. Alex
  16. Alex
  17. Alex
  18. Michał
  19. Alex TODO reconsider order of slides Your are forced to have one thread per connection Those threads actually waiting for the data instead of perform real work This leads to big amount of context switches And also this leads to resource wasting because threads are expensive For example you can't create more than 4000 threads (on the latest Mac Book Pro -> OOM ) Christopher Batey - $8 per year on AWS EC2
  20. Alex
  21. Alex
  22. Alex
  23. Alex
  24. Michał
  25. TODO kick out?
  26. Michał
  27. Michał
  28. Michał
  29. Alex
  30. Alex It is harder to debug: no clear stack traces; you're more relying on logs; It is harder to trace business flows: MDC becomes useless (thread locals); To trace business flows you need to pass (or close on) some immutable (!!!) debugging context;
  31. Michał Servers: JaxRS 2.x implementation like RestEasy 3.x with @Suspended annotation support Netty Akka (IO, Http) – different story, still better used with Scala (sorry ) Clients: Async Http Client 2.0 Latest database clients: Lettuce for Redis Cassandra Mongo DB JDBC drivers by nature blocking :( Akka (IO, Http)
  32. Alex + Michał (last one) JDK 8 + some libraries like Netty (vanilla Java) are sufficient to implement non-blocking processing and build micro-services (no additional huge frameworks really required) Async code can be readable but it requires to apply functional programming patterns which are not common for classic approach As soon as you're using several threads to process your flows immutability becomes 1-st class citizen Unit tests should be synchronous -- no concurrency at all or fully synchronized on test's execution thread (which can be challenging sometimes) Sometimes you need to develop your own tools to make tests locking like scenarios and not as complex asynchronous code; Load/stress testing is a must - you really need to stress your system to check that it behaves properly
  33. Michał + Alex (last one) Do not use MDC use some context passing technique (like we showed in example); Name your threads properly: it will help you to investigate/profile issues; Make bulkheading and plan your resources utilization in advance, adjust configuration while performing load/stress tests; Be prepared to solve some non-obvious errors (like direct memory OOM or virtual memory OOM); Implementing graceful shutdown is tricky, design it from the beginning; Netty is a best library to implement custom protocols in non-blocking way in Java; Technically Scala still provides better toolset for non-blocking asynchronous data processing (standard library and/or Akka) -- but it is different topic ;)
  34. Alex