Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If you imagine a monolith as a service that:

  takes a request 
  -> deserializes it/unpacks it to a function call
  -> sets up the context of the function call (is the user logged in etc)
  -> calls the business logic function with the appropriate context and request parameters
  -> eventually sends requests to downstream servers/data stores to manipulate state
  -> handles errors/success
  -> formats a response and returns it
The main problem I've seen in monoliths is that there is no separation/layering between unraveling a requests context, running the business logic, making the downstream requests, and generating a response.

Breaking things down into simplified conceptual components I think there is a: request, request_context, request_handler, business_logic, downstream_client, business_response, full_response

What is the correct behavior?

  return request_handler(request):
    request -> request_context;
    business_response = business_logic(request_context, request):
      downstream_client();
      downstream_client();
    business_response -> full_response;
    return full_response;
    
  business_response = request_handler(request_context, request):
    return business_logic(request_context, request):
      downstream_client();
      downstream_client();
  business_response -> full_response;
  return full_response;  

  request -> request_context;  
  business_response = request_handler(request_context, request, downstream_client):
    return business_logic(request_context, request, downstream_client):
      downstream_client();
      downstream_client();
  business_response -> full_response;
  return full_response;  
    
  something else?
In most monoliths you will see all forms of behavior and that is the primary problem with monoliths. Invoke any client anywhere. Determine the requests context anywhere. Put business logic anywhere. Format a response anywhere. Handle errors in 20 different ways in 20 different places. Determine the request is a 403 in business logic, rather than server logic? All of a sudden your business logic knows about your server implementation. Instantiate a client to talk to your database inside of your business logic? All of a sudden your business logic is probably manipulating server state (such as invoking threads, or invoking new metrics collection clients).

The point at which a particular request is handed off to the request specific business logic is the most important border in production.



> In most monoliths you will see all forms of behavior and that is the primary problem with monoliths. Invoke any client anywhere. Determine the requests context anywhere. Put business logic anywhere. Format a response anywhere. Handle errors in 20 different ways in 20 different places.

This just seems like a poorly (or not at all?) designed monolith, if there's no standard way of doing things, of concerns or responsibilities of various application layers? I mean I've been there too in organizations, but it just seems like we're skirting around the obvious: the system should've had a better architect (or team) in charge?


>This just seems like a poorly (or not at all?) designed monolith, if there's no standard way of doing things, of concerns or responsibilities of various application layers? I mean I've been there too in organizations, but it just seems like we're skirting around the obvious: the system should've had a better architect (or team) in charge?

First you need to have people who understand architecture. College does not meaningfully teach architecture. How many businesses are started with senior devs who know what they are doing? How many business are going to spend time on architecture while prototyping? When a prototype works, do you think they are going to spend resources fixing architecture or scaling/being first to market?

When a new employee joins, how many companies are going to inform the new employee on standard architecture practices for the company? After how many employees do you think it's impossible for 1 person to enforce architecture policy? Do you think people will even agree what best architecture is?

What about hiring new people? Is it important to hire another dev as fast as possible when you get money, or to have 1 dev fix the architecture? After all technical debt is cheaper to pay off (50% of engineering resources) with 2 devs than with 1 (100% of engineering resources), context switching is it's own expense...

Once you get into pragmatics you understand that good architecture is a common in the tragedy of the commons sense. It takes significant resource cost and investment for a very thankless job. So you must have authority make a commitment to architecture, who is almost always going to be making cost benefit analysis which is almost always going to favor 1 day from now to 1 year from now.


I guess it all boils down to building software with modular structure rather than mixing business logic all around. I personally think that it is easier to isolate business logic with microservice structure, but you can also make a huge mess. You can also make really good modular monolith, where business logic and state is where it belongs and not spread everywhere.


It is easier to isolate business logic with a microservice architecture, but as the microservice graph gets more complicated so too does administering it.

How do you make graphs that make sense of your various microservices? How do you make sure code doesn't get stale/all versions are compatible/rolling back code doesn't take out your website? How do you do capacity planning? How are service specific configurations done? How does service discovery work? How do you troubleshoot these systems? How do you document these systems? How do you onboard new people to these systems? What about setting up integration testing? Build systems? Repositories? Oncall? What happens when a single dev spins up a microservice and they quit? What happens when a new dev wants to create a new service in the latest greatest language? What happens when you want to share a piece of business logic of some sort? What about creating canaries for all these services? What about artifact management/versioning?

What about when your microservice becomes monolithic?

Complexity is complexity no matter where it exists. Microservices are an exchange of one complexity for another. Building modular software is a reduction of complexity. A microservice that has business logic mixed with server logic is still going to suffer from being brittle.


I definitely agree. I'm actually thinking that the microservices architecture punishes team earlier for creating a mess, which is a good thing. It forces you to adapt good patterns, because otherwise nothing will work.

I'm not sure, but I feel that with monoliths the teams get punished later and thus create a bigger mess. But I guess it's more like 60/40 rather than 99/1.


The answer to your questions is, hire competent SRE’s.


An SRE might help you build systems, but that is a lot of system to build depending on number of microservices. Managing the complexity of N services comes at a cost, maybe that cost is in how seamless and wonderful the testing infra is.

A very well built monolith is very easy to manage.

Most product devs want to trivially build a feature, not deal with the complexities of running a service in production. Abstracting away a request handler is going to be an easier overall system than abstracting services.

As for the oncall/onboarding etc, SRE is there to support and enable, not to be an ops monkey, so that stuff scales with number of services/engineers.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: