3. About Me
• Pavel Mička
• Software architect at ZOOM International
• Modernizing CallRecording and WorkForce
Optimization application
• Previously: Software engineer at Cisco
Systems
• Breaking up monolith, I helped to build
• pavel.micka@zoomint.com
• @pavelmicka_xyz
5. Monolith - advantages
• Default architectural style
• Whole application in one piece
• One deployable artifact
• Easy to distribute
• All data in one place
• Doing cross-selects is trivial
• Strong consistency model
• Extremely good processing latency
• There is no network…
6. Monolith - drawbacks
• Increasingly hard to maintain/evolve
• Internal parts tightly coupled (interdependencies)
• Technological monoculture
• Hard to start/setup
• A lot of dependencies
• Hard to scale independently
• Hard to assign clear responsibilities
• Usually ends up in Big Ball of Mud
• HA is often problematic (shared state)
“If you have only a hammer, everything looks as a nail”
8. Microservice architecture
• Separately deployable
• Built around bounded context
• Vertical slice of functionality
• Size: 2 pizza team
• Internals are opaque
• Services separated using API
9. Microservices – advantages
• Fast release cycle
• Each service may be written using different technology
• Are small
• Extremely resilient, if written properly
• Microservice architecture scales well
• You can scale the technology by feature
• More important: you can scale the TEAM
10. Drawbacks: There is no silver bullet
• Do not do microservices, if you have
• Just started with the project
• Legacy product without fast development
• Limited automation
• Slow release cycle & Waterfall
• Small number of developers
• Low latency requirements
• Low memory requirements
12. The “showcase” service
• Audit log
• Used for compliance reasons
• Logs all user actions
• All user actions must be logged
• This is real production code
• Basic tech facts
• Java 8/11
• Spring Boot
• Built using Gradle
• Artifact: RPM
16. Implement DevOps
• Take care of the full lifecycle
• Create GIT repo
• Create build pipeline
• Build the code
• Test it
• Get it to distribution
• Distribute it
• Maintain it
• Microservices are about agility & rapid delivery
• If you need an external team for everything, you will not be very agile…
17. Describe you data model
• What are the entities in your business?
• Formalize them
• What properties/relations do they have?
• How they fulfil the business use case?
• How do you want to expand your model from business perspective?
• Regardless if you are 10 years on the market, perform this
exercise…
• You may find out that you current model contains contradictions
• And/Or does not fully satisfy the needs of your customers
19. Standardize quality & testing
• Use latest versions of libraries
• OWASP/Continuous security is a good vehicle
• Other teams are easily able to help, when scenarios are covered
by tests
• Tests are easily executable without exotic setup
• Consider: TestContainers
• Do not: run tests against “database in lab”
20. Standardize Versioning
• Use semantic versioning (1.3.2)
• Only visible API is versioned
• Patch == No change in API (bugfixes, new libs…)
• Minor == Additive change in API
• Major == Something was removed/modified
• Pitfalls
• Change in interpretation is breaking (timestamp in ms vs. ns)
• If you rewrite JS to Cobol, but keep API, its just a patch change
22. Create a paved path
• Using Spring Boot is just the start
• Create opinionated chassis
23. Build in resiliency
• Because of network you cannot distinguish:
• Request was lost on the way
• Request failed during processing
• Response failed
• Request or response are still on their way
• Request/response can though a different network line
• Slow request causes cascading failures
• Use bulkheads
• Use circuit breakers
26. Build is also a code
• Build is also a code
• Gradle & Maven: use plugins
• Continuous integration: use templates
Example
• apply plugin: ‘quality-plugin’
• Coverage, PMD, Checkstyle, licenses, reports, OWASP
• Build of RPM or Docker should be also a one-liner
• Preconditon: all projects have the same structure
27. Use integration tests
• Integration tests == testing the component as a whole, DB included
• Unit Tests: You have unit tested app & its security in isolation
• Performing integration tests suite should be relatively cheap
• The service surface is small
• Gives you sense of security that its really works
• You still need a unit test suite
28. Avoid N+1 scenarios
• 2 services (one handling users, other logs)
• Load N users, load logs for each one separately
• May somehow work in a single transaction
• BUT if logs and users are in different microservice, it will not work
• You will tend to implement caches (hint: don’t)
• Implement multiget
29. Observability: Monitoring and Logging
• Centralized monitoring
• Have an overview of all state of all services in one place
• Use TVs in your office for dashboards (if you are a cloud company)
• Centralized logging
• Have log messages in one place (you want to correlate)
• Its not fun to search the flow through 7 services, each with 3 instances
• Distributed tracing
• Be able to track your request across many services
30.
31.
32. What about consistency?
• With microservices you get eventual consistency
• Eventually the system will end up in consistent state
• Heavy use of queues
• Idempotent operations
• Strong consistency via distributed transactions?
• Creates more issues than is really solves
• Its expensive
• Some error states need to be manually resolved in 2 phase commit
33. Eventually consistent delete
• Delete agent and all his logs
• Message cannot be lost
• If delete from customer db fails
• The message was not ACKed
• The same applies to billing
• This is choreography based
• Other option: orchestration