Building Microservices: Designing Fine-Grained Systems

Author: Sam Newman
4.3
This Year Stack Overflow 3
This Month Stack Overflow 2

Comments

by key_lime_pie   2019-07-21

Just in general, or on a specific topic?

Books I'm reading right now:

  • Building Microservices: Designing Fine-Grained Systems
  • The Outer Limits of Reason: What Science, Mathematics, and Logic Cannot Tell Us
  • Loose Balls: The Short, Wild Life of the American Basketball Association by Terry Pluto (Halfway through, this book is fucking hilarious)
  • The United States Football League, 1982-1986 (I do not recommend this book... "The $1 League" by Jim Byrne is much better if you can find it)
  • Football Scouting Methods
  • Square Foot Gardening
by PedroMutter   2019-07-21

Thanks for your advice. The O'reilly book you mentioned is this one? (Building-Microservices-Sam-Newman). And could you send me some material that you like please? (blog posts included).

by anonymous   2019-07-21

I stick with Sam Newman who says in Chapter 4 "The shared Database" of his book something like:

Remember when we talked about the core principles behind good microservices? Strong cohesion and loose coupling --with database integration, we lose both things. Database integration makes it very easy for services to share data, but does nothing about sharing behaviour. Our internal representation is exposed over the wire to our consumers, and it can be very difficult to avoid making breaking changes, wich inevitably leads to fear of any changes at all. Avoid at (nearly) all costs.

This is the point I make when I curse at Content-Management-Systems.

In my view a microservice is autonomous, what it cannot be if it shares things or consumes shared things. The only exception I make here are Domain-Objects, those represent the shared understanding of the business model and must be used in communication between microservices solely.

It depends on the microservice itself if an ER or AggregationOriented database (divided into document based or graph based) better suits the needs. The funny thing is, by being loosley coupled and by being autonomus you are able to do just that!

If an PaymentService shares the behaviour of "how many payments for Person A" He needs to know Person A in order to fullfill this. But Everything he knows about Person A must origin from the PersonService, maybe at runtime (the PaymentService maybe just stores an id) or event based (the PaymentService stores the data it needs up to the Domain-Object user, what gets updated triggered and supplied by the PersonService). The PaymentService itself does not share users itself.

by anonymous   2019-07-21

I would't worry too much about the latency, as all the calls would be asynchronous.

Microservices are all about the options, selective: scalability, robustness/antifragility, deployment, etc. You cannot make the whole system robust but you can make some of it (the important bits).

I would focus on modelling of domain models/boundary contexts, try to get Single Responsibility Principle right, that would hopefully help you to avoid functionality replication, Death Star dependencies.

Very basic µService Architecture

Reading:

Building Microservices

Domain-Driven Design: Tackling Complexity in the Heart of Software

by freedomben   2019-07-12
If you want to learn "the right way" I highly recommend "Building Microservices: Designing Fine-Grained Systems" by Sam Newman[1]

[1] https://smile.amazon.com/Building-Microservices-Designing-Fi...

by karolist   2019-07-12
I'll structure this in "current/future/recent_past" format if I may.

Currently:

* The Go Programming Language

https://www.amazon.com/Programming-Language-Addison-Wesley-P...

* Building Microservices

https://www.amazon.com/Building-Microservices-Designing-Fine...

Plan to do next:

* Designing Data-Intensive Applications

https://www.amazon.com/Designing-Data-Intensive-Applications...

* Designing Distributed Systems

https://www.amazon.com/Designing-Distributed-Systems-Pattern...

* Unix and Linux System Administration 5th ed, but probably just gonna skip/read chapters of interest, i.e. I wanna get a better understanding of SystemD.

https://www.amazon.com/UNIX-Linux-System-Administration-Hand...

Read last month:

* Learning React

Good for a quick intro but I probably wouldn't read cover-to-cover again, some sections are old, but overall an OK book.

https://www.amazon.com/Learning-React-Functional-Development...

* React Design Patterns and Best Practices

Really liked this one, picked a tonne of new ideas and approaches that are hard to find otherwise for a newbie in JS scene. These two books, some time spent reading up on webpack and lots of github/practice code made me not scared of JS anymore and not feeling the fatigue. I mean, I was one of the people who dismissed everything frontend related, big node_modules, electron, complicated build systems etc. But now I sort of understand why and am on the different side of the fence.

https://www.amazon.com/React-Design-Patterns-Best-Practices/...

* Flexbox in CSS

Wanted to understand what's the new flexbox layout is about since it's been a while when I've done some serious CSS work. Long story short I made it about half of this and dropped it - not any more useful than MDN docs and actually playing with someone's codepen gave me better understanding in 5 minutes than 3 hours spent with this book.

https://www.amazon.com/Flexbox-CSS-Estelle-Weyl-ebook/dp/B07...

by mrburton   2019-07-12
1. Building Evolutionary Architectures - A great book for those looking to build an IT department that can meet the business needs of today and create an organizational mindset that allows you to still be nimble and evolve to meet future demands.

https://www.amazon.com/Building-Evolutionary-Architectures-S...

2. Building Microservices - A great book by Sam Newman which Building Evolutionary Architectures is effectively written upon IMHO. This book is really more technical and gets into the weeds of building out systems using microservices and it also touches based on CI/CD.

https://www.amazon.com/Building-Microservices-Designing-Fine...

3. Inside the Minds - Although this book is old and talks about XML as an emerging technology, it's exceptional in showing you how various CTOs think and define their roles in different companies. It really drives home the importance of having IT support business vs. just building out technical solutions.

Note: Buy this book used and save yourself a lot of money. I got it for $2.58.

https://www.amazon.com/Inside-Minds-Technology-Officers-Peop...

4. Release It! - A very good book that talks about important concepts in building systems that can be released often. It talks about things like Bulkheads, and circuit breakers; also mentioned in Sam Newmans book,. If you're company doesn't have CI/CD in place and a proper release model, then you should certainly read this book.

https://www.amazon.com/gp/product/1680502395

I have more books, but I don't want to flood this post.

by anonymous   2019-01-13

There are at least three ways that I can think of to solve this problem.

  1. Document Model NoSQL DB: Instead of using a SQL DB, consider using a document model NoSQL DB like Mongo DB. So instead of a relational DB with the tables like Books and Authors and an AuthorBooks table that are all joined on a pair of foreign keys - you can use a document NoSQL DB like Mongo where your books are stored as document type, in a BSON format that looks almost identical to the JSON in your question. A nice feature of document DBs like Mongo is that you can set up an index on JSON inside the Book document on Author, thus improving your query time. This is discussed quite well in NoSQL Distilled by Martin Fowler (Sec. 2.2 and Chp. 9).
  2. Break the foreign key relationship so that referential integrity is maintained by the service instead of the DB: Instead of relying on the relational DB to enforce referential integrity for you (via the maintenance of foreign keys) restrict access of the DB to just your microservice and maintain the integrity of foreign keys by your service itself. This tactic is discussed by Sam Newman in Building Microservices on pp. 84-85.
  3. Denormalize the DB: Instead of having two tables each for books and authors, just combine them into a denormalized table. So, create a new table where the info for your books is duplicated and author info is unique to each book per row. It's ugly. Searches now have a larger search space, but it's simple too. For example, something like the following format:

    book_id | book_name              | book_author
    =====================================================
          1 | NoSQL Distilled        | Pramod J. Sadalage
    -----------------------------------------------------
          1 | NoSQL Distilled        | Martin Fowler
    -----------------------------------------------------
          2 | Building Microservices | Sam Newman
by anonymous   2019-01-13

This does not really qualify as a microservice architecture.

The whole code you provided is small enough to be considered one single microservice (containing two routes), but this is not an example of a microservice architecture.

According to this definition;

"Microservices are small, autonomous services that work together"
Building Microservices <-- tip: you should read this book

Both service1 and service2 to be considered a microservice should be autonomous, what is not happening when you place them together in the same express app. For example; you cant restart one without not-affecting the other. You cant upgrade version of service1 without also having to deploy service2. They are not distributed in the sense that they can leave in separate machines.

by anonymous   2018-03-19

You should not go with DRY in microservices. Think about one of the advantages of using them: you can replace one microservice with other stack at any time (PHP + Apache) and the system would not care, as long as it respects the contract.

You can read more here, page 59, DRY and the Perils of Code Reuse in Microservices World.

by anonymous   2018-03-19

Is it possible to have multiple versions of service(s) deployed in production at the same time

Yes, it is possible. The idea is to keep all used microservices in production (v1, v2 ...) at the same time and to bring down the versions that are not used anymore. For this, you should somehow know when a version is not used anymore.

AFAIK, you have to options:

  1. For every new version you make a new endpoint (like /v2/someApiCall) that is connected to the same (now upgraded) microservice and gradually instruct clients to use the new endpoind; when the old endpoint is not used anymore you deleted it; this is the preferred way.

  2. For every new version you make a new microservice that share the same persistence with the old microservice; you should avoid the use of this solution; Netflix uses this strategy in rare occasions when the cost of changing old consumers is too high.

You can read more at page 62 from Building microservices by Sam Newman.

by anonymous   2017-08-20

The Book Building Microservices describes in detail the styles mentioned by @RogerAlsing in his answer.

On page 43 under Orchestration vs Choreography the book says:

As we start to model more and more complex logic, we have to deal with the problem of managing business processes that stretch across the boundary of individual services. And with microservices, we’ll hit this limit sooner than usual. [...] When it comes to actually implementing this flow, there are two styles of architecture we could follow. With orchestration, we rely on a central brain to guide and drive the process, much like the conductor in an orchestra. With choreography, we inform each part of the system of its job, and let it work out the details, like dancers all find‐ ing their way and reacting to others around them in a ballet.

The book then proceeds to explain the two styles. The orchestration style corresponds more to the SOA idea of orchestration/task services, whereas the choreography style corresponds to the dumb pipes and smart endpoints mentioned in Martin Fowler's article.

Orchestration Style

Under this style, the book above mentions:

Let’s think about what an orchestration solution would look like for this flow. Here, probably the simplest thing to do would be to have our customer service act as the central brain. On creation, it talks to the loyalty points bank, email service, and postal service [...], through a series of request/response calls. The customer service itself can then track where a customer is in this process. It can check to see if the customer’s account has been set up, or the email sent, or the post delivered. We get to take the flowchart [...] and model it directly into code. We could even use tooling that implements this for us, perhaps using an appropriate rules engine. Commercial tools exist for this very purpose in the form of business process modeling software. Assuming we use synchronous request/response, we could even know if each stage has worked [...] The downside to this orchestration approach is that the customer service can become too much of a central governing authority. It can become the hub in the middle of a web, and a central point where logic starts to live. I have seen this approach result in a small number of smart “god” services telling anemic CRUD-based services what to do.

Note: I suppose that when the author mentions tooling he's referring to something like BPM (e.g. Activity, Apache ODE). As a matter of fact the Workflow Patterns Website has an awesome set of patterns to do this kind of orchestration and it also offers evaluation details of different vendor tools that help to implement it this way. I don't think the author implies one is required to use one of these tools to implement this style of integration though, other lightweight orchestration frameworks could be used e.g. Spring Integration, Apache Camel or Mule ESB

However, other books I've read on the topic of Microservices and in general the majority of articles I've found in the web seem to disfavor this approach of orchestration and instead suggest using the next one.

Choreography Style

Under choreography style the author says:

With a choreographed approach, we could instead just have the customer service emit an event in an asynchronous manner, saying Customer created. The email service, postal service, and loyalty points bank then just subscribe to these events and react accordingly [...] This approach is significantly more decoupled. If some other service needed to reach to the creation of a customer, it just needs to subscribe to the events and do its job when needed. The downside is that the explicit view of the business process we see in [the workflow] is now only implicitly reflected in our system [...] This means additional work is needed to ensure that you can monitor and track that the right things have happened. For example, would you know if the loyalty points bank had a bug and for some reason didn’t set up the correct account? One approach I like for dealing with this is to build a monitoring system that explicitly matches the view of the business process in [the workflow], but then tracks what each of the services does as independent entities, letting you see odd exceptions mapped onto the more explicit process flow. The [flowchart] [...] isn’t the driving force, but just one lens through which we can see how the system is behaving. In general, I have found that systems that tend more toward the choreographed approach are more loosely coupled, and are more flexible and amenable to change. You do need to do extra work to monitor and track the processes across system boundaries, however. I have found most heavily orchestrated implementations to be extremely brittle, with a higher cost of change. With that in mind, I strongly prefer aiming for a choreographed system, where each service is smart enough to under‐ stand its role in the whole dance.

Note: This sounds a lot like CQRS and EvenSourcing. To this day I'm still not sure if choreography is just another name for event-driven architecture (EDA), but if EDA is just one way to do it, what are the other ways? (Also see What do you mean by "Event-Driven"?)

Now, after this comes the fun. The Microservices book does not assume microservices are going to be implemented with REST. As a matter of fact in the next section in the book they proceed to consider RPC and SOA-based solutions and finally REST. Important point here is that Microservices does not imply REST.

So, What About HATEOAS?

Now, if we want to follow the RESTful approach we cannot ignore HATEOAS or Roy Fielding will be very much pleased to say in his blog that our solution is not truly REST. See his blog post on REST API Must be Hypertext Driven:

I am getting frustrated by the number of people calling any HTTP-based interface a REST API. What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period. Is there some broken manual somewhere that needs to be fixed?

So, as you can see, Fielding thinks that without HATEOAS you are not truly building RESTful applications. For fielding HATEOAS is the way to go when it comes to orchestrate services. I am just learning all this, but to me HATEOAS does not clearly define who or what is the driving force behind actually following the links. In a UI that could be the user, but in computer-to-computer interactions, I suppose that needs to be done by a higher level service.

According to HATEOAS, the only link the API consumer truly needs to know is the one that initiates the communication with the server (e.g. POST /order). From this point on, REST is going to conduct the flow, because in the response of this endpoint, the resource returned will contain the links to next possible states. The API consumer then decides what link to follow and move the application to the next state.

Despite how cool that sounds, the client still needs to know if the link must be POSTed, PUTed, GETed, PATCHed, etc. And the client still needs to decide what payload to pass. The client still needs to be aware of what to do if that fails (retry, compensate, cancel, etc.).

I am fairly new to all this, but for me, from HATEOAs perspective, this client, or API consumer is a high order service. If we think it from the perspective of a human, you can imagine an end user in a web page, deciding what links to follow, but still the programmer of the web page had to decide what method to use to invoke the links, and what payload to pass. So, to my point, in a computer-to-computer interaction, the computer takes the role of the end user. Once more this is what we call an orchestrations service.

I suppose we can use HATEOAS with either orchestration or choreography.

The API Gateway Pattern

Another interesting pattern is suggested by Chris Richardson who also proposed what he called an API Gateway Pattern.

In a monolithic architecture, clients of the application, such as web browsers and native applications, make HTTP requests via a load balancer to one of N identical instances of the application. But in a microservice architecture, the monolith has been replaced by a collection of services. Consequently, a key question we need to answer is what do the clients interact with?

An application client, such as a native mobile application, could make RESTful HTTP requests to the individual services [...] On the surface this might seem attractive. However, there is likely to be a significant mismatch in granularity between the APIs of the individual services and data required by the clients. For example, displaying one web page could potentially require calls to large numbers of services. Amazon.com, for example, describes how some pages require calls to 100+ services. Making that many requests, even over a high-speed internet connection, let alone a lower-bandwidth, higher-latency mobile network, would be very inefficient and result in a poor user experience.

A much better approach is for clients to make a small number of requests per-page, perhaps as few as one, over the Internet to a front-end server known as an API gateway.

The API gateway sits between the application’s clients and the microservices. It provides APIs that are tailored to the client. The API gateway provides a coarse-grained API to mobile clients and a finer-grained API to desktop clients that use a high-performance network. In this example, the desktop clients makes multiple requests to retrieve information about a product, where as a mobile client makes a single request.

The API gateway handles incoming requests by making requests to some number of microservices over the high-performance LAN. Netflix, for example, describes how each request fans out to on average six backend services. In this example, fine-grained requests from a desktop client are simply proxied to the corresponding service, whereas each coarse-grained request from a mobile client is handled by aggregating the results of calling multiple services.

Not only does the API gateway optimize communication between clients and the application, but it also encapsulates the details of the microservices. This enables the microservices to evolve without impacting the clients. For examples, two microservices might be merged. Another microservice might be partitioned into two or more services. Only the API gateway needs to be updated to reflect these changes. The clients are unaffected.

Now that we have looked at how the API gateway mediates between the application and its clients, let’s now look at how to implement communication between microservices.

This sounds pretty similar to the orchestration style mentioned above, just with a slightly different intent, in this case it seems to be all about performance and simplification of interactions.

Further Reading

There is a great series of articles recently published in the NGINX Blog that I recommend to delve deeper into all these concepts:

  • Introduction to Microservices
  • Building Microservices: Using an API Gateway
  • Building Microservices: IPC in a Microservices Architecture
  • Service Discovery in a Microservices Architecture
  • Event-Driven Data Management for Microservices
  • Choosing a Microservices Deployment Strategy
  • Refactoring a Monolith into Microservices
by imauld   2017-08-19
Very good read that gives a pretty high level description of services:

https://www.amazon.com/Building-Microservices-Designing-Fine...

by sundvor   2017-08-19
I somewhat recently worked on a huge monolith where certain parts were "off limits"; I was told to the effect of "noone changes those classes, we don't really understand them". That business is not going too well now.

I searched the article for "domain" and "bounded contexts", found nothing. Article is not without merit, however; Sam Newman in his book [1] cautions about going too aggressive, i.e. splitting down into too many microservices before the domain is fully understood. On the other hand, having systems cross obvious domains is a definite warning sign (of disaster).

So the motto might be, use them, but in moderation (as with a lot of things).

1) https://smile.amazon.com/Building-Microservices-Designing-Fi...