show of hands who knows what they are? who's using them?
what's the problem with monoliths? Why add complexity?
Separation of concerns
Avoid duplication of business logic
Smaller codebases
Easier to understand
Smaller teams
Small autonomous teams. New projects can easily be started by cross-functional teams, less time wasted on synchronisation
Independent lifecycles
Independent release schedules, independent deployments. No more "stop the world" releases
Maybe the most important thing to understand about microservices
Compartimentalize failure
If a part of your system is hanging (typically HTTP thread exhaustion, it doesn't bring your whole system down)
Allow different scaling policies
simple stateless part of the system can scale out big stateful part can scale up parts that are harder to scale are stripped down to control their growth
Polyglot tech stacks
Language best suited for the task. Maybe it's a bash script to pilot a C reverse proxy, or a JEE API, or a small scala service
JEE
Main API complex HTTP API & data models
JSE
Simple queue management, no HTTP API will be eventually replaced by something more suited with streams like akka streams
Scala
data management api. good modelisation, good perf
Node Js
small services, was very good at managing push stuff at some point. slowly rewritten as well
Ruby & bash
good for system scripting
Rust
good fit for many things, will partly replace other languages small footprint, easy to deploy
Try new things
some services are less critical, they're the best place to experiment without risk: I've written stuff in go, no I know why I won't use it any more
Polyglot persistence
No central data model
no more central data model
Drop your SQL monolith
Different datastore scaling
multiple data stores with different capabilities / scaling needs and possibilities
Keep your monolith
There are reasons to stay on a monolithic arch
Increased complexity
- more deployments - hidden failure modes
More deployments
Tricky failure modes
Bad network
Can you afford microservices?
Are you ready for microservices ? There are prerequisites
Rapid provisionning
Lots of applications, designed to ease scale out => you need to make room for a new instance very quickly
Basic monitoring
Lots of application, you need to know when one fails.
Rapid application deployment
Easy rollback / restart on failure. Scaling out quickly reduces the degraded quality during traffic surges
12factor
Go farther than the 3 core requirements. 12 factor is completely suited for microservices architectures.
Aparté Clever sur not mandatory
Automate everything
Automate builds
Automate config injection
Automate deployments
Automate whole env provisionning
Don't share state
Each microservice is responsible for its own state no shared access to a DB end of the "SQL store + multiple applications writing in it"
Make state explicit
No persistent local state
Put sessions in a proper DB
Use S3 for files
Use explicit synchronization
don't write your own transaction system in mongodb
Use zk, etcd, consul for transactions
The hard parts
Network is fragile, errors happen
Complexity is still here
Complexity is outside the code
Know your failure modes
Where will your system break? If service A breaks, what will it take down? If service A is dead slow, what will it make slow?
Know if a call is local or distant
If you feel like you're doing RPC everywhere, then your boundaries are likely bad
Make boundaries explicit
ORMs
"vietnam of computer science"
RMI
let's pretend the network doesn't exist
Hidden complexity == tech debt
if a system seems less complex than its domain, then there's accidental complexity hiding somewhere and you won't find it until it's too late
Hexagonal architecture
Each microservice or DB is an implementation. Clear zoning. Your topology manager does the plugging
Know your topology
You MUST know how services relate to each other, where network is involved. Semantic topology. a docker-compose.yml or a kubernetes JSON config file is not a proper way to define a topology, the same way that a makefile does not describe your business model
Make topology explicit
Make micro-services topology-agnostic
- rabbitMQ instead of HTTP to make a service topology-agnostic
RabbitMQ or HTTP?
Boundaries
Document interactions
- document and specify interactions
Know your protocols
- for HTTP, endpoints and representation structures - for message brokers, exchanges / queue names / topics / … - shared protocols description - at the very least serialization & data types
Serialization
Language-specific serde
Breaks polyglotism
Poor tooling and documentation
Extended attack surface
Turing-complete serde
is bad
XML
nice support for schema and links expensive parsing hard to use, verbose, too powerful (security risk)
JSON
decent support ~everywhere simple enough
JSON schema
representation structure
Swagger / RAML
endpoints integrates document structure API explorer client generation
Avro
serialization system best contendent for a greenfield project