microservices-pres



microservices-pres

0 0


microservices-pres


On Github AndrewSwerlick / microservices-pres

Microservices

The Easy way

Created by Andrew Swerlick / @thirdthoughts

Straight to what are microservices

What are Microservices?

  • Build systems of small composable parts
  • Interact through defined channels
1. Small systems of composable parts 2. Each app has its own database/deployment etc. 3. interact through defined channels

Why?

Ease of mainteance

Scalability

Autonomous Teams

1. Start with why Herrmann is interested a. Have a bunch of apps/potential apps with different purposes b. Didn't want all of this sharing a single hard to managment monolith c. Transition to general explanation 1. Ease of maintenance - Each app has it's own database and smaller codebase 2. Scalability, give example of order vs pricing, why its' harder to scale monoliths. Say it's not our primary concern 3. Teams can behave autonmously.

Microservices Concerns

  • Client Routing/Discovery
  • Common Client/Protool Concerns
  • Cross service communication
  • Deployment

    As you might expect it means setting up some infrastructure so that what is really a bunch of little apps still ensures an integrated user experience, and that everything plays nicely. In general there are 4 real concerns

Routing

How does a client get to the right service?
Api gateway takes client requests and ensure they go to the correct application. Generally it's a webserver, with some sort of logic to map a url to an application and then proxy the content

The hard way

Dedicated service discovery tools + webproxy
Consul, Zookeeper, etc.
In enterprise scenarios companies will use dedicated service discovery tools like consul and zookepper. Track multiple instances of the same server, do health checks, load balancing, etc. These tools are hooked into the webproxy through custom scripts, and the webrpoxy may even be load balanced itself

Benefits

  • Load Balancing
  • Complex routing scenarios

Drawbacks

  • Complex setup and maintenance

The easy way

Docker + nginx + nginx-proxy
Docker is containerization tech that can run multiple apps on a single server in an isolated fashion. Nginx is a webserver. Docker nginx is a program that runs in a docker container and builds dynamic config files for nginx based on running docker containers. Basically we build a template for docker-nginx that will generate our nginx config based on our running services.

Benefits

  • Easy setup
  • All pieces required for our infrastructure anyways

Drawbacks

  • Single server
  • Redeploy for each new service
This setup is easy to put together, since it's a just s series of docker containers and a single template for the dynamically generated configuration part. All the components were already a required part of our infrastructure, and don't require any additional apps or processes The main drawback is that you can't scale beyond a single server/single process per application, but that's a huge problem for us, because we're not at that scale.

Common Client Concerns

HTTPS

Authentication

Error Handling

The next thing we'll look at are some common client concerns. This is about how the client connects to a service, how errors are handled, etc 1. Some of these, like HTTPS and error handling are easy, just handle at the api gateway. There really isn't anything tricky or unique about our approach there 2. What about Auth though?

The hard way

OAuth
One approach I've seen alot of companies reccomend is OAuth. If you aren't familiar with OAuth, it's an authentication/delegation protocol used by companies like twitter and facebook. If you've ever signed into a third party web app using a "facebook", "twitter", or "google" login, you've used OAuth It delegates authentication to another service, which then may choose to share some data with the requesting app.

Benefits

  • Allows an "app" ecosystem

Drawbacks

  • Complex setup
  • Every app has to be oauth aware
  • Every app has to know how to find the auth service
  • Lots more cross service chatter
This setup is easy to put together, since it's a just s series of docker containers and a single template for the dynamically generated configuration part. All the components were already a required part of our infrastructure, and don't require any additional apps or processes The main drawback is that you can't scale beyond a single server/single process per application, but that's a huge problem for us, because we're not at that scale.

The easy way

Signed cookies generated by the gateway
We go with a very different approach. Instead, all of our auth logic lives at the api gateway. No auth in individual applications, just get user data in custom http headers 1. On login we proxy credential request to an auth service 2. Auth service checks credentials and if good generates a simple json token 3. This json token is cryptographically signed with a secret key and then sent to the client in the form of a cookie, or just a string. 4. The token is included for subsequent requests, the gateway decrypts the token. 5. If decryption is successfully, the gateway adds token data to http headers 6. If it fails, we give the user a 401.

Benefits

  • We only hit the database on login, not on later requests
  • Apps implement no auth logic. Devs don't have to worry about it.

Drawbacks

  • Any mobile apps have to be spefically written to store and manage the token
This setup is easy to put together, since it's a just s series of docker containers and a single template for the dynamically generated configuration part. All the components were already a required part of our infrastructure, and don't require any additional apps or processes The main drawback is that you can't scale beyond a single server/single process per application, but that's a huge problem for us, because we're not at that scale.

Cross Service Communication

How do services talk and share data?

Next we're going to look at cross service communication, how do services talk a share data?

The ugly way

Synchronous request/response
We're going to break format here, and before I talk about the hard way, I'm going to talk about the ugly way. This is a really common approach that's got alot of flaws, and should really be avoided because of it's problems. That's synchronous request/response usually over http. This is where service A sends Service B request on http, and then service B sends back data Problems 1. Really tight coupling. Failure of 1 = failure of all Ex: Price management and ordering system. 2. Hard to trace where requests go, and which systems are hit 3. Hard to scale, since every service might be involved in every request

Async

Data duplication over events

No coupling

Better traceability

Better scalability

If no sync, then what. After all that ordering application still needs the price data It helps to think about how we handled this sort of stuff before computers CSR taking orders over the phone. Wouldn't call up the sales person and ask the price of every product while they're taking. Instead each CSR would have a list. If the price changes, somebody distributes a new list. The CSR has everything he or she needs to <!DOCTYPE html> their job, without having to request data from anyone else. We can use the same model, and in fact it has a very computery sounding name. Data duplication over events. In this model, everytime someone updates a price in the price management system, we publish an event with data about the change. The online store listens for these events and uses the data to update it's own cache of product prices. This solves all the problems we outlined with synchronous communication. How does this work? We'll talk about the hard way and then the easy way

The hard way

Dedicated event bus/messaging system

Kafka

Rabbit MQ

Zero MQ

Etc.

Dedicated system that only does event management/pub sub.

Benefits

  • Fault tolerant
  • Optimized for high loads

Drawbacks

  • Another system to support and maintain
  • Dual Writes

The easy way

Database based message system
What this means is that we have our pub sub messaging system built directly into a shared database

QueBus

Built on top of background job library

Add a subscribers table

Publishing application loops through subscribers and queues up jobs

We built a custom pub sub system that uses the database directly called QueBus It may sound like alot, but it's mostly but on top of an existing background job library explain background jobs So on top of this background job library, we add a table of subscribers Stores who is listening for what kind of events. So when the price management app goes to publish a price changed event it looks at the subscribers table, sees a row in there for the online store and then queues up a background job for the online store. The online store grabs this background job, and processes it, adding the price change data to it's own database Most of the heavy lifiting is this existing background job library

Benefits

  • No new system, built into existing database
  • No dual writes

Drawbacks

  • All apps share a database (mitigated by postgres schema)
  • Logic for using the subscribers and jobs tables must be implemented in every app
This setup is easy to put together, since it's a just s series of docker containers and a single template for the dynamically generated configuration part. All the components were already a required part of our infrastructure, and don't require any additional apps or processes The main drawback is that you can't scale beyond a single server/single process per application, but that's a huge problem for us, because we're not at that scale.

Deployment

Autonomous teams = Automated deploys

Deploy on checkin

Isolated apps

How does your code get into production. Remember one of the original goals was autonomous teams. Autonomous teams need to be apply to deploy on their own schedule, and without depending on other teams. That means automated deployment Generally this means you build a Heroku like setup. If you aren't familar with Heroku, the way you deploy code is by checking your latest code into a specific git repository. From their an automated process takes over and publishes the code you checkin Different branches or repositories are used for different environments

The hard way

Dedicated Build server

Team City

Jenkins

Standalone server/app for builds and deployments

The easy way

Cloud build services

Codeship

Drone.io

Travis CI

In this case, the hard way and the easy way aren't too different. It's mostly the same process just one uses the cloud versus setting up and configuring a dedicated system. The cloud might cost a little more, but it gives you convinence and ease of setup.

Summary

  • Small applications that talk asynchronously

  • Automated deployments tied to source control

  • Easy to add new features via seperate apps

  • Easy to experiment with different approachs from app to app

  • Single server, but ready to scale with minimal app changes

  • Single database but ready to scale with minimal app changes

THE END

Microservices The Easy way Created by Andrew Swerlick / @thirdthoughts Straight to what are microservices