(I'm in the process of build a toy language).
Is this more a problem for a language with baggage, or is general? I wonder if for example in Go, Erlang is less of a issue...
(I'm in the process of build a toy language).
Is this more a problem for a language with baggage, or is general? I wonder if for example in Go, Erlang is less of a issue...
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.
I'm not saying I agree, but I do understand why some golang programmers might be evangelizing microservices as well
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.
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".
:)
> 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!
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.
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.
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...
(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.)
1. Support full threading and one of the memory models that allows it. To have an inspiration look at Clojure, Rust, Go, Erlang (probably I don't mean any particular order).
2. Have a standard communication way between processes, like Erlang has. My favourite would be to implement SP protocol family developed as a part of nanomsg library (https://github.com/nanomsg/nanomsg/tree/master/rfc).