Presentation from Warsjawa 2014 workshop "Microservices in Scala". Topics covered:
- What are microservices?
- What's the difference between them vs monolithic
architectures?
- What are the different flavours of microservices?
Unlocking the Future of AI Agents with Large Language Models
Microservices - opportunities, dilemmas and problems
1. Microservices in Scala
workshop by Iterators
by Jacek Głodek, Łukasz Sowa and Andrzej Michałowski
2. Questions we try to answer today:
• What are microservices?
• What's the difference between them vs monolithic
architectures?
• What are the different flavours of microservices?
• How to use Spray.io, Play and Akka to do
microservices?
3. Agenda
• Short introduction to microservices
• Spec of our system
• "MS backbone - simple microservices with spray.io" talk
• Auth and url collection microservices
• "Asynchronous views and web services with Play and Akka" talk
• Image fetching — reactive deffered job — Play with websockets
• "Eventsourcing - total data immutability with akka persistence" talk
• Voting made with event sourcing
• Ops, testing and monitoring
• Summary
4. Architectures and practices
What architectures are we talking about?!
Don't think MVC, think MVC web-app run on multiple
nodes with load-balancing, memcached cache and
Postgres db.
What practices are we talking about?!
Think TDD, BDD, SOLID, etc.
5. Code and code-base
architecture and practices
• programming paradigms
• TDD, SOLID, BDD, etc.
• Folder structure
• Object naming conventions
• Separation of concerns
• Sharing data in threads
6. Distributed system
architecture
• Interfaces, protocols and
contracts between modules
• System modules
• APIs
• Deployment strategy
• Non-functional guarantees
7. “Microservices”
is a vague term
• multiple small apps with REST/HTTP interface,
• multiple small apps with deferred message
processing
• multiple single-file apps with less than 100 lines of
code
• multiple small apps possibly written in different
languages communicating with each other
11. Microservices vs Monolithic architecture
Coupling
Monolith Microservices
• global variables
• messages
• function calls
• data structures
• shared memory
• multiple levels of indirection
managed with
• SOLID, encapsulation and other practices
• dependency injection, etc.
• different protocols
• shared DB’s
• shared message queues
managed with
• contracts
12. Microservices vs Monolithic architecture
Interfaces vs Contracts
Monolith Microservices
• written with code and shared interfaces
within code packages and libraries
• checked by tests or compilers (?)
• type validations
• api calls defined by the language
• encapsulation, single-responsibility
rule, etc.
Problems:
• meta-programming, monkey-patching,
global state and workarounds.
• spoken / unspoken
• should be defined on “paper”
• defined by protocols, and technologies
used, like:
• http, websockets, RPC, rabbitMQ,
shared MongoDB or Redis, etc. )
Problems:
• changing contract or having no contract
requires changing multiple services.
• multiple API versions without easy
solution for validating consistency
14. Small single purpose code
• Low complexity
• No code-level coupling
with other modules
• “this big” or one
hundred lines of code
• Easy to rewrite
• Rewrite instead of
refactor
• Easy to spot inputs and
outputs
• Still requires readable
logic
15. Relevant metrics
• Measuring business
performance using relevant
metrics
• Visualisation
• Ex. Kamon, custom charts
Ex:
• forms processed,
• mails sent,
• PDF invoices generated
• performance metrics:
• response times
• queue sizes
• ex. New Relic, etc.
16. Continuous deployment with hot
swapping
Having all the metrics:
• You can deploy continuously
• You can test the service by deploying new and old
versions concurrently.
• Given enough fail-safety contracts, you can test in
production
• One service down shouldn’t break whole architecture
19. Problems and Dilemmas
• synchronous and asynchronous processing
• guarantees and SLAs
• shared and private databases
• making layers of micro services
• bare-metal vs platforms
• data-driven systems, eventsourcing and real-time
messaging
20. Synchronous vs
Asynchronous processing
Synchronous processing
• immediate responses
• fast and hard failure
• “asking”
• request timeouts
• problematic to debug series of request
Ex. chain of HTTP request and getting 200
Success response
Asynchronous processing
• posting jobs to be processed
• tell don’t ask
• fire and forget
• need of pooling or waiting for response
• longer jobs
• failures can be recovered from!
Ex. uploading a video file to be processed
and getting “Video uploaded successfuly”
response.
21. Guarantees and SLA’s
Is clicking like button same as performing bank transfer? Do we really need full
ACID DB for holding chat messages? Will it perform fast enough to serve
thousand of clients concurrently without building whole cluster of DB’s?
100% consistency and synchronicity is not possible to achieve in distributed
system without introducing system wide locks.
System-wide locks affect performance a lot, while we try to achieve reactive and
scalable system.
In microservices we can keep different parts of system with different guarantees
and different approaches
22. Shared vs private databases
Shared database
• pretty strong contract
• convenient for simple domain problems
• easier to maintain
• problems:
• coupling too many services, too deeply.
• can become performance bottle-neck
Private databases
• useful for decoupling and reuse
• useful for performance
• useful for embedding in microservices that abstract
complicated domain models
• difficult to maintain, although can many databases can
work on single db cluster/instance.
• useful for giving microservice authority over some data
• problems:
• data sharding
23. Layers of micro services
frontend, public facing micro services,
background workers and services
24. Layers of micro services
frontend issues
• CORS (Cross Origin Resource Sharing)
• Rendering of HTML: server-side or in javascript
• Moving caches to CDN
• Keeping modularity and reusability also on the frontend side
• One backend microservice failure shouldn’t break whole frontend.
25. Layers of micro services
user facing services issues
• CORS
• Versioning of API
• Authentication
• Caching
• Loadbalancing
• Security
26. Layers of micro services
internal services
• Security
• Scalability
• Monitoring for failures
• Keeping the data consistent
• Garbage-in garbage-out
27. Platform abstraction level
bare-metal servers vs platforms
Higher level framework = more difficult polyglot
programming + easier maintenance + possible code
sharing + more tight coupling opportunities
28. Stateful databases vs
eventsourcing
Stateful databases
• State stored in the database
• Ex. “John has $3122
USD on his account”
• Transactions and locks that
enable us to mutate the
state
Eventsourcing
• No state just events.
• Ex. “John got spent $12 USD”
• State is inferred from the past
events…
• Every situation can be replayed!
• Events are immutable = no
problem with locking, etc.
We can also not care about keeping the data at all.
36. Summary
Spray is great foundation:
for simple HTTP services
for connecting with awesome Akka processing framework
with great directives for strictly defining what requests get
processed
with great marshalling and serialisation
who make simple easy and abstractable
37. Summary
Play is has some useful elements:
!
nice routing DSL,
nice controller with Action composing
nice Websockets with Akka actors
lots of libraries to integrate to
big boilerplate
38. Summary
Akka is great for messaging, makes concurrent
programming easy!
! Actors are not threads
Messages and Questions with timeouts
Scheduling
Watch not to make bloated — keep it single
purpose
39. Summary
Eventsourcing !
! Don’t store mutable state
Store immutable events
Rebuild state by processing the past events
Akka persistance stores the events for you in a
journal of choice (Mongo, Redis, Postgres, Maria,
Mysql)
40. What haven’t we talked about
!
JVM microframeworks — Finagle, etc.
Frontend — how to keep modularity, where to generate HTML,
how to handle caching.
Monitoring — health checks and metrics (spray directives?) and
monitoring front end
DevOps — How to configure loadbalancers, CORS, handling
configuration and discovery of microservices, prepare auto-scaling,
and handling situations when services fail, or how to make
hot swap deployments.
41. Thanks!
Łukasz Sowa @luksow
lukasz@theiterators.com
Jacek Głodek @jacekglodek
jacek@theiterators.com