Where does Elixir/erlang fit into the microservices approach?

12,880

This is a very open question but I will try to illustrate why Elixir/Erlang may be the best platform out there for developing distributed systems (regardless if you are working with microservices).

First, let's start with some background. The Erlang VM and its standard library were designed upfront for building distributed systems and this really shows up. As far as I know, it is the only runtime and VM used widely in production designed upfront for this use case.

Applications

For example, you have already hinted at "applications". In Erlang/Elixir, code is packaged inside applications which:

  1. are started and stopped as unit. Starting and stopping your system is a matter of starting all applications in it
  2. provide a unified directory structure and configuration API (which is not XML!). If you have already worked with and configured an OTP application, you know how to work with any other one
  3. contains your application supervision tree, with all processes (by process I mean "VM processes" which are lightweight threads of computation) and their state

The impact of this design is huge. It means that Elixir developers, when writing applications have a more explicit approach to:

  1. how their code is started and stopped
  2. what are the processes that make part of an application and therefore what is the application state
  3. how those process will react and be affected in case of crashes or when something goes wrong

Not only that, the tooling around this abstraction is great. If you have Elixir installed, open up "iex" and type: :observer.start(). Besides showing information and graphs about your live system, you can kill random processes, see their memory usage, state and more. Here is an example of running this in a Phoenix application:

Observer running with a Phoenix application

The difference here is that Applications and Processes give you an abstraction to reason about your code in production. Many languages provides packages, objects and modules mostly for code organization with no reflection on the runtime system. If you have a class attribute or a singleton object: how can you reason about the entities that can manipulate it? If you have a memory leak or a bottleneck, how can you find the entity responsible for it?

If you ask anyone running a distributed system, that's the kind of insight that they want, and with Erlang/Elixir you have that as the building block.

Communication

All of this is just the beginning really. When building a distributed system, you need to choose a communication protocol and the data serializer. A lot of people choose HTTP and JSON which, when you think about it, is a very verbose and expensive combination for performing what is really RPC calls.

With Erlang/Elixir, you already have a communication protocol and a serialization mechanism out of the box. If you want to have two machines communicating with each other, you only need to give them names, ensure they have the same secret, and you are done.

Jamie talked about this at Erlang Factory 2015 and how they were able to leverage this to build a game platform: https://www.youtube.com/watch?v=_i6n-eWiVn4

If you want to use HTTP and JSON, that is fine too and libraries like Plug and frameworks like Phoenix will guarantee you are productive here too.

Microservices

So far I haven't talked about microservices. That's because, up to this point, they don't really matter. You are already designing your system and nodes around very tiny processes that are isolated. Call them nanoservices if you'd like to!

Not only that, they are also packaged into applications, which group them as entities that can be started and stopped as unit. If you have applications A, B and C, and then you want to deploy them as [A, B] + [C] or [A] + [B] + [C], you will have very little trouble in doing so due to their inherent design. Or, even better, if you want to avoid adding the complexity of microservices deployments into your system upfront, you can just deploy them altogether in the same node.

And, at the end of the day, if you are running all of this using the Erlang Distributed Protocol, you can run them in different nodes and they will be able to reach other as long as you refer to them by {:node@network, :name} instead of :name.

I could go further but I hope I have convinced you at this point. :)

Share:
12,880

Related videos on Youtube

Papipo
Author by

Papipo

I take my hobbies seriously. As a programmer, I started professionally with PHP many years ago, and switched to ruby when rails 0.11 came out. I've done some lots of stuff with Ruby and Rails over the years, and some with Javascript (Mithril) and Cordova, GraphQL, Elixir, TypeScript... Lately I've been experimenting with docker, kubernetes, Elixir and Erlang as well as with Rust.

Updated on January 28, 2020

Comments

  • Papipo
    Papipo over 4 years

    Lately I've been doing some experiments with docker compose in order to deploy multiple collaborating microservices. I can see the many benefits that microservices provide, and now that there is a good toolset for managing them, I think that it's not extremely hard to jump into the microservices wagon.

    But, I have been experimenting with Elixir too, and I am quite fond of the benefits that provides by itself. Given that it encourages packing your code into multiple decoupled applications, and supports hot code upgrades, how would you mix docker with elixir (or erlang, for that matter)?

    For example, if I want to use docker because it provides dev-prod parity, how does elixir fit in that? Given that docker containers are immutable, I lose the ability to do hot-code upgrades, right? What about blue/green deployments or canary releases?

    I mean, I could just write microservices with Elixir and use them as if they were written in any other language, polyglotism is one of the benefits of microservices anyway, but then I'm not getting the full benefits of using the OTP platform, I guess that pure collaborative erlang applications are way more optimal that using intermediate queues to communicate between microservices written in different (or not) languages.

    • Papipo
      Papipo almost 9 years
      I see that the downvote is because the question "does not show any research effort". That's sad because it's not really true, of course the problem might be on the question itself, but I can't be accused of not researching because lately it's the only thing I've been doing. A lot.
    • Paweł Obrok
      Paweł Obrok almost 9 years
      This question is too broad - questions on stackoverflow are meant to include specific problems.
    • Papipo
      Papipo almost 9 years
      should I move it to another stackexchange site? Because the quesiton is legitimate IMO.
    • Paweł Obrok
      Paweł Obrok almost 9 years
      I don't think so - it's legitimate, but almost entirely context- and opinion-based. Depending on your specific circumstances, skills, etc. any number of answer may be "correct"
    • Abhishek
      Abhishek almost 9 years
      I think its an interesting question, but might belong on the programmers stackexchange? That being said, not voting to close
    • bryan hunt
      bryan hunt about 8 years
      It's awesome, and totally made for the job.
    • bryan hunt
      bryan hunt about 8 years
      Hope that response didn't come across as overly subjective ;-)
    • Kenny Evitt
      Kenny Evitt almost 5 years
      I don't think this question is too broad and the currently accepted answer is pretty strong evidence that that's the case.
  • Papipo
    Papipo almost 9 years
    Actually I like Elixir and OTP a lot, the question was more about how to get some benefits of microservices (like dev-prod parity, canary releases, etc) while using Elixir.
  • José Valim
    José Valim almost 9 years
    I had a paragraph about Docker but it got lost. :) The gist is that you use it for node deployment so you pick which applications make sense per node. Blue/green deployments are definitely achievable but depends on the protocol, kind of state and other factors.
  • José Valim
    José Valim almost 9 years
    The talk I mentioned covers a routing layer that could be used for blue/green or canary. Again, it depends on the protocol of choice, but you can go from a global entry in distributed Erlang, something using consul, or haproxy for something HTTP based.
  • Papipo
    Papipo almost 9 years
    The service discovery approach makes sense. I guess that I was always thinking on load balancing terms.
  • Jeancarlo
    Jeancarlo almost 7 years
    What about one of the other benefits of micro services like choosing the best language for a specific task. I love elixir, however it is not the best language for every single task. What i mean is one may need for a specific micro service to use a different language instead of elixir. Should it still follow a traditional micro services architecture then?
  • José Valim
    José Valim almost 7 years
    In such cases, you can go with the traditional approach and use gRPC, HTTP+JSON, RabbitMQ, etc for the communication between services in different languages/platforms.
  • Laymer
    Laymer over 5 years
    @JoséValim thanks a lot for the great answer and the YouTube link that is going straight into my "favorites" playlist !