Microservices Vs The Monolith

Fact and Fiction

Who am I

  • My name is Jedediah Smith
  • I love JavaScript, working with data, and organizing chaos.
  • I enjoy teaching, training, mentoring, and otherwise helping others with their code.
  • I work for CurbNTurf Inc.

 

 

  • Twitter: @jedsmith13
  • LinkedIn: https://www.linkedin.com/in/jedediahsmith

Puzzles

  • How long does it take to finish a jigsaw puzzle?
  • There are many different factors.
    • Colors
    • Piece shape
    • Overall puzzle shape
    • Piece count

Image By Psyon CC BY-SA 3.0

Puzzles - Piece Count

  • How much is time to completion affected
    by piece count?
    • It is generally estimated as being O(N^2)
    • The reason being that each time you try matching
      a piece you have to compare it with every other
      piece.

 

Puzzles - O(N^2)

const puzzleArray = ourPuzzle.toArray();

puzzleArray.forEach(pieceA => {
  puzzleArray.forEach(pieceB => {
    if (pieceA.canConnectTo(pieceB)) {
      pieceA.connect(pieceB);
    }
  });
});

​

 

Puzzles - Completion Times

  • So lets set our base at 500 pieces and if it takes 3 hours 20 minutes* then we get the following
    • 100 = 8 minutes (0.133 hours)
    • 200 = 32 minutes (0.533 hours)
    • 500 = 200 minutes (3.33 hours)
    • 1000 = 800 minutes (13.33 hours)

 




*Measured time

1000 Piece Puzzle

Puzzles - Optimizing

  • Based off of the chart
    • 100 = 8 min
    • 200 = 32 min
    • 500 = 200 min
    • 1000 = 800 min
  • We can see that building 1000 piece puzzles isn't effective (unless by chance you are building the puzzles for entertainment purposes instead of necessity)
  • So if we took the 1000 piece puzzle and broke it into 10x100 piece puzzles it should take 80 instead of 800 minutes.

Puzzles - Over Optimizing

  • Better yet why not do 100x10 or 1000x1 piece puzzles?
    • First off, assuming the same image we would
      need to connect the 100(1000) puzzles together essentially creating an additional puzzle (the 1000x1 is really still just the 1000 piece puzzle from before hidden behind a new name).
    • Still 10 piece puzzles should be under a minute each and then the new 100 puzzle to put them all together should only be 8 minutes so well under 20 minutes for the 100x10.

3 x 33ish

Puzzles - what we are missing

  • The real reason we don't go to 100x10 is simple.
    • Our whole premise to this point is based strictly on theory
      • Timing myself on a 100 piece puzzle it takes me 16 not 8 minutes.
      • Completing a puzzle doesn't actually follow a simple mathematical equation.
      • Remember Big-O just gives you a general idea so don't use it alone when calculating completion time.

5x100 Piece Puzzle

Puzzles - Other Factors

  • Yes, there are other factors
    • Partially complete puzzles have a reduced testing time for each test and need fewer tests.
    • The longer we are working on something the more we "get in the groove"
    • Opening the box, dumping out the pieces, searching on the floor for lost pieces, and similar steps takes the same amount of time.

Puzzles - Possible Best Case

  • Even though 16 minutes for a 100 piece puzzle is slower then the 8 we calculated it is still far better then 3 hours and 20 minutes.
  • So if I wanted to complete 500 pieces of puzzle it would be better if I could assemble 5x100 piece puzzles then assembled them.
  • Even if we were to allow 10 minutes to assemble the 5 puzzles after completing, which seems ridiculous it is still only.
    • 5 X 16 minutes + 10 minutes = 90 minutes
    • Still less than half the time.

Back to the real world

  • Puzzles are fun but what does that have to do with writing code?

Code and Puzzles

  • When you assemble a puzzle you are organizing a bunch of disconnected elements on the table.
  • When editing code you have to organize a bunch of processes, objects, properties, behaviors, etc... in your head so you can start logically working through your problems.

​and

  • When you make an application you take a bunch of smaller pieces (functions, variables, and operators) and put them together in a meaningful and productive way.

The "Monolith"

According to Wikipedia:

A monolith is a geological feature consisting of a single massive stone or rock, such as some mountains, or a single large piece of rock placed as, or within, a monument or building.

-https://en.wikipedia.org/wiki/Monolith

For developers, the term references a single large codebase that runs as a single application. Or we could say a "mountain of code".

Figuring Out Existing Code

I have been thrown into the middle of some fairly complex code to try and fix a problem. This leads to two different outcomes.

You spend a lot of time trying to figure out what everything does and try and understand each process and how it all fits together and hope eventually you will find your way through the code.

You go in and start changing code that looks promising then hope for the best.

The "Shortcut"

  • So if you take the shortcut route and change the first code you find that might be related you can be successful some of the time.
  • And some time you are wrong and so you put it back and try again.
  • But what about when you make a change that seems to fix the problem but next week when the code is pushed your customers can't do something that is seemingly unrelated?
  • Well hopefully your boss is patient and will give you a second chance, after explaining the importance of not breaking the site and having you spend more time reading the code.

Figuring it "ALL" out

  • The other option is to spend countless hours learning how each piece of code ties to the other pieces.
  • This can be very time consuming and even the most thorough attempt can miss vital points.
  • Remember this isn't like a simple 1,000 piece puzzle that takes 10 to 14 hours. No this is a puzzle with 100,000 or 1,000,000 or more lines of code. This puzzle can also connect lines to thousands of other places instead of just on four sides.
  • There are lots of tricks to help organize your code, OOP, functional programming, separate files, modules, etc... but in the end your code is still all run from a single place.

Microservices

  • What are Microservices
  • According to Wikipedia 

Microservices is a specialisation of an implementation approach for service-oriented architectures (SOA) used to build flexible, independently deployable software systems.

 

- https://en.wikipedia.org/wiki/Microservices

Which Means?

  • The idea behind microservices is that you build separate applications for each service.
  • Examples:
    • Sending emails
    • Processing images
    • Creating and editing entities
    • Getting stock prices
    • Your e-commerce catalog
    • Your e-commerce shopping cart
    • Handling payments
    • Building puzzles

Other Key Features

  • Each application in a microservice should be able to be deployed by itself.
  • They can and often will communicate with each other. However, they should have a well defined API that they present to the other services.
  • Each service can be written in any language and can use whatever database works best for it.
  • Often lends itself to continuous delivery as each service can be tested and deployed independently without impacting other services. (Except when the API changes)

Benefits

  • Each microservice is much simpler then the monolith.
  • They each have a smaller code base.
  • We can learn how the single application works much quicker and are more likely to really understand how it works.
  • It makes dividing responsibilities between teams much easier.
  • Individual microservices can scale on there own instead of scaling the entire system as a unit.
  • Allows the use of multiple technologies.
  • Adopting new technologies is easier as they can be brought into whichever microservice makes sense.

Don't Over Optimize

  • In microservices the cost of connecting each service to other services will be larger then internal connections.
  • In our 1000x1 example connecting the 1000 together is essentially the same as a single 1000 piece puzzle.
  • With microservices there is some added overhead of connecting them together so it might end up being more like a 1500 piece puzzle.
  • It is generally better to error on fewer larger microservice than to have too many smaller services.

Migrating from a Monolith

  • Analyze the services your application provides. You should create your microservices based off discrete services.
    • To assemble a puzzle the fastest I prefer to start out by sorting the pieces by discernable object or color.
  • Start simple, maybe only pull-out a single service or split the application in two, separating on service boundaries.
  • When migrating take your time. You will have to build up your infrastructure to handle multiple services so you don't want to overwhelm it.

Simple Example

We were working with a stock analyst application.

 

Here is an example of the steps used:

  1. Import the data
  2. Clean data
  3. Format data
  4. First analysis
  5. Second analysis
  6. Validating
  7. Formatting
  8. Storing

Simple Example - Continued

  • First problem, the code was difficult to figure out as it was all jumbled together.
  • Second, decreasing time to completion was an issue as each staging had different bottlenecks. We couldn't just throw more hardware at it.
  • Third, it needed to scale to more stocks, and some of the data (especially from the importing and cleaning stages) could be reused or at least done together.

Simple Example - Continued

In this case each step became its own microservice.

  1. Import the data
  2. Clean data
  3. Format data
  4. First analysis
  5. Second analysis
  6. Validating
  7. Formatting
  8. Storing

Simple Example - Continued

  • First, we had to separate the functionality. This wasn't too bad as we had tried to make it as modular as possible.
  • Second, we had to develop a way to orchestrate how and when each step is run so that each can scale independently and so we can maximize our efficiency.
    • To make this happen we built a master controller (think TRON) that would handle the distribution of tasks and data.
  • The master controller added some complexity to the overall process but allows for scaling each step as needed and we could then process more stocks. It is also much easier for someone to work on each step as they are clearly isolated.

Building From the Ground Up

  • Microservices forces modularization
  • Requires a more thorough initial plan to determine how each microservice will communicate
  • Conversly once inter-service communication is established the individual microservices need less planning from the central authority.
  • Individual microservice planning can be pushed off to the team.
  • It is easier to divide work between teams
  • Encourages using better practices to take advantage of continuous integration

Teaming Up on Microservices

Each microservice should be assigned to a team or individual. This has a lot of advantages over everyone being responsible for the entire program.

The advantages normally fall into one of these two reasons.

  • Less cognitive overhead
  • Simplifies chain of responsibility

Two ways

When building a web application there are two fundamental ways to approach microservices.

 

  1. Creating a router
  2. Individual points of entry

Creating a Router

The router method is where you use a microservice to handle all of the communications coming in.

  • This allows for simple consolidation of user authentication.
  • Allows for a single end point.
  • Reduces the need for the other microservices to know how the request comes in.
  • Creates a single point for tracking.

Individual Points of Entry

This approach has each microservice that provides services directly to the front-end provide their own endpoints.

  • No one point of failure
  • It can allow for greater performance
  • Each service has to handle things like user authentication

What about the real world?

So should I use microservices on my next project?

 

YES!

Or maybe?

You can use both

Just because you use have a monolith doesn't mean you can't have some microservices.

Pseudo-Microservices

One area you should look into is 3rd party APIs.

  • Basically microservices with reduced maintenance
    • Authentication
    • Image processing
    • Video hosting
    • Payment processing
    • Chart generation
    • Maps, geocoding, point of interest lookup
    • User validation
    • etc...

CurbNTurf

A real world example.

AirBnB for RVers

Users: Landowners and RVers

Offering: Website(curbnturf.com), Apple & Google Apps

Team Size: 3 (2 devs and 1 UI/UX)

Technologies: Postgres, NodeJS, Angular, Ionic

Hosting: AWS, ElasticBeanstalk, S3, CloudFlare, Lambda

3rd Party Services: HereMaps, AWS Cognito(auth), Converge (Credit Card processing)

Microservice: Search, Location lookup, Photo processing, Payment Gateway Facade

Microservices using NodeJS

By Jedediah Smith

Microservices using NodeJS

An introduction into the fundamentals of microservices with a NodeJS example.

  • 1,315