Microservices are becoming a popular paradigm in software engineering, but without much specific definition. The idea sounds compelling on paper and can provide real advantages for separation of concerns, system availability, and enabling devops practices. However, microservices come with a set of foundational challenges that must be addressed in order to realise those benefits; first and foremost, what do we mean by "microservices" in the first place?
In this talk, I present what we have found to be an effective definition of microservices architecture and requirements for an practical implementation.
2. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Agenda
Microservices!
This is a very complicated topic
Questions: raise your hand (may defer to end)
Follow up on Twitter: @jeremey (that's 3 e's!)
Perspective disclaimer
2
4. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
What are microservices, anyway?
4
5. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Our story: Cloud Insight
Why are we talking about microservices?
Two years ago: new vulnerability assessment product from the ground up
Focused on cloud (AWS), deployed in the cloud (AWS)
Opportunity to improve/fix/design development practices
Deliberately design our SDLC
Consistent with "devops best practices"
Continuous integration
Continuous deployment
Opportunity to build a platform for our future
A set of mandates...
5
6. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Our story: Cloud Insight mandates
Everything is an API
Everything is highly available
There is no web server
100% automated deployment in AWS, of 100% of the environment
Don't operate infrastructure
Minimize or eliminate configuration
Scale dynamically and manage resources on a per-customer basis
Pervasive AAA - ALL API calls are authenticated, authorized, and audited
Release small, testable, loosely-coupled components independently
Focused teams with long-term ownership of dev, test, and production
6
7. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Our story: generalizing our solution
We satisfied all our mandates
We learned a lot
This presentation is about generalizing from our solution:
A definition of microservices
A set of pillars or primitives necessary for such a microservices architecture to
function
7
9. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
What are microservices, anyway?
Poorly defined buzzword, but doesn't need to be
Useful paradigm if given a solid/meaningful definition
Evolution of Service Oriented Architecture (SOA), significant overlap
Still services, but now "micro"!
Defined by what we want from them: what problem are we solving?
If it looks like a duck...
Perhaps slightly better to define "microservices architecture"
No such thing as "one microservice"
9
10. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
What problem are we solving?
A good microservices architecture should:
Result in simpler components that can be better tested and understood
Allow development teams to work and release independently
Allow for good separation of concerns, data, and data access
Allow for independent scalability according to data needs and access patterns
Provide a mechanism for high availability
Reduce the "blast radius" for bugs and downtime
Allow for scalability of development resources
10
11. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Microservices Architecture: a definition
A collection of software components working together such that:
each manages a specific problem domain or set of data and access patterns
each service's data storage, if any, is opaque to all other services
each service instance is stateless; its state is persisted elsewhere
each service is independently tested and released
services are loosely coupled
services adhere to well-defined interfaces as contracts
services have the ability to locate each other
11
12. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
There be dragons...
Deployment/operational complexity
Where are all these things and what are they doing?
Something isn't working, now what?
Complexity of documentation / system understanding
Pace of changes
Complexity for consumer
Solve the "location" problem for them
Distribution transactions!
End-to-end testing complexity
12
14. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Pillars
I need to know where all the things are (and so do all the things)
I need to know if they are healthy
I need to be able to independently build services that react to state
changes in the system
I need to be able to release software quickly, frequently, and reliably
I need teams of developers to be able to iterate quickly and
independently
I need clear paths of communication to identify and coordinate
dependencies
14
15. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Pillars
Technology
Service discovery / registration
Publish-subscribe messaging
Stateless-ness
Documentation
API interfaces are contracts that cannot be broken
Testing
End-to-end integration testing in a dedicated environment
Integration testing gates release to production
15
16. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Pillars
Practices
Consistent monitoring interfaces provided by the services themselves
Developer ownership in production
Consistent build/package interfaces
Release automation
"Grab the chicken" - serialized, mutexed releases
Build/release system should use the consistent build/package interfaces
16
17. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Service discovery
Register service instances when they become available
Unregister instances when they become unavailable
Doing this well has bought us so much flexibility, especially around
devops and release practices
Because this is built in, machinery around it can just assume it works
Automated releases: stand up new ones, tear down old ones
Scaling events: just stand up new ones
Move from in-place rolling package upgrades to baked images from test -> prod
17
18. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Publish-subscribe messaging
For services to take independent action on changes in other services,
they need to know
All services publish their operations
Services that care about them can subscribe
Topics, queues + exchanges, etc.
Key component in facilitating loose coupling
18
19. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Stateless-ness
Service instances will come and go
Internal state of the service (not the instance) must be persisted
A new instance must begin its work from the persisted state
Multiple instances will need to coordinate while running
19
20. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Documented API contracts
Services depend on each other's interfaces
Releases cannot break interfaces
Deprecation is a coordinated process over time
20
21. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
End-to-end integration testing
End-to-end test is the only mechanism to verify the behavior of the
system as a whole
An end-to-end smoke test should gate release to production
21
22. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Consistent interfaces to monitoring
Built in to the services themselves
Part of service API
Consistent interface across all services
This is a developer problem, not an ops problem
22
23. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Developer ownership in production
Only developers can understand the problem
Only developers can analyze the problem
Only developers can fix the problem
Developers need to own their software in production
23
24. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
What works well for us
Consistent language and service boilerplate / scaffold
Polyglot is nice, but you need a consistent mechanism to manage and monitor
services and service instances (a distinction worth keeping in mind as well)
AWS
Software-defined infrastructure
APIs to scale up, down, etc.
Availability
Data services (DynamoDB in particular)
24
25. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
What works well for us
Erlang
We lean heavily on the primitives provided by OTP supervision
We have predictable behavior in error conditions and edge cases
Concurrency scale allows for simpler software
Zookeeper
Don't believe everything you read in blogs
Easy to abuse: it's not for storage
25
26. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Our Implementation
Services written in Erlang (for simplicity, functional style, concurrency, reliability, we
don't use Erlang clustering)
Services interact over HTTP using JSON, all APIs are public
All services publish operations to RabbitMQ exchanges
Each service is deployed on at least two AWS instances in at least two AWS
availability zones
Service discovery enables instances to find each other (proprietary, built on top of
zookeeper's basic coordination primitives)
Software-routing reverse proxy (using service discovery) at the edge (so we have one
point of contact for external clients)
All API calls are authenticated and authorized both internally and externally
26
27. Jeremey Barrett | Alert Logic | Making Microservices Work | @jeremey
Other Interesting Implementations
Pure Erlang
Great solution in many ways (global registration of components, well-defined reliable
communication, etc.)
Depends on Erlang clustering
At last check, not as great in a dynamic environment (nodes coming and going all day long)
More difficult to dedicate specific resources to specific applications or data sets
What happens if half your cluster falls off the earth all at once?
Pure AWS
API gateway + Lambda + SQS/SNS + S3/Dynamo
Complex to deploy, impossible to version / source control / etc.
Javascript or Python
27