Monolithic services vs. microservices: which is the least WTFy?


  • FoxDev

    We're looking into designing an all-new V2 version of our API, and I want to make it as streamlined and simple as I can possibly make it. It's intended to be used both internally and externally, and I'm intending to go with a modular design, which will give me better control over access management and security. However, there's one question I need to answer before I get started actually designing this thing: should I design a single monolithic service, or a collection of microservices?

    I know what platform and IDE I'll be using: .NET and VS2017. I'm also favouring sticking with the tried-and-tested .NET Framework (most likely 4.7) over .NET Core (most likely 2.0), but I'm open to persuasion if it really does turn out .NET Core is a better fit.

    So, should I embrace the hipster way and use microservices? Or should I make an old-fashioned all-inclusive monolith? Or should I aim somewhere in the middle?


    No, we're not going to use Node.



  • @raceprouk Which one will be easier to maintain and expand by a constantly growing team of developers who are -- more or less -- unfamiliar with the existing codebase?

    Filed under: Asking for a friend



  • The one which is most effective for your environment (weighted over time) and application is the "good one", the other is the WTF...

    That being said, a MicroService design has been the choice made by most of my clients, and has worked out very well.

    [note: I highlighted the word design for a reason!]


  • Fake News

    Will the database be split into many smaller databases? Can all the services work independently from each other? Are they useable in a context other than the application you're replacing or do other applications have a different concept of e.g. a user, a product, ...?

    If you answer "no" to one of them, you might be building a "distributed monolithic service" rather than a bunch of micro-services.


  • FoxDev

    @jbert said in Monolithic services vs. microservices: which is the least WTFy?:

    Will the database be split into many smaller databases?

    No: it's one big database.

    skips the other questions

    @jbert said in Monolithic services vs. microservices: which is the least WTFy?:

    If you answer "no" to one of them, you might be building a "distributed monolithic service" rather than a bunch of micro-services.

    That does seem to be the more likely option at the moment.

    To be honest, I'm canvassing for general opinion before deciding whether to take the opportunity to try something new.


  • Fake News

    @raceprouk Just to double-check: building a distributed monolithic service is not a good thing - it indicates that you just made a monolothic application more prone to failure by network weirdness.

    For example, suppose you have a Single Page Application interacting with a backend which returns e.g. a list of (paged) invoices with (some) details. You could split it up into one call returning a page of just ids and several calls returning the detail for a single invoice, but that has almost zero benefit: it might make the initial load faster, but now some invoices might not get loaded if the network is congested, the DB is always returning little items, etc.



  • JBert is spot on. With true Microservices the only dependency is on other MicroServices [neglecting the specific services which communication with external systems, of course]....


  • Grade A Premium Asshole

    (DIsclaimer: I have never done something like this in real life, don't try this at work, yada yada)
    @raceprouk said in Monolithic services vs. microservices: which is the least WTFy?:

    We're looking into designing an all-new V2 version of our API, and I want to make it as streamlined and simple as I can possibly make it.

    What is your data model? I guess it will change significantly until you design V3? What is it that may never change, so you can depend your design on it?

    It's intended to be used both internally and externally

    And how will you keep the internal access safe from external users? You MUST keep the code paths separate, at a degree - Your system will inevitably need blessed access. If you expose any, any call that is not expected to be called by end or middle users, to the Internet, then an internal call gets exposed to the Internet. Even if you decide to ruin yourself and add AWS instances, put them all inside a VPN !

    , and I'm intending to go with a modular design, which will give me better control over access management and security. However, there's one question I need to answer before I get started actually designing this thing: should I design a single monolithic service, or a collection of microservices?

    Why should you use microservices? What are microservices to you?

    • Are they software modules? You could call each high level class a 'microservice', be done with it, and enjoy great reliability, and CPU latency and performance by keeping them all in a single OS-level process. Packing micro-nodes in a single process is even the new hot trend, just for these reasons.
    • Are they separate OS-level processes?
      What will you lose by separate processes?
      Each process the code path is passed through adds round trip lag, outstanding request RAM and CPU costs, and a failure point you must handle. And once you put a second machine, lag and robustness will suffer, and we've not even mentioned webscale dynamic clown instances. You are not Google and you don't need this class of problems.
      What will you gain from separate OS-level processes?
      Is it more internet IO volume? Then you need cloned API proxy instances, that will call the backend (Do not expose any part of the backend, use a protection layer before anyone that is not you!).
      Is it more concurrent DB hits? Is there anything to serve that is not money? You could put cache instances. But how will you keep, say, a forum thread page consistent enough? If you need something like MongoCouchDB to handle all the data changes, surely you also have the specialized full-time distributed DB experts to save you from total corruption?
      Is it software modularity? Then why do you need all the configuration and runtime complexity of juggling multiple independent processes? Does your software platform lack the facilities to keep the code sorted? Does your team lack the discipline to do so?
    • Are they separate machines? Do you want a single small, commodity box to hold your entire system hostage?
    • Are they separate projects or clients? Then how could you keep a single monolithic system to serve them all at the same time?


  • @bugmenot - All good advice. Remember I posed about Microservice and mentioned design specifically? These were some of the aspect. Also paying close attention to SOLID and DRY (among a few others). Once your design is solid (and you have automated design verification) implementation choices may present themselves.



  • @raceprouk Another important thing when considering microservices: No one knows where the correct splitting points for your application are. Things need to be thoroughly decoupled, and a lot of thought needs to go into which things are in the same service. I'd recommend splitting things later if you feel you need to, but otherwise not.



  • @raceprouk I'm going to suggest that a microservice design is better for reliability, in the sense of up-time. But realistically, implementing the software is going to be about the same difficulty either way. The only difference is that each "micro-codebase" is going to have to have its own server code to do auth, low level request handling, etc.

    So a microserver is worth it iff you can readily stick all that stuff in libraries or the servers have to be radically different anyway.



  • @raceprouk said in Monolithic services vs. microservices: which is the least WTFy?:

    So, should I embrace the hipster way and use microservices? Or should I make an old-fashioned all-inclusive monolith? Or should I aim somewhere in the middle?

    What do you mean exactly by "microservices"?

    It seems every programmer who champions them has a different idea what they are and how "micro" they need to be to be called "microservices".


  • Impossible Mission - B

    @cartman82 said in Monolithic services vs. microservices: which is the least WTFy?:

    What do you mean exactly by "microservices"?

    It seems every programmer who champions them has a different idea what they are and how "micro" they need to be to be called "microservices".

    Sounds about right.



  • @raceprouk Also, how do you intend to deploy this? Azure web services? Service Fabric? Some other system? That may matter a lot.


  • FoxDev

    @magus It's all going on Azure, but the exact form I've yet to decide. The current API is a sorta Web App thing, though it was actually created as an API App when Web Apps and API Apps were separate.

    I'm starting to think that I need to at least begin the design before I can choose the deployment method and micro vs. macro architecture, at least at a high level.



  • @raceprouk will your future services need to scale separately and in very different patterns? Will there be separate teams maintaining them? Do you have an idea how you would split the requirements on service lines? Would your application visibly benefit from more granular flow control and back-pressure that this architecture (properly implemented) provides?

    Every yes takes you one step closer to microservices. Every no leads you away.



  • @magus said in Monolithic services vs. microservices: which is the least WTFy?:

    @raceprouk Also, how do you intend to deploy this? Azure web services? Service Fabric? Some other system? That may matter a lot.

    Large effects on the implementation. Much less on the Design.



  • Basically as @bugmenot said, look behind the word and into the meaning. When you're splitting 1 service into several microservices, what are you really doing? Just splitting existing classes into processes or containers or VMs? That's silly and you're most likely just falling for buzzwords.

    If you're actually separating code into logically independent pieces, that is generally considered a good thing (to a certain extent).



  • A few good "smell tests" I use... If you are considering X for a microservice.

    1. is X a minimal yet complete set?
    2. could the contract (effectively API) be documented and outsourced to a qualified provider requiring only "routing changes" to the remainder of the system?