Skip to content

Comment on The Future of Asynchronous IO in Pythonparent

Comments

The entire premise of this article is that the author has adopted the microservices disease and is suffering from not having asynchronous IO. You'll never hear an Erlang programmer even talk about microservices because they are a solution to a problem that doesn't exist in Erlang, or any sufficiently concurrent language for that matter[0]. Oh, and microservices clearly create other problems, such as messaging.

0 - I do hear Go-lang users talk about microservices, which is weird. Because they have decent concurrency primitives to where they shouldn't need to split web applications up into microservices.

You'll never hear an Erlang programmer even talk about microservices because they are a solution to a problem that doesn't exist in Erlang, or any sufficiently concurrent language for that matter[0].

The architecture of an idiomatic Erlang-based system is essentially a microservice architecture.

- I do hear Go-lang users talk about microservices, which is weird. Because they have decent concurrency primitives to where they shouldn't need to split web applications up into microservices.

Microservice architecture has motivation (loose coupling, distribution, independent scalability of components) that go considerably beyond "my language doesn't have decent concurrency primitives".

The architecture of an idiomatic Erlang-based system is essentially a microservice architecture.

:)

loose coupling, distribution, independent scalability of components

If you have good abstractions for concurrency then distribution and independent scalability should be trivial in a single codebase. Loose coupling is usually a false dream. Microservices tend to get coupled at the network level instead of the code level. Yuck!

A system which serves millions of users spans multiple machines. It's much easier to scale and evolve your stack if you're keeping it decoupled. Plus if you use something like nanomsg you can keep the services on the same host, and use something like ipc:// for minimal latency, then just switch the protocol and move the service to a new host with no other changes when it's time to scale up.

No matter how good your concurrency primitives, you cannot escape the network. Yes, I know, Erlang is awesome and has excellent distribution and concurrency capabilities out of the box, but you cannot write all the things in Erlang, nor should you want to. Different languages/services have to talk to each other somehow and at some point.

A system which serves millions of users spans multiple machines. It's much easier to scale and evolve your stack if you're keeping it decoupled.

It can be much harder. Let's say that you have a zipcode<->address conversion library and you're deciding whether to use it within the web stack (option A) or to create an additional service with a REST API on a separate machine (option B). Microservices!

Option A means that it scales with your web stack. If you have 5 application servers today behind a load balancer and your load doubles then tomorrow you will need 10.

Option B means an entirely new set of servers. Not only do you still need those 5 application servers, you need an entirely new server for handling zipcode<->address translation. Let's say it's maxed out.

What happens when your load doubles then?

Well, you'll still need to scale up those 5 application servers running behind a load balancer, but you ALSO need an entirely new load balancer and two servers behind it for the zipcode<->address translation service.

Different languages/services have to talk to each other somehow and at some point.

This doesn't mean that you need for them to talk over a network layer.

I don't see why would you need to have a load balancer for the zipcode service; if the service truly scales linearly with the number of application servers, you can simply tie them together 1-on-1 with simple configuration.

What, so one extra zipcode server for every application server?

Or N-to-1. You still don't need load balancing, if it truly scales linearly, just configuration.

Microservices are touted as being fault tolerant. Erlang provides fault tolerance as part of the OTP. While I haven't programmed much in Go, I haven't seem much in the way of fault tolerance.

a lot of the articles I read about microservices seem to come at them more from an organization point-of-view than a concurrency one. That is, encapsulating the logic for one specific component of a system, both for ease of scaling up only the parts of the system that need to be scaled, as well as for a different way for dev teams to interact with other parts of the system.

I'm not saying I agree, but I do understand why some golang programmers might be evangelizing microservices as well

I still don't see how it really helps. For organizational concerns it may be easier to say that a team is responsible for a (micro)service than for a library, but it doesn't have to be easier. If they change their API all users will suffer anyway. It doesn't have to help much with scaling either. If the service/library is the thing that uses most of the cpu it will still help to add more servers with everything on them. Microservices actually may cause bigger lag since the network connections may take time (app calls service 1 which calls service 2 etc). If they all were libraries on the same server the calls would be much faster.

You do get an opportunity to monitor each service easier if they live on separate machines (or just separate processes). If you want that with libraries you need to add monitoring code to all libraries and then collect data from them to see where the bottlenecks are. You might also need to develop new tools to configure things like pool-sizes and cache-sizes for each library. For example saying that you should have 5 threads (or handlers) handling mail-messaging and 20 threads/handlers handling calculations. You might also want to be able to change theese configurations in a live system. I think a lot of applications misses this monitoring and configuration part and then gets into problem because of that. And of course microservices helps with using different languages for different parts, even though most organizations I've seen seem to mandate a specific language anyway.

Good point about the organizational point of view. I'm still torn on whether more smaller teams is better for organizations or worse. Smaller is usually better, but now along with coordinating between the applications at the network level you also have to coordinate between applications at the human level. Some organizations probably do a lot better at this than others.

Maybe I'm dumb, but doesn't splitting up a web application into micro services have many other benefits such as modularity, constraining complexity, code reuse etc.?

You can get those with a straight library without introducing the complexity of message-passing, RPCs, and distributed systems.

(I'm a big fan of SOAs/microservices for companies that operate at Google-scale. Most companies do not, and for the rest of us - plain old libraries are very underrated. You can always slap an RPC layer or message broker on top of a library's API, but there's no reason to pay that cost until you need to. The real reason to break things up into microservices is when you run out of RAM on the box, or alternatively when you want better cache hit rates by focusing the processor on a small amount of code. You typically don't get there until you're serving thousands of QPS against a data set in the terabytes.)

Modularity: No. Your headache in creating a system of micro services will just be that much greater if you don't have modular code. I wouldn't call that a benefit even if it does end up with you writing more modular code.

Constraining complexity: It actually makes complexity worse (what do you do when microservice A goes down? times out? returns data you can't deserialize? takes too long?). These things you do not have to worry about if you are not doing any inter process or inter-server communication.

Code reuse: No. Why would it help code reuse?

Additionally....

https://en.wikipedia.org/wiki/Fallacies_of_distributed_compu...

Bingo! It's extra funny when someone that dislikes distributed systems is pro SOA. How do SOA advocates not realize they are signing up for distributed systems? If you think keeping business logic decoupled is hard, try keeping network logic decoupled, oh and that unreliability thing, too.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.