Microservices
Design, connect and operate services that stay up when one of them falls over.
Take this course in the learning hubLessons
- Monolith vs microservicesUnderstand what actually changes when one deployable becomes many, and what it costs you.
- Finding service boundariesDraw boundaries around business capabilities so services stay independent instead of chatty.
- Synchronous calls done rightCall another service over HTTP with a client that has timeouts, and see the risk you just took on.
- Asynchronous messagingUse events so a slow or dead consumer cannot take the producer down with it.
- The API gatewayPut one front door in front of your services and keep cross-cutting concerns out of each one.
- Service discoveryFind healthy instances by name instead of hard-coding IPs that go stale on every deploy.
- Configuration and secretsKeep configuration out of the jar so one image runs unchanged in dev, staging and production.
- Resilience: timeout, retry, breakerStop one failing dependency from dragging down every service that calls it.
- IdempotencyMake repeated requests safe so retries and at-least-once delivery stop being frightening.
- Distributed transactions and sagasReplace the transaction you cannot have across services with a sequence of steps and compensations.
- Eventual consistency and the outboxAccept that copies lag for a moment, and publish events atomically with the outbox pattern.
- Tracing and correlation idsFollow a single user request across every service by propagating one id into logs and spans.
- Centralised logs and metricsShip structured logs to one place and export the few metrics that reveal a sick service.
- Versioning your APIsChange a contract without breaking the callers you cannot redeploy at the same moment.
- When not to use microservicesSpot the cases where a modular monolith wins and splitting early makes everything harder.
- Strangler fig: splitting a monolithMove a monolith to services one route at a time, keeping a way back at every step.
- Testing a service you cannot run alonePush each kind of bug down to the cheapest layer of test that can still catch it.
- Consumer-driven contract testsCatch a breaking API change inside the provider build instead of in production.
- Securing service-to-service callsAuthenticate every hop instead of trusting the network your services happen to share.
- Service mesh and the sidecarMove mTLS, retries and traffic rules out of every service and into the proxy beside it.
- CQRS and read modelsSplit the write shape from the read shape when one table cannot serve both well.
- Caching between servicesCut repeat calls with a cache, and decide up front how stale an answer may be.
- Graceful shutdown and drainingFinish the requests you already accepted before the pod is allowed to disappear.
- Backend for frontend (BFF)Give each client one endpoint that fans out, so a phone is not making six calls.
- Rolling, blue-green and canaryRelease a service with no maintenance window, and get the change back out in seconds.
- Why splitting a service can lower availabilityLatency adds and availability multiplies - the maths that decides your architecture.
- The dual-write problem and the outbox patternSaving a row and publishing an event are two systems - and there is no transaction across them.
- Retry amplification and metastable failureHow a brief blip becomes an outage that outlives its own cause.
- Capacity planning: threads, pools and Little lawThe arithmetic that tells you how many instances and connections you actually need.
- Making operations genuinely idempotentRecording that you processed something is not enough when the side effect is elsewhere.
- Debugging a failure across servicesA method for finding the cause when the symptom is three services away.
- Multi-tenancy: isolation versus costThree models, and why the cheapest one is the hardest to get right.
- Anti-patterns that undo the whole exerciseThe six mistakes that turn services back into a harder-to-run monolith.