Live data from Hacker News

The End of Microservices

lightstep.com

81–90 of 154 posts

Re: The End of Microservices

#81
post #71
post #68

Earlier quoted context omitted.

Not as I understand microservices. A library would be something that's compiled or included in to your application code. A microservice is a separate process that the application communicates with over a protocol (eg http).

I think the point is you can achieve the same result by just using a library. There are potential benefits and downsides to services over libraries of course, but unless there are specific requirements that make a library unsuitable, all else equal I would rather just use a library.

Microservices also enable you to scale individual parts of your application. If you need better performance for, say, image compression then it's much easier to add resources to a service that lives in its own process space (or its own server, or rack of servers, or data centre..) than it is to improve the performance of a specific library in a larger application.

Re: The End of Microservices

#82
post #71
post #68

Earlier quoted context omitted.

Not as I understand microservices. A library would be something that's compiled or included in to your application code. A microservice is a separate process that the application communicates with over a protocol (eg http).

I think the point is you can achieve the same result by just using a library. There are potential benefits and downsides to services over libraries of course, but unless there are specific requirements that make a library unsuitable, all else equal I would rather just use a library.

There are a number of downsides of libraries that make services attractive by comparison. Of course, it's not as if one or the other is better in all circumstances.

First, libraries don't encapsulate very well. A storage service hides its representation from users. A storage service can change its implementation at any time without users having to know or care. Perhaps you migrate from Cloud Provider X to Y. A shared storage library, on the other hand, can't just change its implementation on a whim. Libraries vend functionality, and they encapsulate functionality at a coding level, but they don't encapsulate much at a systems level, especially in distributed systems. For example, if this function would talk to a data store like a database or another remote service, then under the service approach, only one application talks to the database, while with the library approach, a ton of applications using the library do -- and now they all need network access to that DB and credentials to talk to it. They care about the details of how to reach it. Every library consumer needs that configuration.

With a service, you can implement security features like input sanitization and access control on the service-side. With a library, you're reliant entirely on trusting its users. (A library can have these functions too, but a malicious user or attacker can bypass them if they compromise the machine it's running on. A service implementation runs in a different security context.)

When a library changes, you need to tackle the problem of distributing the new version to every application that uses it. When a service changes, you just deploy the new version, and all systems using it immediately experience the new version. When a service changes, you can completely coordinate the way in which the new functionality rolls out. You can pass 1% of requests through a new version of the code, if you want. You can pass requests through both versions of the code, and compare one to the other. You can in principle do these things with a library, but few organizations have the ability to roll out updates to all usages of a library nearly as effectively as they can change and redeploy a service. Services allow the service owner to centrally control the behavior of the functionality in all circumstances where it's used.

Libraries don't help you scale different parts of your system differently. For example, let's say that the storage service needs to cache a lot of content for good response times. If that's a library, then all of the applications using it need to have adequate RAM or disk for the cache. With a storage service, that can be hidden behind the service interface, and only the machines running the service need the extra RAM/disk.

Services are portable in a way that libraries are not. A library needs to be implemented in a way that can be consumed within many platforms. For example, it might not be easy to vend the same function for applications on Windows, Ubuntu, MacOS. With a service, I might vend only an interface description, or lightweight clients for the platforms I target.

A service separates the consumption of the functionality entirely from its operation. If there's a defect in the service, like it's returning the wrong result, then that's the service owner's problem to fix and roll out an update. If the library everyone is using in their applications is returning the wrong result, then that's now everyone's problem.

With a service, I can measure anything and everything I might want to know about the behavior of an operation. I can record metrics and log files and anything I want. With a library, there isn't always an easy way to get the information out of applications that use it. Services make applications easier to understand and troubleshoot, because you can reduce the amount of code running on any given machine (VM) to the smallest reasonable amount, compared to applications that embed potentially many libraries. Debugging a library is tricky because you need to debug the application too. I can debug or instrument a service all on its own, without affecting its clients.

The right answer to this question might depend on the scale of the component's usage, the scale of the functionality, and how much you care about these properties, and encapsulation, and coordinated update, etc. Services start to become compelling at a sort of inflection point where you have a lot of usage, enough that updating all applications using a library would be problematic, and you want to decouple things (both components within software and the organizations that develop and run them). I probably have more to say about this, but I'll leave it here. There are plenty of reasons why you'd choose to make something a library, but there are also good reasons why to choose a service.

Re: The End of Microservices

#83

Earlier quoted context omitted.

If you're starting "micro", why do you need the "services" part at all? Why not just make it a function call? To use your example, if my task were "make a record of the errors of this process available on the web", my first thought would be to write to stderr, pipe stderr to a file, and then serve that from the webroot of some commodity webserver like Apache, 'python -m SimpleHTTPServer', or even S3. If the format is…

It is a pure function call. There are no side effects, just a clear and simple input stream and a clear and simple output stream. I agree with your characterization. All except maybe the "I'd probably write a quick JS viewer that can collapse stack traces" part. Here's the thing: I'm so minimalist that I'm only going to add frameworks and libraries as a last result, if you stuck a gun to my head. I'm going to resist…

I'd agree philosophically that this is the right way to do it, but that's not what most people are speaking about when they say "microservices". They usually mean small independent servers communicating via RPC, each of which only does one thing. I'd say that this is pretty much the opposite of what you describe, since now each task needs the overhead of serialization, deserialization, marshalling, error-checking, process monitoring, etc.

Re: The End of Microservices

#84

I see several people criticize microservices here. We've been doing it for about 6 years and are extremely happy with it. A core principle which a lot of people and articles ignore, though, is reusability . I bring this up on HN every time there's a discussion about microservices, yet I've never seen any discussion about it. Essentially, you build out the backend to act as a library for your front end. So we have log…

I have been doing it since the early 90's.

It is called unit, module, package, library.

No need to put some network layer, with its own set of problems, between method/function calls.

Re: The End of Microservices

#85
post #55

Earlier quoted context omitted.

You are not getting more reusability from a bunch of microservices, compared to one big service, I don't see where you got that?

I also don't see how microservices are more reusable. However, the replacability is usually much better due to being forced to define sharp boundaries with clear interfaces.

But that is the thing.

It just means that instead of using the language features and creating clean interfaces across modules, they were witting spaghetti code.

With microservices they get to write spaghetti REST calls with the added fun of distributed computing failures.

Re: The End of Microservices

#86
post #33

I'll tell you the real reason behind microservices: developer fiefdoms. "Faux-Specialization". It allows developers to feel like they have control over certain pieces of infrastructure and run the gambit on their strategy for getting ever more increasing pieces of the pie. It has nothing to do with building reliable software. You could just as easily build and deploy a single networked application (so called "monolit…

You say it as if it's a bad thing... Compared to the alternative, fiefdoms really are a wonderful thing! I once work for a giant fortune 500 corporation. Our department had a good 300 developers, and had been writing code for years. They had built the whose system using the classic, box-box-cylinder architecture. There were hundreds of little top tier 'services', but in practice, they all shared the same database, ha…

I really value your contribution, thanks for sharing.

I give the proponents/consultants credit for proposing a practical and incremental solution to these people instead of just insulting them or saying "you're doing it wrong".

That being said, the issue I have with microservices is the fact that the below is repeatedly used as a core technical argument :

> They had built the whose system using the classic, box-box-cylinder architecture. There were hundreds of little top tier 'services', but in practice, they all shared the same database, had to be deployed pretty much at the same time, and version upgrades had to go in lockstep. Every so often, database changes were necessary, and the world would grind to a halt for months to make the system still work after the migration: It was awful.

This is not a feature of "monoliths", this is a feature of shortsighted design (at the beginning) and cowboy design (at the end).

Let's be clear : apart for load balancing for performance critical areas (which only exist in 20% of the applications, and only cover 1% of a typical such application - or 60% if you are Google, Facebook, or Amazon or the rest of the top 10), there's nothing that microservices do better than in-memory libraries. Also, centralizing everything as opposed to having processes run on various servers creates the issue of the single point of a failure. Whole new classes of similar issues appear. It basically is buying troubles.

Adding microservices will never be a neutral operation, and incurs a real cost. This cost is the cost of distributed objects which has been known for over 20 years and has been well-documented by our fathers.

Once the above has been dismantled, it then comes to : "yes but teams can develop in different languages", "yes but dependency management becomes easier". But once again, when it comes these interoperability considerations, a solution also exists and has been created about 15 years ago. This solution is called .NET (30+ languages compiling to a single Intermediate Language, COM components, first-class library support, etc...). Even the "yes but I need to communicate with non .NET in-memory applications" is very maturely addressed by the framework. (it was one of the first-use cases addressed)

I also read in this thread : "the ability of teams to control their own destiny and not be blocked by other teams". With libraries teams can choose the version that works best for them, and a well-design in-house library would provide the extension points (Dependency Injection, Dynamic Binding...) that would allow the clients (the other teams) to specialize the behavior.

So in a gist, my main reproach for this, is that if people put the same effort they put in learning microservices to learning system and component design, they wouldn't even be a need to talk about the former. My regret is that people will always choose the hype and the new. But hey, that's how the game works.

Re: The End of Microservices

#87

Earlier quoted context omitted.

It is a pure function call. There are no side effects, just a clear and simple input stream and a clear and simple output stream. I agree with your characterization. All except maybe the "I'd probably write a quick JS viewer that can collapse stack traces" part. Here's the thing: I'm so minimalist that I'm only going to add frameworks and libraries as a last result, if you stuck a gun to my head. I'm going to resist…

I'd agree philosophically that this is the right way to do it, but that's not what most people are speaking about when they say "microservices". They usually mean small independent servers communicating via RPC, each of which only does one thing. I'd say that this is pretty much the opposite of what you describe, since now each task needs the overhead of serialization, deserialization, marshalling, error-checking, pr…

There's quite a bit of variability in what people mean when they say "microservice" I've read quite a few articles over the last few years that describe things as I just did.

However, you are correct. Most people are unable to get the cruft out of their head, so when they talk about microservices, they mean something like "exactly the way we used to do things, only with a few differences"

I was talking to a team last year that wanted to do microservices. They had a framework, a lot of tools, and were busy doing research, most of which consisted of reading fanboy posts and walking through happy-path tutorials.

When I started listening to what they were talking about in terms of an architecture? Wow! Too much to go into here, but one of the things was a "microservice" that at the beginning of the pipeline cleaned all the data.

Think about that. One "service" which was responsible for knowing every data type, performing all safety checks, and ensuring that all of the other services could run correctly. All in one place. You screw that one up? The whole thing is broken. You couldn't ask for tighter coupling.

And this, they thought, was better than a monolithic app.

I'm a big fan, but micoservices are going to make a huge mess in the industry that it will take decades to clean up. That's because most people doing them will think of them just as you suggested.

(Having said that, the ones who don't are going to run over everybody else in terms of productivity. Good for them and the orgs they work for)

Re: The End of Microservices

#88
post #33

I'll tell you the real reason behind microservices: developer fiefdoms. "Faux-Specialization". It allows developers to feel like they have control over certain pieces of infrastructure and run the gambit on their strategy for getting ever more increasing pieces of the pie. It has nothing to do with building reliable software. You could just as easily build and deploy a single networked application (so called "monolit…

You say it as if it's a bad thing... Compared to the alternative, fiefdoms really are a wonderful thing! I once work for a giant fortune 500 corporation. Our department had a good 300 developers, and had been writing code for years. They had built the whose system using the classic, box-box-cylinder architecture. There were hundreds of little top tier 'services', but in practice, they all shared the same database, ha…

I agree with you that it's not a bad thing - I think it's the main benefit of microservices for most larger organizations, the ability for different teams to control their own destiny and not be blocked on each other.

But there's now a whole bunch of new developers out there who are just starting out and read all about these microservices, and think that it's the way to write web backends, and that if you don't do it that way, you just don't know what you're doing. Even if you're a two person team - you must use microservices if you want to scale out in the future apparently. It's just unfortunate the amount of cargo culting going on.

Re: The End of Microservices

#89
post #63
post #56

Earlier quoted context omitted.

I think it's the old loose coupling vs. late binding discussion. Some people confuse the former with the latter. You can very mechanically achieve late binding with microservices, but it takes extra effort to actually achieve loose coupling; and guess what, the effort might or might not be less than doing loose coupling within the components of a monolith.

I was just reading the other day this article about the Backend for Frontend pattern (BFF) which suggests the best way to avoid tight coupling is for services you don't want tightly coupled to be owned by different teams, and to allow reasonable duplication of functionality between them. Everybody knows how hard it is to get another team to implement functionality for you. This is where I got the BFF pattern from: ht…

I fully agree with this. If a system cannot be extended by some external team using only external extension points, all claims of modularity and architecture are idle talk.

I tend to use MEF (on .NET) and OSGi (on the JVM) not because I actually need extensibility, but because I want to enforce certain architectural constraints.

Re: The End of Microservices

#90
post #55

Earlier quoted context omitted.

You are not getting more reusability from a bunch of microservices, compared to one big service, I don't see where you got that?

I also don't see how microservices are more reusable. However, the replacability is usually much better due to being forced to define sharp boundaries with clear interfaces.

> the replacability is usually much better due to being forced to define sharp boundaries with clear interfaces

If by "sharp boundaries with clear interfaces", you mean API specification, how is it a microservice thing? I thought the benefits of microservices lie in behind-the-scenes details.

Post reply on HN