Перейти до вмісту

Erlang

Матеріал з K2 ERP Wiki Ukraine — База знань з автоматизації та санкцій в Україні

SEO title: Erlang — мова для fault-tolerant систем, BEAM VM, OTP, actor model, процесів, message passing і distributed systems SEO description: Erlang — Wiki-стаття про мову програмування Erlang і платформу Erlang/OTP для побудови fault-tolerant, concurrent і distributed systems. Розглянуто BEAM VM, lightweight processes, actor model, message passing, supervisors, supervision trees, gen_server, OTP behaviours, applications, releases, hot code upgrade, distributed Erlang, pattern matching, immutable data, functional programming, telecom, messaging systems, RabbitMQ, WhatsApp, Elixir, тестування, Common Test, EUnit, PropEr, продуктивність, безпеку та практичне використання Erlang у backend, telecom, IoT, real-time і high-availability системах. SEO keywords: Erlang, Erlang/OTP, OTP 28, BEAM, BEAM VM, actor model, lightweight processes, message passing, supervisors, supervision tree, gen_server, gen_statem, gen_event, OTP behaviours, Erlang applications, Erlang releases, hot code upgrade, distributed Erlang, fault tolerance, let it crash, concurrency Erlang, telecom systems, RabbitMQ, Elixir, EUnit, Common Test, PropEr, Erlang backend, distributed systems, high availability, soft real-time systems Alternative to: монолітні сервери без fault tolerance; thread-based concurrency без isolation; ручне відновлення сервісів після падіння; backend без supervision tree; distributed systems без actor model; системи реального часу без process isolation; сервери без hot upgrade; message systems без BEAM; ручне керування потоками й locks


Erlang — це функціональна мова програмування і runtime-платформа для побудови concurrent, distributed і fault-tolerant систем.

Erlang створювався для телекомунікаційних систем, де важливі:

  • висока доступність;
  • обробка великої кількості одночасних з’єднань;
  • відмовостійкість;
  • гаряче оновлення коду;
  • розподілена робота;
  • ізоляція помилок;
  • робота 24/7.

Сьогодні Erlang використовується не тільки в telecom, а й у messaging systems, real-time backend, distributed systems, IoT, фінансових системах, chat-серверах, брокерах повідомлень і high-availability інфраструктурі.

Коротко: Erlang — це мова й платформа для систем, які мають не просто “працювати”, а продовжувати працювати навіть тоді, коли окремі частини падають.

Офіційна сторінка Erlang пояснює, що OTP — це набір Erlang libraries і design principles для middleware, distributed database, взаємодії з іншими мовами, debugging і release handling tools. [1]

Головна ідея

Головна ідея Erlang — будувати системи з багатьох легких ізольованих процесів, які спілкуються повідомленнями.

Замість того щоб боятися кожної помилки, Erlang пропонує підхід:

Let it crash

Це не означає “писати поганий код”. Це означає: якщо процес потрапив у неправильний стан, краще дати йому впасти, а supervisor перезапустить його в чистому стані.

Проста аналогія: Erlang-система схожа на добре організовану команду. Якщо один працівник помилився, керівник не зупиняє всю компанію, а перезапускає саме цю ділянку роботи.

Актуальна версія

Станом на травень 2026 року офіційна сторінка Downloads вказує Erlang/OTP 28.5 як latest version of Erlang/OTP. [2]

Erlang/OTP 28 був випущений 21 травня 2025 року як новий major release з новими можливостями, покращеннями й деякими несумісностями. [3]

Серед помітних новинок OTP 28 офіційний блог виділяє priority messages — opt-in механізм, який дозволяє процесу отримувати деякі urgent messages раніше за звичайні повідомлення в черзі. [4]

Для документації: в Erlang важливо вказувати не просто “Erlang”, а конкретну версію Erlang/OTP: наприклад, OTP 28.5. Поведінка runtime, libraries і tooling може залежати від OTP-релізу.

Erlang і OTP

Erlang — це мова програмування.

OTP — це набір libraries, behaviours, design principles і tooling для побудови production-систем на Erlang.

OTP включає:

  • supervisors;
  • gen_server;
  • gen_statem;
  • applications;
  • releases;
  • logging;
  • distributed tools;
  • release handling;
  • debugging tools;
  • стандартні design patterns.

Тому часто говорять не просто Erlang, а Erlang/OTP.

BEAM VM

BEAM — virtual machine, на якій виконується Erlang-код.

BEAM також виконує інші мови, зокрема Elixir.

BEAM сильна в:

  • lightweight processes;
  • scheduling;
  • message passing;
  • fault isolation;
  • concurrency;
  • soft real-time behaviour;
  • garbage collection per process;
  • distributed Erlang;
  • hot code loading.

BEAM — одна з головних причин, чому Erlang добре підходить для high-concurrency systems.

Actor model

Erlang часто описують через actor model.

У такому підході система складається з незалежних actors/processes.

Кожен process:

  • має власний стан;
  • не ділить пам’ять напряму;
  • отримує messages;
  • обробляє messages послідовно;
  • може створювати інші processes;
  • може падати незалежно від інших.

Це сильно відрізняється від shared-memory threading.

Lightweight processes

Erlang processes — це не операційні системні процеси.

Це легкі процеси всередині BEAM.

Можна створювати тисячі або мільйони Erlang processes, залежно від задачі й ресурсів.

Приклад створення process:

Pid = spawn(fun() ->
    io:format("Hello from process~n")
end).

Process має PID — ідентифікатор процесу.

Message passing

Erlang processes спілкуються через messages.

Відправка повідомлення:

Pid ! {hello, "Erlang"}.

Отримання:

receive
    {hello, Name} ->
        io:format("Hello, ~s~n", [Name])
end.

Message passing допомагає уникати shared mutable state.

Ключова ідея: Erlang не намагається зробити один процес дуже складним. Він дозволяє створити багато маленьких процесів, які спілкуються повідомленнями.

Mailbox

Кожен Erlang process має mailbox — чергу повідомлень.

Коли process отримує message, він може обробити його через receive.

Якщо message не підходить під pattern, він залишається в mailbox.

Це дає гнучкість, але може створити проблему, якщо mailbox росте швидше, ніж process обробляє повідомлення.

Priority messages

У OTP 28 з’явилися priority messages.

Звичайно повідомлення додаються в кінець черги процесу. Priority messages — opt-in механізм, який дозволяє process отримувати певні urgent messages раніше, якщо receiver це підтримує. [5]

Це корисно для систем, де деякі control messages не повинні довго чекати за великою чергою звичайних повідомлень.

Pattern matching

Pattern matching — центральна частина Erlang.

Приклад:

{ok, Value} = {ok, 42}.

Якщо pattern не збігається, буде error.

У function clauses:

status_text(draft) -> "Чернетка";
status_text(paid) -> "Оплачено";
status_text(cancelled) -> "Скасовано".

Pattern matching робить обробку повідомлень і структур дуже природною.

Immutability

Дані в Erlang immutable.

Значення не змінюються після створення.

Наприклад:

X = 10,
Y = X + 5.

X не змінюється. Створюється нове значення Y.

Immutability допомагає:

  • уникати race conditions;
  • спростити reasoning;
  • зробити процеси ізольованими;
  • краще працювати з message passing.

Functional programming

Erlang — функціональна мова.

Вона підтримує:

  • functions;
  • recursion;
  • pattern matching;
  • immutable data;
  • higher-order functions;
  • lists;
  • tuples;
  • maps;
  • anonymous functions;
  • tail recursion.

Але Erlang дуже практичний: його функціональність служить не академічній красі, а побудові надійних систем.

Variables

Змінні в Erlang присвоюються один раз.

Приклад:

Name = "Erlang".

Спроба присвоїти інше значення тій самій змінній не працює як у імперативних мовах.

Це називають single assignment.

Atoms

Atom — іменоване константне значення.

Приклади:

ok
error
draft
paid
cancelled

Atoms часто використовують для status, tags, messages і pattern matching.

Важливо: atoms не збираються garbage collector у звичайному сенсі, тому не можна безконтрольно створювати atoms із зовнішнього input.

Tuples

Tuple — фіксована структура.

Приклад:

{ok, 42}
{error, not_found}
{customer, 10, "Anna"}

У Erlang дуже поширений стиль:

{ok, Result}
{error, Reason}

Це дозволяє явно обробляти успіх і помилку.

Lists

List — базова структура даних.

Приклад:

Numbers = [1, 2, 3, 4].

Pattern matching зі списком:

[Head | Tail] = [1, 2, 3].

Тут:

  • Head буде 1;
  • Tail буде [2,3].

Maps

Map — key-value структура.

Приклад:

User = #{id => 1, name => <<"Anna">>, active => true}.

Доступ:

Name = maps:get(name, User).

Maps корисні для structured data, configs, JSON-like structures і API payloads.

Records

Records — старіший спосіб описати structured data.

Приклад:

-record(customer, {
    id,
    name,
    email
}).

Використання:

Customer = #customer{id = 1, name = "Anna"}.

Records часто зустрічаються в старому Erlang-коді.

Binaries

Binaries використовуються для bytes і binary data.

Приклад:

Data = <<"hello">>.

Binaries важливі для:

  • network protocols;
  • files;
  • binary formats;
  • strings as UTF-8 binaries;
  • performance-sensitive data processing;
  • messaging.

Erlang має потужний binary pattern matching:

<<A:8, B:8, Rest/binary>> = Data.

Strings

Історично string в Erlang — це list of integers.

Приклад:

"hello"

Але для сучасної роботи з текстом і network data часто використовують binaries:

<<"hello">>

Треба розуміти різницю між lists і binaries, бо вона впливає на performance і APIs.

Recursion

Erlang не має класичних loops як у багатьох імперативних мовах.

Замість цього використовується recursion.

Приклад:

sum([]) -> 0;
sum([H | T]) -> H + sum(T).

Для довгих циклів важлива tail recursion.

Tail recursion

Tail recursion — recursion, де recursive call є останньою операцією функції.

Приклад:

sum(List) ->
    sum(List, 0).

sum([], Acc) ->
    Acc;
sum([H | T], Acc) ->
    sum(T, Acc + H).

Tail recursion дозволяє runtime оптимізувати стек.

Modules

Erlang-код організовано в modules.

Приклад:

-module(example).
-export([hello/0]).

hello() ->
    io:format("Hello~n").

Module має ім’я й список exported functions.

Функції ідентифікуються як:

module:function/arity

Наприклад:

example:hello/0

Function arity

Arity — кількість аргументів функції.

У Erlang foo/1 і foo/2 — різні функції.

Приклад:

add(A) -> A + 1.
add(A, B) -> A + B.

Це важливо для exports, callbacks і documentation.

Behaviours

Behaviour — OTP-шаблон для типових процесів.

Основні behaviours:

  • gen_server;
  • gen_statem;
  • gen_event;
  • supervisor;
  • application.

Behaviour визначає callback functions, які module має реалізувати.

Це дає стандартну структуру для production-процесів.

gen_server

gen_server — generic server behaviour.

Він використовується для процесів, які мають state і обробляють requests/messages.

Офіційна документація gen_server пояснює, що gen_server може створювати process як частину supervision tree через start_link, а process викликає Module:init/1 для ініціалізації. [6]

Типові callbacks:

  • init/1;
  • handle_call/3;
  • handle_cast/2;
  • handle_info/2;
  • terminate/2;
  • code_change/3.

call і cast

У gen_server є два типові способи взаємодії:

  • call — синхронний request із відповіддю;
  • cast — асинхронне повідомлення без очікування відповіді.

Приклад ідеї:

gen_server:call(Server, get_state).
gen_server:cast(Server, {set_value, 42}).

call зручно використовувати, коли потрібна відповідь.

cast — коли потрібно просто надіслати команду.

gen_statem

gen_statem — behaviour для state machines.

Він корисний, коли процес має чіткі стани й переходи між ними.

Сценарії:

  • protocols;
  • connection lifecycle;
  • payment workflow;
  • device states;
  • session management;
  • telecom flows.

gen_statem часто кращий за gen_server, коли логіка справді є state machine.

supervisor

Supervisor — процес, який контролює child processes.

Офіційна документація supervisor behavior описує supervisor як process, що supervises child processes; child process може бути іншим supervisor або worker process, зазвичай реалізованим через gen_server, gen_statem або gen_event. [7]

Supervisor може перезапускати child process, якщо той падає.

Supervision tree

Supervision tree — дерево supervisors і workers.

Приклад ідеї:

Application Supervisor
├── Database Worker
├── HTTP Listener
└── Session Supervisor
    ├── Session Worker 1
    ├── Session Worker 2
    └── Session Worker 3

Supervision tree — основа Erlang fault tolerance.

Головна сила OTP: ви не просто пишете процеси. Ви описуєте, хто за ким стежить, що робити після падіння, як перезапускати частини системи й де проходять межі відмови.

Restart strategies

Supervisors мають restart strategies.

Типові стратегії:

  • one_for_one;
  • one_for_all;
  • rest_for_one;
  • simple_one_for_one historically / dynamic supervisors у новіших підходах.

Сенс:

  • перезапустити тільки process, що впав;
  • перезапустити всіх;
  • перезапустити process і тих, хто залежить від нього.

Вибір restart strategy — важлива архітектурна частина.

Let it crash

Let it crash — філософія Erlang.

Ідея:

  • не ловити кожну помилку локально;
  • не залишати процес у невідомому стані;
  • дати процесу впасти;
  • supervisor перезапустить його;
  • система продовжить працювати.

Цей підхід працює тільки тоді, коли правильно побудовані supervision trees, state boundaries і recovery strategy.

Fault tolerance

Fault tolerance — здатність системи продовжувати роботу після часткових помилок.

Erlang допомагає через:

  • isolated processes;
  • supervisors;
  • links;
  • monitors;
  • message passing;
  • supervision trees;
  • crash recovery;
  • distribution;
  • process-per-connection style;
  • hot code loading.

Але fault tolerance не виникає автоматично. Її потрібно проектувати.

Processes можуть бути linked або monitored.

Link створює двосторонній зв’язок: якщо один process падає, сигнал отримує інший.

Monitor дозволяє одному process спостерігати за іншим без взаємного зв’язку.

Це основа для supervisor-like behaviour і fault detection.

Applications

OTP application — логічна одиниця Erlang-системи.

Application може мати:

  • application callback module;
  • supervision tree;
  • config;
  • dependencies;
  • workers;
  • release metadata.

OTP application — не обов’язково “додаток” у звичному UI-сенсі. Це компонент системи.

Releases

Erlang release — зібрана система для deployment.

Release може включати:

  • Erlang runtime;
  • applications;
  • configuration;
  • boot scripts;
  • release metadata;
  • versioning;
  • upgrade instructions.

Releases важливі для production, бо Erlang-система часто складається з багатьох OTP applications.

Hot code upgrade

Erlang підтримує hot code loading і hot upgrade.

Ідея: можна оновити код без повної зупинки системи.

Це важливо для telecom і high-availability systems.

Але hot upgrades складні:

  • потрібно думати про state migration;
  • old і new code можуть співіснувати;
  • callbacks code_change/3 мають бути правильними;
  • release handling має бути протестований.

У багатьох сучасних deployment-процесах замість hot upgrade використовують rolling deploy або blue-green deploy, але сама можливість залишається важливою частиною Erlang-історії.

Distributed Erlang

Distributed Erlang дозволяє Erlang nodes спілкуватися між собою.

Node може надсилати messages process на іншому node майже так само, як локальному process.

Це зручно для distributed systems, але потребує обережності:

  • network partitions;
  • security;
  • node cookies;
  • latency;
  • cluster topology;
  • observability;
  • failure detection.

Erlang nodes використовують cookie для автентифікації між nodes.

Якщо cookies не збігаються, nodes не з’єднаються.

Cookie потрібно зберігати як секрет.

Не можна випадково публікувати Erlang cookie в репозиторії або logs.

Mnesia

Mnesia — distributed database management system, що входить в OTP.

Вона історично корисна для Erlang-систем, але її потрібно використовувати обережно.

Mnesia може бути доречною для:

  • distributed Erlang applications;
  • metadata;
  • telecom-like systems;
  • small/medium distributed state;
  • systems tightly integrated with Erlang nodes.

Для багатьох сучасних web/backend систем частіше використовують PostgreSQL, Redis, Kafka, RabbitMQ або інші спеціалізовані сховища.

ETS

ETS — Erlang Term Storage.

ETS — in-memory tables для зберігання Erlang terms.

ETS корисний для:

  • caches;
  • lookup tables;
  • shared read-heavy data;
  • session data;
  • counters;
  • local state.

ETS не є заміною persistent database, але дуже корисний для runtime state.

DETS

DETS — disk-based term storage.

DETS схожий на disk-based варіант ETS, але має інші обмеження й performance characteristics.

Для production persistence потрібно обережно оцінювати, чи DETS справді підходить.

Ports і NIFs

Erlang може взаємодіяти з зовнішнім кодом через ports і NIFs.

Port — безпечніший спосіб спілкування із зовнішньою програмою як окремим OS process.

NIF — Native Implemented Function, код на C/C++, який викликається всередині BEAM.

NIF може бути швидким, але небезпечним: поганий NIF може заблокувати або зламати VM.

Важливо: NIF — це місце, де Erlang може втратити частину своєї fault tolerance. Помилка в native code може вплинути на всю VM, а не лише на один Erlang process.

Синтаксис Erlang

Приклад модуля:

-module(greeter).
-export([hello/1]).

hello(Name) ->
    io:format("Hello, ~s~n", [Name]).

Компіляція в shell:

c(greeter).
greeter:hello("Erlang").

Erlang syntax може здаватися незвичним через:

  • крапки в кінці function definitions;
  • коми між expressions;
  • крапку з комою між clauses;
  • atoms;
  • pattern matching;
  • single assignment.

Erlang shell

Erlang shell запускається командою:

erl

Приклад:

1> 2 + 3.
5
2> self().
<0.82.0>

Shell корисний для:

  • навчання;
  • testing small functions;
  • process experiments;
  • debugging;
  • runtime inspection.

Rebar3

rebar3 — популярний build tool для Erlang.

Він використовується для:

  • створення проєктів;
  • builds;
  • tests;
  • dependencies;
  • releases;
  • plugins;
  • Common Test;
  • Dialyzer integration.

Типові команди:

rebar3 new app my_app
rebar3 compile
rebar3 eunit
rebar3 ct
rebar3 release

Rebar3 — стандартний вибір для багатьох Erlang-проєктів.

Hex.pm

Hex.pm — package manager ecosystem для Erlang/Elixir.

Використовується для dependencies.

Перед додаванням dependency потрібно перевіряти:

  • підтримку;
  • ліцензію;
  • сумісність з OTP;
  • активність;
  • транзитивні залежності;
  • security issues.

Dialyzer

Dialyzer — static analysis tool для Erlang.

Він знаходить:

  • type discrepancies;
  • unreachable code;
  • pattern matching issues;
  • potential bugs.

Dialyzer використовує success typing, а не класичну повну статичну типізацію.

Це означає, що він часто знаходить реальні проблеми, але не вимагає описувати всі типи наперед.

Typespecs

Erlang підтримує typespecs.

Приклад:

-spec add(integer(), integer()) -> integer().
add(A, B) ->
    A + B.

Typespecs корисні для:

  • документації;
  • Dialyzer;
  • API contracts;
  • code navigation;
  • maintenance.

EUnit

EUnit — unit testing framework для Erlang.

Приклад:

add_test() ->
    ?assertEqual(5, add(2, 3)).

EUnit корисний для маленьких unit tests.

Common Test

Common Test — testing framework для більших test suites.

Він корисний для:

  • integration tests;
  • system tests;
  • protocol tests;
  • distributed tests;
  • telecom-style testing;
  • complex setup/teardown.

Common Test часто використовується в серйозних Erlang/OTP проєктах.

PropEr

PropEr — property-based testing tool для Erlang.

Property-based testing перевіряє не один приклад, а властивості програми на багатьох generated inputs.

Це добре підходить для:

  • protocols;
  • parsers;
  • state machines;
  • business rules;
  • serialization;
  • distributed logic.

Erlang і Elixir

Elixir — сучасна мова на BEAM VM.

Вона використовує Erlang/OTP ecosystem, але має інший синтаксис і tooling.

Порівняння:

Мова Особливість
Erlang оригінальна мова OTP, telecom roots, дуже стабільна
Elixir сучасніший синтаксис, Mix tooling, Phoenix web framework, ширша популярність у web

Elixir не замінює Erlang повністю. Багато core libraries і OTP написані Erlang.

Erlang і RabbitMQ

RabbitMQ — популярний message broker, написаний на Erlang.

Це один із найвідоміших прикладів практичного використання Erlang/OTP.

RabbitMQ використовує сильні сторони Erlang:

  • concurrency;
  • fault tolerance;
  • process isolation;
  • distributed behaviour;
  • message-oriented architecture.

Erlang і WhatsApp

WhatsApp історично часто згадується як приклад системи, яка використовувала Erlang для масштабної messaging infrastructure.

Цей приклад важливий не як “магічна реклама Erlang”, а як демонстрація того, що Erlang добре підходить для великої кількості одночасних з’єднань і messaging.

Erlang і telecom

Erlang народився в telecom.

Telecom systems потребували:

  • 24/7 availability;
  • soft real-time;
  • hot upgrade;
  • fault isolation;
  • distributed operation;
  • call/session management;
  • supervision;
  • message passing.

Саме ці вимоги сформували Erlang/OTP.

Soft real-time

Soft real-time означає, що система має реагувати швидко й стабільно, але не гарантує жорстких real-time deadlines як hard real-time systems.

Erlang добре підходить для soft real-time:

  • messaging;
  • telecom sessions;
  • chat;
  • presence;
  • notification systems;
  • control planes.

Але для hard real-time embedded control Erlang зазвичай не є першим вибором.

Erlang у backend

Erlang можна використовувати для backend-сервісів.

Сценарії:

  • messaging backend;
  • chat server;
  • presence system;
  • notification service;
  • IoT gateway;
  • protocol server;
  • multiplayer coordination;
  • distributed control plane;
  • queue workers;
  • real-time systems.

Для класичного CRUD API Erlang теж можливий, але часто Elixir/Phoenix або інші мови можуть бути зручнішими для команди.

Erlang і Web

Erlang має web libraries/frameworks:

  • Cowboy;
  • Ranch;
  • Elli;
  • Webmachine historically;
  • Zotonic;
  • ChicagoBoss historically.

Cowboy часто використовується для HTTP/WebSocket servers.

Erlang web stack менш mainstream, ніж Node.js, Python, Go, Java або C#, але сильний у concurrent connection handling.

Erlang і distributed systems

Erlang добре підходить для distributed systems, але не робить їх автоматично простими.

Потрібно думати про:

  • network partitions;
  • consistency;
  • message ordering;
  • retries;
  • duplicate messages;
  • idempotency;
  • cluster membership;
  • observability;
  • backpressure;
  • failure domains.

Erlang дає інструменти, але архітектурні проблеми distributed systems залишаються.

Backpressure

Backpressure — механізм, який не дозволяє producer надсилати більше повідомлень, ніж consumer може обробити.

В Erlang backpressure важливий, бо mailbox process може рости.

Без backpressure можливі:

  • memory growth;
  • latency;
  • process overload;
  • node instability.

Потрібно проектувати flow control.

Observability

Для Erlang production-систем потрібні:

  • logs;
  • metrics;
  • tracing;
  • process inspection;
  • crash reports;
  • supervision tree visibility;
  • mailbox length monitoring;
  • memory monitoring;
  • scheduler utilization;
  • distributed node health.

Інструменти можуть включати:

  • observer;
  • recon;
  • telemetry;
  • OpenTelemetry;
  • logs;
  • custom metrics;
  • VM statistics.

Observer

Observer — Erlang GUI tool для перегляду runtime-системи.

Він може показувати:

  • processes;
  • applications;
  • memory;
  • scheduler info;
  • ETS tables;
  • supervision trees.

Observer корисний для локального аналізу й debugging.

Performance

Erlang оптимізований для concurrency і availability, а не для raw CPU performance у стилі C/Rust.

На performance впливають:

  • кількість processes;
  • mailbox sizes;
  • message copying;
  • binary handling;
  • scheduler utilization;
  • garbage collection;
  • ETS usage;
  • NIFs;
  • distribution overhead;
  • serialization;
  • supervision restarts.

Для CPU-heavy задач Erlang може бути не найкращим вибором.

Для high-concurrency I/O systems — часто дуже сильний.

Garbage collection

У BEAM garbage collection зазвичай process-local.

Це допомагає ізолювати паузи: GC одного process не мусить зупиняти всю VM.

Це одна з причин, чому Erlang добре підходить для систем із багатьма одночасними процесами.

Безпека

Erlang-системи потребують безпеки так само, як інші backend-системи.

Потрібно контролювати:

  • distributed Erlang cookie;
  • TLS;
  • input validation;
  • authentication;
  • authorization;
  • secrets;
  • dependency security;
  • NIF risks;
  • exposed ports;
  • node connectivity;
  • logging;
  • remote shell access;
  • configuration;
  • cluster access.

Особливо уважно потрібно ставитися до distributed Erlang у відкритих мережах.

Erlang cookie — секрет для node communication.

Не можна:

  • комітити cookie в Git;
  • використовувати однаковий cookie для всіх середовищ;
  • писати cookie в logs;
  • відкривати distributed Erlang ports у публічний інтернет без захисту.

Для production потрібні network isolation, firewall, secrets management і TLS, якщо доречно.

Erlang і Python / Go / Java / C#

Порівняння:

Мова Сильні сторони
Erlang fault tolerance, concurrency, messaging, distributed systems, OTP
Go простий backend, cloud-native, single binary, performance
Java enterprise ecosystem, JVM, Spring, tooling
C# .NET, ASP.NET Core, Microsoft ecosystem, enterprise
Python scripting, data, AI, automation, швидкий старт

Erlang найсильніший там, де потрібні concurrency, fault tolerance і long-running systems.

Erlang і Haskell

Erlang і Haskell обидві функціональні, але мають різну філософію.

Мова Фокус
Erlang fault-tolerant distributed runtime, processes, message passing, OTP
Haskell чисті функції, сильна type system, lazy evaluation, математичне моделювання

Erlang практичніший для resilient runtime systems.

Haskell сильніший у type-driven correctness і pure functional modeling.

Erlang у бізнесі

Erlang може бути корисним у бізнесі, якщо потрібні:

  • messaging;
  • telecom;
  • real-time backend;
  • high availability;
  • distributed systems;
  • IoT gateways;
  • notification services;
  • chat;
  • queue systems;
  • fault-tolerant services;
  • systems that run 24/7.

Але Erlang має менший ринок розробників, ніж mainstream backend-мови.

Erlang і ERP-системи

Erlang не є ERP-системою.

Він не веде облік, не проводить документи й не керує складом сам по собі.

У контексті K2 ERP Erlang може бути корисним опосередковано:

  • message broker integration;
  • real-time notification service;
  • high-availability gateway;
  • concurrent session service;
  • IoT/telemetry ingestion;
  • distributed background processing;
  • fault-tolerant integration layer;
  • service, де важлива supervision і self-healing.

Але основну бізнес-логіку ERP зазвичай варто писати в основному стеку системи. Erlang доречний тоді, коли його fault-tolerance модель справді потрібна.

Erlang і API

Erlang може створювати HTTP API через Cowboy або інші libraries.

Приклад сценарію:

  • HTTP listener приймає request;
  • process обробляє session;
  • gen_server керує state;
  • supervisor перезапускає workers;
  • response повертається client.

Erlang API особливо доречні, коли багато одночасних connections або WebSocket sessions.

Erlang і тестування коду

Для тестування коду в Erlang варто поєднувати:

  • EUnit для unit tests;
  • Common Test для integration/system tests;
  • PropEr для property-based tests;
  • Dialyzer для static analysis;
  • release tests;
  • distributed tests;
  • fault injection;
  • supervisor restart tests.

Для fault-tolerant систем важливо тестувати не тільки “happy path”, а й падіння processes, timeouts, повтори й network issues.

Коли Erlang особливо корисний

Erlang особливо корисний для:

  • telecom;
  • messaging;
  • chat;
  • notification systems;
  • real-time backend;
  • distributed systems;
  • high-availability services;
  • fault-tolerant systems;
  • process-per-connection architectures;
  • protocol servers;
  • RabbitMQ-like systems;
  • IoT gateways;
  • systems that must run continuously.

Коли Erlang може бути невдалим вибором

Erlang може бути невдалим вибором, якщо:

  • потрібен простий CRUD;
  • команда не знає Erlang/OTP;
  • потрібен великий ринок розробників;
  • потрібен CPU-heavy numerical code;
  • потрібна AI/data science ecosystem;
  • потрібен mobile app;
  • потрібен modern mainstream web stack;
  • fault tolerance не є важливою вимогою;
  • система легко вирішується Go/C#/Java/Python;
  • немає плану observability і OTP architecture.

Типові помилки в Erlang

Поширені помилки:

  • писати Erlang як імперативну мову;
  • створювати processes без supervision;
  • ігнорувати mailbox growth;
  • використовувати gen_server для всього;
  • ловити всі errors замість правильної supervision strategy;
  • створювати atoms із зовнішнього input;
  • використовувати NIF без розуміння ризиків;
  • не контролювати distributed Erlang security;
  • не тестувати restart scenarios;
  • не використовувати Dialyzer;
  • не документувати message formats;
  • не думати про backpressure;
  • запускати distributed nodes без network/security design.

Хороші практики

Під час роботи з Erlang варто:

  1. Проектувати supervision tree з самого початку.
  2. Використовувати OTP behaviours.
  3. Не створювати процеси без зрозумілого lifecycle.
  4. Стежити за mailbox length.
  5. Описувати message formats.
  6. Не створювати atoms із user input.
  7. Використовувати gen_server для stateful servers, але не для всього.
  8. Використовувати gen_statem для state machines.
  9. Додавати EUnit і Common Test.
  10. Використовувати Dialyzer і typespecs.
  11. Тестувати crash/restart scenarios.
  12. Думати про backpressure.
  13. Захищати Erlang cookie.
  14. Обережно використовувати NIFs.
  15. Моніторити BEAM runtime metrics.

Практичний висновок

Erlang — це не просто функціональна мова. Це платформа для побудови систем, які мають жити довго, обробляти багато одночасних подій і відновлюватися після помилок.

Сильні сторони:

  • BEAM VM;
  • lightweight processes;
  • message passing;
  • actor model;
  • OTP;
  • supervisors;
  • supervision trees;
  • gen_server;
  • gen_statem;
  • fault tolerance;
  • distributed Erlang;
  • hot code loading;
  • telecom heritage;
  • soft real-time systems;
  • RabbitMQ-like workloads.

Обмеження:

  • менший ринок розробників;
  • незвичний синтаксис;
  • менша mainstream web ecosystem;
  • не найкращий вибір для CPU-heavy задач;
  • distributed systems усе одно складні;
  • потрібна дисципліна OTP architecture;
  • NIFs можуть зламати fault tolerance;
  • observability і backpressure потрібно проектувати.

Erlang найкраще використовувати там, де головна вимога — не просто виконати код, а побудувати систему, яка продовжує працювати під навантаженням, при помилках і в distributed environment.

Пояснення термінів

  • Erlang — функціональна мова й runtime-платформа для concurrent і fault-tolerant systems.
  • OTP — набір Erlang libraries, behaviours і design principles для production systems.
  • BEAM — virtual machine для Erlang і Elixir.
  • Actor model — модель, де незалежні actors/processes спілкуються messages.
  • Process — легкий Erlang process у BEAM, не OS process.
  • PID — process identifier.
  • Message passing — передача повідомлень між processes.
  • Mailbox — черга повідомлень процесу.
  • Priority messages — механізм OTP 28 для пріоритетних повідомлень.
  • Pattern matching — зіставлення значень із шаблонами.
  • Atom — іменована константа.
  • Tuple — фіксована структура значень.
  • Map — key-value структура.
  • Binary — binary data у Erlang.
  • Arity — кількість аргументів функції.
  • Behaviour — OTP-шаблон із callbacks.
  • gen_server — generic server behaviour.
  • gen_statem — behaviour для state machines.
  • Supervisor — process, що контролює child processes.
  • Supervision tree — дерево supervisors і workers.
  • Let it crash — філософія fault tolerance через контрольовані падіння й перезапуски.
  • Application — OTP application, логічна одиниця системи.
  • Release — зібрана Erlang/OTP-система для deployment.
  • Hot code upgrade — оновлення коду без повної зупинки системи.
  • Distributed Erlang — взаємодія Erlang nodes у distributed system.
  • Mnesia — distributed database в OTP.
  • ETS — in-memory storage для Erlang terms.
  • NIF — Native Implemented Function.
  • Dialyzer — static analysis tool для Erlang.
  • EUnit — unit testing framework.
  • Common Test — framework для більших test suites.
  • PropEr — property-based testing tool.
  • Rebar3 — build tool для Erlang.
  • Hex.pm — package ecosystem для Erlang/Elixir.

Дивіться також

Джерела