Złożone drzewa nadzoru
Projektuj i implementuj złożone, zagnieżdżone hierarchie nadzoru, aby skutecznie zarządzać zależnościami i domenami awarii.
Złożone drzewa nadzoru to bezpłatna lekcja Erlang OTP: Distributed & Fault-Tolerant Systems Programming na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Erlang OTP: Distributed & Fault-Tolerant Systems Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Erlang OTP: Distributed & Fault-Tolerant Systems Programming zawiera 4 lekcji w sumie.
Części tej lekcji nie zostały jeszcze przetłumaczone i są wyświetlane po angielsku.
Supervision Trees: The Basics
In Erlang, supervisors are special processes that oversee other processes, called children. If a child process crashes, the supervisor can restart it, ensuring fault tolerance.
A supervision tree is formed when a supervisor itself becomes a child of another supervisor. This creates a hierarchy, much like an organizational chart.
Why Complex Trees?
As applications grow, a single supervisor isn't enough. Complex supervision trees allow us to:
- Manage dependencies: Group related processes so they start and stop together.
- Isolate failures: A crash in one part of the tree won't necessarily bring down unrelated parts.
- Improve modularity: Each supervisor can be responsible for a specific subsystem, making the application easier to understand and maintain.
Child Spec: Worker vs. Supervisor
Every process a supervisor manages is defined by a child specification. A child spec tells the supervisor how to start, restart, and shut down the child process.
Crucially, a child can be of two types:
worker: A regular process (like agen_server) that performs application logic.supervisor: Another supervisor process, forming a nested level in the tree.
The Worker: my_worker_module
Let's start with a simple worker process. This gen_server will be the leaf node in our supervision tree. It just prints messages when it starts or receives calls.
-module(my_worker_module).
-behaviour(gen_server).
-export([start_link/1, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
start_link(Id) ->
gen_server:start_link(?MODULE, Id, []).
init(Id) ->
io:format("Worker ~p starting...~n", [Id]),
{ok, Id}.
handle_call(Req, _From, State) ->
io:format("Worker ~p received call: ~p~n", [State, Req]),
{reply, ok, State}.
handle_cast(Msg, State) ->
io:format("Worker ~p received cast: ~p~n", [State, Msg]),
{noreply, State}.
handle_info(Msg, State) ->
io:format("Worker ~p received info: ~p~n", [State, Msg]),
{noreply, State}.
terminate(_Reason, State) ->
io:format("Worker ~p terminating...~n", [State]).
code_change(_OldVsn, State, _Extra) ->
{ok, State}.The Nested Supervisor: my_nested_sup
This supervisor will manage our my_worker_module processes. It defines two workers, 'WorkerA' and 'WorkerB', each with slightly different restart strategies.
Notice how its child_specs define type => worker.
-module(my_nested_sup).
-behaviour(supervisor).
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
SupFlags = #{
strategy => one_for_one,
intensity => 10,
period => 1
},
ChildSpecs = [
#{
id => worker_A,
start => {my_worker_module, start_link, ["WorkerA"]},
type => worker,
restart => permanent,
shutdown => 5000,
modules => [my_worker_module]
},
#{
id => worker_B,
start => {my_worker_module, start_link, ["WorkerB"]},
type => worker,
restart => transient,
shutdown => 2000,
modules => [my_worker_module]
}
],
{ok, {SupFlags, ChildSpecs}}.The Top-Level Supervisor: my_app_sup
This is the root of our complex tree. It supervises my_nested_sup. Notice that its child_spec for my_nested_sup has type => supervisor. This is how you build nested trees!
-module(my_app_sup).
-behaviour(supervisor).
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
SupFlags = #{
strategy => one_for_one,
intensity => 10,
period => 1
},
ChildSpecs = [
#{
id => my_nested_sup_child,
start => {my_nested_sup, start_link, []},
type => supervisor,
restart => permanent,
shutdown => infinity,
modules => [my_nested_sup]
}
],
{ok, {SupFlags, ChildSpecs}}.Running the Complex Tree
To see our tree in action, compile all three modules (my_worker_module.erl, my_nested_sup.erl, my_app_sup.erl) and then start the top-level supervisor. You'll see the workers start up!
You can use supervisor:which_children(PidOrName) to inspect the tree.
% In the Erlang shell:
c(my_worker_module).
c(my_nested_sup).
c(my_app_sup).
{ok, MySupPid} = my_app_sup:start_link().
% Check the children of the top-level supervisor:
supervisor:which_children(MySupPid).
% Find the nested supervisor's PID:
{_, NestedSupPid, _, _} = lists:keyfind(my_nested_sup_child, 1, supervisor:which_children(MySupPid)).
% Check the children of the nested supervisor:
supervisor:which_children(NestedSupPid).Visualizing the Hierarchy
Our complex supervision tree looks like this:
my_app_sup(top-level supervisor)- supervises
my_nested_sup(a child supervisor)- supervises
worker_A(a worker process) - supervises
worker_B(a worker process)
- supervises
- supervises
This structure ensures that if worker_A crashes, only my_nested_sup handles it. If my_nested_sup itself crashes, my_app_sup will restart it, bringing worker_A and worker_B back to life.
Benefits of Complex Trees
Complex supervision trees are a cornerstone of building robust Erlang applications. They provide:
- Fault Isolation: Failures are contained to specific branches.
- Logical Grouping: Components with related functions are supervised together.
- Clear Responsibilities: Each supervisor has a well-defined set of processes it's responsible for.
- Scalability: Easier to add or remove subsystems without disrupting the entire application.
Quick Check: Supervision Trees
Which of the following are key benefits of using complex (nested) supervision trees in Erlang?
Recap: Complex Supervision
Today, we explored complex supervision trees in Erlang. We learned that supervisors can manage other supervisors, creating nested hierarchies. This powerful pattern enables robust fault tolerance by isolating failures, managing dependencies, and improving the modularity of your applications. By defining child specs with type => supervisor, you can build intricate and resilient Erlang systems.
Często zadawane pytania
Czy lekcja „Złożone drzewa nadzoru” jest bezpłatna?
Tak — pełny tekst „Złożone drzewa nadzoru” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Erlang OTP: Distributed & Fault-Tolerant Systems Programming, przejdź na CoddyKit PRO. Kurs Erlang OTP: Distributed & Fault-Tolerant Systems Programming zawiera 4 lekcji w sumie.
Co nauczysz się w „Złożone drzewa nadzoru”?
Projektuj i implementuj złożone, zagnieżdżone hierarchie nadzoru, aby skutecznie zarządzać zależnościami i domenami awarii. Ćwiczysz Erlang OTP: Distributed & Fault-Tolerant Systems Programming z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Erlang OTP: Distributed & Fault-Tolerant Systems Programming?
Nie wymagamy żadnego doświadczenia. Erlang OTP: Distributed & Fault-Tolerant Systems Programming w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Złożone drzewa nadzoru”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Erlang OTP: Distributed & Fault-Tolerant Systems Programming?
Tak. Każda lekcja Erlang OTP: Distributed & Fault-Tolerant Systems Programming zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Złożone drzewa nadzoru
- Dynamiczne zarządzanie procesami
- Zaawansowane strategie ponownego uruchamiania
- Mosty supervisorów i mieszane hierarchie procesów