Live data from Hacker News

In Defence of Monoliths

techblog.bozho.net

61–70 of 76 posts

Re: In Defence of Monoliths

#61
post #12

There's a dangerous, contagious illness that developers of every generation get that causes them to worry about architecture and getting "street cred" even more than they worry about solving business problems. I've fallen victim to this myself, because street cred is important to me. But it's a trap. An important meta-idea that encapsulates all of this is remember to solve your business problems as your first priorit…

Very well said.

A clean data model, one aligned with business needs, and sensitive to the nature of machines, makes the best architecture.

Far too many decisions are based on what is trendy and fashionable rather than what is right for the domain.

Re: In Defence of Monoliths

#62

It depends how you do micro services. There are middle grounds. One big gain of micro-services is that it guarantees things are separate and can be handled by separate teams if the need arises. That doesn't mean you need to start out that way. For instance in Python I use hug to create my microservices https://github.com/timothycrosley/hug , then I can just install them to create a "monolithic" services that consumes…

This is more or less what I'm doing right now with Dropwizard. I started building this app as a set of separated microservices, but was finding it to slow me down more than I wanted it to--so I flipped it upside-down and loaded every "application" into a single Dropwizard service. Which is uncomfortably like application servers, but I'm using this almost exclusively to get around doing the inter-service wire-up that I'd have to do manually, rather than letting my DI container do it. Each module's still separated, and if we need to fork services off in the future, it's about twelve lines of code.

Re: In Defence of Monoliths

#63
post #60
post #58

Earlier quoted context omitted.

I don't mind to sound crass, but it sounds like you implemented microservices poorly. You could s/microservices/threads/g on your post above and it would point much more to a problem with your implementation rather than a problem with threads.

Writing multi-threaded code is hard, writing micro services is even _harder_. I don't think your argument holds here. Micro services are hard to write, so don't write them unless you absolutely have to.

I think in 2015 we should be pretty good at writing code without race conditions, especially considering the tools made available to us by our programming languages.

Re: In Defence of Monoliths

#64

One advantage of a microservice architecture not mentioned in the article is the ability to scale services independently of other services. Being able to fire up more instances to address a bottleneck is often much simpler than managing threads in a monolith.

you can often as easily deploy a monolith to multiple servers and grant different subtasks different cpu and memory for their work. for me its just a matter of adjust with the supervisord config for each server, how many of which workers start and run on that machine.

Re: In Defence of Monoliths

#65

Earlier quoted context omitted.

> Ensuring that a change in one micro service doesn't break things in another can be daunting. That is what I was referring to when I mentioned nebulous APIs. In a properly-designed system, each component (be it a module of a monolithic system or service in a microservice system) should be a black box with known APIs and no side effects. Part of defining the API is defining the acceptable values that can come across…

The more your system is broken down into smaller components the more you have to break an API to make a change. Unless all change consists of nothing but bug fixes and performance enhancements, changes to the API is as common as anything else. If your need is respond quickly to changing requirements this setup falls flat.

We've never had to break an API to make a change. Changes to the API should not break existing consumers. That's just as true for monoliths as it is for microservices.

Re: In Defence of Monoliths

#66

Earlier quoted context omitted.

The more your system is broken down into smaller components the more you have to break an API to make a change. Unless all change consists of nothing but bug fixes and performance enhancements, changes to the API is as common as anything else. If your need is respond quickly to changing requirements this setup falls flat.

We've never had to break an API to make a change. Changes to the API should not break existing consumers. That's just as true for monoliths as it is for microservices.

A change to an API necessarily, by definition, breaks existing consumers. You can add to an API without breaking consumers but you can't change or remove.

Re: In Defence of Monoliths

#67

Earlier quoted context omitted.

> Ensuring that a change in one micro service doesn't break things in another can be daunting. That is what I was referring to when I mentioned nebulous APIs. In a properly-designed system, each component (be it a module of a monolithic system or service in a microservice system) should be a black box with known APIs and no side effects. Part of defining the API is defining the acceptable values that can come across…

The more your system is broken down into smaller components the more you have to break an API to make a change. Unless all change consists of nothing but bug fixes and performance enhancements, changes to the API is as common as anything else. If your need is respond quickly to changing requirements this setup falls flat.

So you either use versioning or RESTy immutable endpoints. Anything else is going to be unmaintainable

Re: In Defence of Monoliths

#68
post #7
post #3

> decentralize all things – well, the services are still logically coupled, no matter how you split them. I think this is missing the point. It isn't just about decentralizing services , it is also about allowing you to decentralize teams and decision making . With very large teams working on a single monolith, features that are complete often cannot be deployed because of the larger organizational overhead of planni…

> The higher coupling in most monoliths also restricts a teams ability to try new things and take risks. I think it's you who's missing the point. That right there is why. Turning your monolith into a micro-service architecture should add up to basically: - Wrap your internal modules in your favourite form of RPC - Replace the modules with stubs that call the RPC If you need more work than that, the problem with your…

The microservices approach has 2 major benefits - 1. Those boundaries running over services allows you a lot of flexibility in read caching using commodity software like Varnish or Mongo (generally assuming REST here) 2. It allows for a polyglot architecture (ok it's a benefit or disadvantage depending on your outlook)

Re: In Defence of Monoliths

#69
post #58
post #29

We've had a lot of issues with micro services. They're extremely difficult to debug and end up being too generic. I argue the reasons why we introduced microservices has merit (massive code base) but does not mean they are simple to use/maintain. Here are some examples: 1. A chat service (race conditions, synchronization issues between the game server and chat service that had to be debugged using sequence diagrams)…

I don't mind to sound crass, but it sounds like you implemented microservices poorly. You could s/microservices/threads/g on your post above and it would point much more to a problem with your implementation rather than a problem with threads.

No true Scotsman...

Monoliths have the advantage of being able to trivially take out a global lock.

Removing global locks from a monolith to migrate to a micro-service deployment adds a ton of design and engineering cost.

Re: In Defence of Monoliths

#70

Earlier quoted context omitted.

don't you think 150LOC is a bit extreme on the low side? I don't see how this is possible unless you compose services out of other services... and in that case it's probably a nightmare to debug anything. Can you elaborate a bit on types of things that this worked great for you?

I can't walk through a solution to a complex domain inside of a HN comment, but I can provide an overview of the theory. Take a large monolithic app or framework. What I've found is that if a problem is properly coded, while you may have tens or hundreds of thousands of LOC, the actual code doing the work is quite small, on the order of hundreds or thousands of LOC. The rest of it is all "wiring". Moving to pure FP m…

they do one thing and only one thing, they're configurable using command-line switches,

The more command line switches the more code paths. The more code paths the less of doing one thing and only one thing.

Post reply on HN