The 10 Puzzle Pieces of an Effective Microservice Architecture

10,157 reads

@ patrickleet Patrick Lee Scott Read my story at https://patscott.io/

Anyone can make a tiny service. It’s the first thing you do when you make your “Hello World” express server. If you’ve made a “Hello World” express server before, then congratulations! You’ve made a microservice 😜!

reactions

It’s going from one to many that the questions start piling up.

reactions

How should they talk to each other? REST? RPC? Messaging? And why choose one over another?

reactions

Let’s say that you do manage to wire up a small system of a few services and you chose REST cause it seemed easiest, and you already knew it. Time to deploy them somewhere. If you’ve tried running microservices on a Platform as a Service (PaaS) like Modulus, or Heroku, this can get pretty time consuming, and pretty expensive.

reactions

Not to mention latency from communicating over the internet instead of a private network. That’s a no go. Oh, and you’ll need to provide environment variables so you’ll know what endpoint to ping.

reactions

Then you think about deployments. Deployments are always a pain, and now you need to do it seven times?!

reactions

The above scenario is basically what my first attempt looked like. I was clever though, I used a unidirectional data flow! Too bad that’s only one of the pieces.

reactions

What about logging? And monitoring? Where do you store secrets? Auto-scaling?

reactions

You finally realize that you now, on top of just wanting to make tiny services, need to go learn how to build your own infrastructure in AWS.

reactions

Suddenly, our tiny services don’t feel so tiny.

The following tools when combined have the potential to greatly increase the speed in which you develop services, the speed in which you deploy them, and the ease of running them in any environment. As a bonus, once they’ve been codified, they are quite reusable.

reactions

It’s more tracking down resources and learning each, as well as how they interface that makes up the majority of the learning curve.

reactions

10 Puzzle Pieces of an Effective Microservice Architecture

1. Containerization

You can’t effectively build microservices without containerization. There are just too many pieces. I mean, you can, but it’s seriously going to be way more work.

reactions

Imagine if you wanted to buy some Oreo’s and they came separately. It would be, well, less convenient to say the least.

reactions

When it comes to services, containers simplify development, testing, deployments, and running in production. All the things you need to do all day every day as your job, so might as well make it easier.

reactions

Services need containers, just like Oreos.

Tools: Docker

reactions

2. A cluster

But you didn’t want just Oreos, did you? You also wanted to make grilled cheese and Tomato Soup, because it is frigid outside. And maybe some deodorant and toothpaste so you aren’t a smelly unsociable human, so you got that too. And of course, beer.

reactions

Imagine if you had to carry all of your groceries home individually. It doesn’t make sense. So, you put them in bags. You put heavy ones on the bottom, so they don’t squish the bread, and cold ones (for the bros) with other cold stuff so they can all be cold together. Some stuff you double bag, for redundancy.

reactions

Bags are like servers, you need more than one, and they hold your services.

Having more than one allows you to avoid failure scenarios, like if an availability zone went down. Or, your soup can broke and the paper bag ripped. Good thing you double bagged it! Give yourself a clap. You can use the button on the bottom. ;)

reactions

You can get your servers at any of the major cloud providers. The important thing here is codifying that infrastructure. There are a few different ways to do this. In the past many people used Ansible for this, but given the requirements of fast scalability, it doesn’t make sense to have to wait for a server to be brought up, and provisioned. Instead you can “bake” an image of the machine with all of the tooling installed, and then use that image with Terraform or Cloudformation. Once you’ve designed your cluster for resiliency, a rolling update of a new AMI will allow you to update your entire infrastructure.

reactions

Servers: AWS, Azure, Digital Ocean

Tools: Cloudformation, Terraform, Packer

reactions

3. An Orchestrator

Now, you are pretty good at bagging stuff, but, you live in New York, and you paid $82 for these grilled cheese ingredients and beer, and now you’re gonna put them in a bag yourself? Forget about it! You’re already saving money by cooking at home! There is a bagger whom bags stuff non-stop all day every day, and they’re like, really good at it!

reactions

An orchestrator is like the grocery bagger.

The orchestrator knows the memory requirements of your services, and how much CPU needs to be allocated, and she carefully places each service into the appropriate server.

reactions

Tools: Docker Swarm, Kubernetes

reactions

4. Continuous Deployment

I don’t think I can take this grocery thing any further. Something about UberEats? I don’t know. Comment with your ideas if you have some! Let’s just get the brass tax. Deployments are time consuming, and you have better things to be doing.

reactions

Automate it, automate it, automate it.

This directly contributes to the business making money. The whole Lean Startup is about build, measure, learn, and repeating that cycle. Continuous Deployment allows you to do this faster. The faster you can get things out the better, because then you can measure, and learn, and know what to build next.

reactions

I personally think you should strive to automate everything to a point where you can confidently commit to master. Git flow is too cumbersome when repeated 15 times across a bunch of tiny services. Make branches when you need, but, it’s ok to just commit to master if you have the proper safety checks in place.

reactions

Tools: Jenkins (With pipeline and Blue Ocean), TravisCI, CircleCI

reactions

5. Proxy

Your services should be secure. A great way to secure them?

reactions

Don’t expose your services directly to the internet!

Instead, use a public facing reverse proxy. However, it needs to be one that is easily configurable, ideally, one that configures itself based on some configuration options defined on the service, so the team developing the service can decide best how to interface with the proxy without having to ssh into servers.

reactions

Tools: HAProxy, nginx, docker-flow-proxy

reactions

6. Message Queue

Services should communicate in a universal language. A Message Queue can be used as the glue that sends messages to all subscribed clients. Also, it should not be the responsibility of a service to know where on the internet you other services are running. If they move, then you’d need to know about it.

reactions

Sure, you could use a distributed key store like Consul and keep it up to date to avoid having to constantly reconfigure your service, or better still use an orchestrator’s DNS features and use REST, but, that’s still a lot of extra responsibility and configuration. This makes your services tightly coupled.

reactions

Use one-way fire and forget messages to make your services loosely coupled, and easy to scale.

Instead, using a message queue, you can simply send or publish messages, in a “fire and forget” manner. Other services can easily be added or removed without affecting the original publishing service. This makes your architecture very easily scalable as well. Also, with features like retries, and error queues, you can stress less about services crashing. The message will simply be retried when the service comes back up.

reactions

Tools: RabbitMQ, ActiveMQ, AWSMQ, ZeroMQ, Kafka

reactions

7. Centralized Logging

With messages happening from across many nodes and many replicas, potentially being moved around by the orchestrator, it’s not a viable option to ssh into a server and check the logs. You need to ship them to a centralized location where they can easily be searched, and drive insights into how code is functionally in production.

reactions

See everything in one place.

Furthermore, it should not be the responsibility of a service to know how to ship logs. Instead, always log to stdout or stderr and use a tool to collect all of those logs by running it globally on each node in your cluster. The log collector tools will then ship the logs to your Centralized Logging subsystem.

reactions

Tools: ELK Stack (ElasticSearch, Logstash, Kibana)

reactions

8. Monitoring and Alerting

Similarly to logging, you don’t want to be chasing services around to see what their usage statistics are. Instead, the should all be collected and shipped to a centralized location.

reactions

Use alerting to drive scaling or recovery events before alerting humans.

You also don’t want to be chasing down that information if you don’t have to be. Ideally, you should only ever hear a peep when something is wrong. This means you need an alerting tool that can respond to the metrics collected from monitoring and alert a user. Better yet, it can alert a microservice to trigger a scaling event, or attempt to resolve the issue in other ways to avoid requiring human interaction.

reactions

Tools: Prometheus, Alertmanager, Grafana

reactions

9. A meta repository

Most people have only heard of monorepos, or multi-repos, both of which fulfill certain requirements. However, with microservices, you tend to have a lot of repositories, which can get to be a lot to handle. Using a meta-repository solves this issue by creating a parent repository and a command line tool to execute commands across many repositories at once. To learn more about meta repos, check out my article: Mono-repo or multi-repo? Why choose one, when you can have both?

reactions

Tools: meta, gitslave

reactions

10. A Microservices Mindset

An architect’s job is not done when the infrastructure is built. For the architecture to achieve it’s benefits, the team needs to embrace microservices. All of the tooling in the architecture’s goal is to remain flexible by supporting any language that is best for the job, due to the loose coupling of the message bus, and containerization. If your team just goes and builds monoliths and calls them microservices, it’s not going to work. Therefore, they need to be educated about microservice design patterns and benefits, so they can approach building with confidence, and less experimentation.

reactions

For more details on Microservice Patterns, see my other article “Learning these 5 microservice patterns will make you a better engineer”. Where I teach you how to categorize your services, and talk about the overarching patterns, and how they relate to Domain Driven Design, CQRS, and Event Sourcing.

reactions

Conclusion

My goal has been to give you a high level overview of the components of a microservice architecture. Being an architect is a difficult journey with a lot of tools to learn, however, leveraging the power of the architecture as a whole will give you development superpowers!

reactions

I’m currently developing a new course "Microservice Driven Design", where you can learn how to build a modern microservices architecture using all of the above components. To be the first to access, sign up here!

reactions

Interested in hearing MY DevOps Journey, WITHOUT useless AWS Certifications? Read it now on HackerNoon! DevOps is a prerequisite to effective microservices!

reactions

Thanks for reading! If you found this useful, please give it a share!

reactions

Want to learn more about me and my story? Click here to read about me and how my agency, Unbounded, can help you turn your product into a money-making system.

reactions

Image licensed by Adobe Stock Photos, by adimas.

reactions

Image 2 licensed by Adobe Stock Photos, By nespix.

reactions

reactions

Tags