This document presents ways to optimize Java application code that applies the Producer Consumer design pattern for use with Microservices, showcasing real-world examples from our own experience with Dynatrace server code, and presenting specific ideas, guidelines, and techniques that can be applied to architecting Java applications for improved modularity.
8. 8 #Dynatrace
Producer Consumer 2
Consumer 1
Consumer N
Visit Store Collection
Work QueueCorrelation Engine
Real Time Analyzer
Producer Consumer Within AppMon
9. 9 #Dynatrace
Producer Consumer 2
Consumer 1
Consumer N
Visit Store Collection
Work Queue
Work Queue
Getting Full
Problem Symptom
15. 15 #Dynatrace
Code Snippet
public synchronized void add(Visit visit) {
Objects.requireNonNull(visit);
super.add(visit);
}
public synchronized Visit get(int visitId) {
return super.get(visitId);
}
Exclusive lock on visit
store caused consumers
to wait on each other
39. 39 #Dynatrace
26.7s Load Time
5kB Payload
33! Service Calls
99kB - 3kB for each call!
Single Search Query End-to-End
40. 40 #Dynatrace
26.7s Load Time
5kB Payload
33! Service Calls
99kB - 3kB for each call!
Architecture Violation
Direct access to DB from frontend service
Single Search Query End-to-End
41. 41 #Dynatrace
26.7s Load Time
5kB Payload
33! Service Calls
99kB - 3kB for each call!
171!Total SQL Count
Architecture Violation
Direct access to DB from frontend service
Single Search Query End-to-End
42. 42 #Dynatrace
The Fixed End-to-End Use Case
“Re-Architect” vs “Migrate” to Service-Orientation
2.5s (vs 26.7)
5kB Payload
43. 43 #Dynatrace
The Fixed End-to-End Use Case
“Re-Architect” vs “Migrate” to Service-Orientation
2.5s (vs 26.7)
5kB Payload
1! (vs 33!) Service Call
5kB (vs 99) Payload!
44. 44 #Dynatrace
The Fixed End-to-End Use Case
“Re-Architect” vs “Migrate” to Service-Orientation
2.5s (vs 26.7)
5kB Payload
1! (vs 33!) Service Call
5kB (vs 99) Payload!
3!(vs 177) Total
SQL Count
49. 49 #Dynatrace
Over To You
• Power of producer consumer pattern
• Parallelize your reads
• Measure before and after
• Affect of Inter-tier communication in
Microservices
• Do not ignore dependencies
Hinweis der Redaktion
Lessons Learned!
They had a monolithic app that couldnt scale endlessly. Their popularity caused them to think about re-architecture and allowing developers to make faster changes to their code. The were moving towards a Service Approach
They had a monolithic app that couldnt scale endlessly. Their popularity caused them to think about re-architecture and allowing developers to make faster changes to their code. The were moving towards a Service Approach
They had a monolithic app that couldnt scale endlessly. Their popularity caused them to think about re-architecture and allowing developers to make faster changes to their code. The were moving towards a Service Approach
They had a monolithic app that couldnt scale endlessly. Their popularity caused them to think about re-architecture and allowing developers to make faster changes to their code. The were moving towards a Service Approach
Separating frontend logic from backend (search service). The idea was to also host these services potentially in the public cloud (frontend) and in a dynamic virtual enviornment (backend) to be able to scale better globally
On Go Live Date with the new architecture everything looked good at 7AM where not many folks were yet online!
By noon – when the real traffic started to come in the picture was completely different. User Experience across the globe was bad. Response Time jumped from 2.5 to 25s and bounce rate trippled from 20% to 60%
The backend service itself was well tested. The problem was that they never looked at what happens under load „end-to-end“. Turned out that the frontend had direct access to the database to execute the initial query when somebody executed a search. The returned list of search result IDs was then iterated over in a loop. For every element a „Micro“ Service call was made to the backend which resulted in 33! Service Invokations for this particular use case where the search result returned 33 items. Lots of wasted traffic and resources as these Key Architectural Metrics show us
The backend service itself was well tested. The problem was that they never looked at what happens under load „end-to-end“. Turned out that the frontend had direct access to the database to execute the initial query when somebody executed a search. The returned list of search result IDs was then iterated over in a loop. For every element a „Micro“ Service call was made to the backend which resulted in 33! Service Invokations for this particular use case where the search result returned 33 items. Lots of wasted traffic and resources as these Key Architectural Metrics show us
The backend service itself was well tested. The problem was that they never looked at what happens under load „end-to-end“. Turned out that the frontend had direct access to the database to execute the initial query when somebody executed a search. The returned list of search result IDs was then iterated over in a loop. For every element a „Micro“ Service call was made to the backend which resulted in 33! Service Invokations for this particular use case where the search result returned 33 items. Lots of wasted traffic and resources as these Key Architectural Metrics show us
The backend service itself was well tested. The problem was that they never looked at what happens under load „end-to-end“. Turned out that the frontend had direct access to the database to execute the initial query when somebody executed a search. The returned list of search result IDs was then iterated over in a loop. For every element a „Micro“ Service call was made to the backend which resulted in 33! Service Invokations for this particular use case where the search result returned 33 items. Lots of wasted traffic and resources as these Key Architectural Metrics show us
They fixed the problem by understanding the end-to-end use cases and then defined backend service APIs that provided the data they really needed by the frontend. This reduced roundtrips, elimiated the architectural regression and improved performance and scalability
They fixed the problem by understanding the end-to-end use cases and then defined backend service APIs that provided the data they really needed by the frontend. This reduced roundtrips, elimiated the architectural regression and improved performance and scalability
They fixed the problem by understanding the end-to-end use cases and then defined backend service APIs that provided the data they really needed by the frontend. This reduced roundtrips, elimiated the architectural regression and improved performance and scalability