Penyelia dan Struktur Aplikasi
Reka bentuk aplikasi yang berdaya tahan menggunakan penyelia untuk memantau dan memulakan semula proses bagi memastikan toleransi terhadap kegagalan.
Penyelia dan Struktur Aplikasi ialah pelajaran Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala merangkumi sejumlah 4 pelajaran.
Membina Sistem yang Tahan Lasak
Dalam aplikasi serentak, perkara boleh berlaku dengan tidak dijangka. Proses mungkin terhenti akibat ralat yang tidak dijangka atau isu luaran.
Toleransi kesalahan ialah keupayaan sistem untuk terus beroperasi walaupun komponennya gagal. Elixir mengamalkan falsafah “biarkan ia terhenti”, iaitu bukannya cuba mencegah setiap kegagalan, Elixir memberi tumpuan kepada pemulihan daripadanya dengan baik.
Penjaga Proses
Di sinilah Penyelia berperanan! Penyelia ialah sejenis proses khas yang direka untuk memantau proses lain (“anaknya”).
- Jika proses anak terhenti akibat ralat, penyelia memulakannya semula secara automatik.
- Ini memastikan aplikasi anda kekal stabil dan tersedia.
- Penyelia menjadi tulang belakang aplikasi Elixir yang tahan terhadap kegagalan.
Penyelia Pertama Anda
Mari takrifkan modul penyelia yang mudah. Modul ini menggunakan tingkah laku Supervisor, sama seperti cara GenServer menggunakan tingkah laku GenServer.
Panggil balik init/1 ialah tempat anda mentakrifkan anak yang akan diselia serta strategi mula semulanya.
defmodule MySupervisor do
use Supervisor
def start_link(init_arg) do
Supervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
end
@impl true
def init(_init_arg) do
# No children yet, just the supervisor itself
children = []
Supervisor.init(children, strategy: :one_for_one)
end
end
# --- Main execution part ---
# This simulates starting the supervisor and checking its status.
# In a real app, this would be part of an Application's start/2.
IO.puts("Attempting to start MySupervisor...")
{:ok, supervisor_pid} = MySupervisor.start_link([])
IO.puts("MySupervisor started with PID: #{inspect(supervisor_pid)}")
# Check if the supervisor process is alive
if Process.alive?(supervisor_pid) do
IO.puts("Supervisor is alive!")
else
IO.puts("Supervisor is NOT alive!")
endMemahami Strategi Penyeliaan
Penyelia mempunyai strategi yang berbeza untuk mengendalikan kegagalan proses anak:
:one_for_one: Hanya memulakan semula anak yang terhenti akibat ralat. Ini ialah pilihan lalai dan yang paling lazim.:one_for_all: Jika mana-mana anak terhenti akibat ralat, semua anak lain ditamatkan dan kemudian semua anak dimulakan semula.:rest_for_one: Jika sesuatu anak terhenti akibat ralat, anak itu dan semua anak yang dimulakan *selepas*nya ditamatkan lalu dimulakan semula.
Pemilihan strategi yang betul bergantung pada kebergantungan antara proses anda.
Menambah Anak yang Diselia
Untuk menjadikan penyelia berguna, ia memerlukan anak! Anda mentakrifkan anak menggunakan Supervisor.child_spec/2, yang memberitahu penyelia cara memulakan dan mengurus proses.
Di sini, kita mentakrifkan GenServer MyWorker yang mudah dan menambahkannya sebagai anak kepada penyelia kita.
defmodule MyWorker do
use GenServer
def start_link(_opts) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
@impl true
def init(:ok) do
IO.puts("MyWorker started!")
{:ok, %{}}
end
@impl true
def handle_call(:crash, _from, state) do
IO.puts("MyWorker is crashing!")
exit(:bad_state) # Simulate a crash
{:reply, :ok, state} # This line won't be reached
end
end
defmodule MySupervisorWithWorker do
use Supervisor
def start_link(init_arg) do
Supervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
end
@impl true
def init(_init_arg) do
children = [
# Define our worker as a child process
Supervisor.child_spec(MyWorker, id: MyWorker)
]
Supervisor.init(children, strategy: :one_for_one)
end
end
# --- Main execution part ---
IO.puts("Starting supervisor with worker...")
{:ok, supervisor_pid} = MySupervisorWithWorker.start_link([])
IO.puts("Supervisor PID: #{inspect(supervisor_pid)}")
# Get the worker's PID
worker_pid = Process.whereis(MyWorker)
IO.puts("Initial MyWorker PID: #{inspect(worker_pid)}")
if Process.alive?(worker_pid) do
IO.puts("Worker is alive and supervised.")
else
IO.puts("Worker did not start correctly.")
endToleransi Kesalahan dalam Tindakan
Sekarang, mari lihat penyelia dalam tindakan! Kita akan sengaja menghentikan proses MyWorker akibat ralat, dan penyelia akan memulakannya semula secara automatik.
Perhatikan bahawa ID Proses (PID) pekerja berubah, menandakan proses baharu telah dicipta.
defmodule MyWorker do
use GenServer
def start_link(_opts) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
@impl true
def init(:ok) do
IO.puts("MyWorker started!")
{:ok, %{}}
end
@impl true
def handle_call(:crash, _from, state) do
IO.puts("MyWorker is crashing!")
exit(:bad_state) # Simulate a crash
{:reply, :ok, state} # This line won't be reached
end
def crash_it do
GenServer.call(__MODULE__, :crash)
end
end
defmodule MySupervisorWithWorker do
use Supervisor
def start_link(init_arg) do
Supervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
end
@impl true
def init(_init_arg) do
children = [
Supervisor.child_spec(MyWorker, id: MyWorker)
]
Supervisor.init(children, strategy: :one_for_one)
end
end
# --- Main execution part ---
IO.puts("Starting supervisor with worker...")
{:ok, _supervisor_pid} = MySupervisorWithWorker.start_link([])
worker_pid_before_crash = Process.whereis(MyWorker)
IO.puts("Worker PID before crash: #{inspect(worker_pid_before_crash)}")
# Crash the worker
IO.puts("Attempting to crash the worker...")
MyWorker.crash_it()
:timer.sleep(100) # Give supervisor a moment to restart
worker_pid_after_crash = Process.whereis(MyWorker)
IO.puts("Worker PID after crash: #{inspect(worker_pid_after_crash)}")
if worker_pid_before_crash != worker_pid_after_crash && Process.alive?(worker_pid_after_crash) do
IO.puts("Worker was restarted by the supervisor! New PID detected.")
else
IO.puts("Worker was NOT restarted, or PID remained the same (unexpected).")
endAplikasi Elixir: Tahap Teratas
Walaupun penyelia mengurus proses individu, Aplikasi Elixir ialah unit kod dan proses tahap teratas dalam sistem Elixir.
Ia menyediakan cara berstruktur untuk:
- Mengumpulkan modul dan proses yang berkaitan.
- Menentukan cara sistem anda dimulakan dan dimatikan.
- Mengurus konfigurasi dan kebergantungan.
Tingkah Laku `Application`
Setiap aplikasi Elixir biasanya mempunyai modul aplikasi utama yang menggunakan use Application.
Panggil balik yang paling penting ialah start/2, yang dipanggil apabila aplikasi anda bermula. Di sinilah anda biasanya memulakan penyelia tahap teratas, yang kemudiannya memulakan semua proses lain dalam sistem anda secara rekursif.
defmodule MyApp.Application do
use Application
# This is the entry point for your application.
# It starts the top-level supervisor.
@impl true
def start(_type, _args) do
children = [
# In a real app, you'd start your main supervisor here.
# For example: Supervisor.child_spec(MySupervisorWithWorker, id: MySupervisorWithWorker)
]
# Start a supervisor that will supervise other processes/supervisors
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
end
# --- Main execution part ---
# This part simulates how an application would be started.
# In a real Mix project, 'mix run --no-halt' would call MyApp.Application.start/2
IO.puts("Simulating application start...")
{:ok, pid} = MyApp.Application.start(:normal, [])
IO.puts("Application top-level supervisor started with PID: #{inspect(pid)}")
if Process.alive?(pid) do
IO.puts("Application supervisor is active.")
else
IO.puts("Application supervisor failed to start.")
endPepohon Penyeliaan Berhierarki
Untuk aplikasi yang kompleks, anda biasanya tidak hanya mempunyai satu penyelia. Anda mencipta pepohon penyeliaan, yang membolehkan penyelia menyelia penyelia lain.
- Ini membolehkan anda menyusun aplikasi kepada unit logik.
- Bahagian yang berbeza dalam sistem anda boleh menggunakan strategi mula semula yang berbeza.
- Jika komponen utama gagal, penyelianya boleh memulakannya semula tanpa menjejaskan bahagian lain yang tidak berkaitan.
Pemeriksaan Penyelia
Masa untuk menguji secara ringkas pemahaman anda tentang strategi penyelia!
Ringkasan Pelajaran
Syabas! Anda telah mempelajari cara Elixir membina aplikasi yang tahan lasak:
- Penyelia memantau proses dan memulakannya semula apabila berlaku kegagalan.
- Strategi penyeliaan yang berbeza (
:one_for_one,:one_for_all,:rest_for_one) menentukan cara kegagalan dikendalikan. - Aplikasi Elixir menyediakan struktur tahap teratas, memulakan penyelia dan membentuk pepohon penyeliaan.
Konsep ini penting untuk membina sistem Elixir yang teguh dan tahan terhadap kegagalan.
Pelajari Elixir dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 12
- Pelajaran
- 48
Soalan Lazim
Adakah pelajaran “Penyelia dan Struktur Aplikasi” percuma?
Ya — teks penuh “Penyelia dan Struktur Aplikasi” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala, tingkat taraf kepada CoddyKit PRO. Kursus Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Penyelia dan Struktur Aplikasi”?
Reka bentuk aplikasi yang berdaya tahan menggunakan penyelia untuk memantau dan memulakan semula proses bagi memastikan toleransi terhadap kegagalan. Anda berlatih Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.
Berapa lamakah pelajaran “Penyelia dan Struktur Aplikasi” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala ini?
Ya. Setiap pelajaran Elixir & Phoenix: Pembangunan Bahagian Belakang Boleh Skala menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Proses Elixir dan Penghantaran Mesej
- Melaksanakan Tingkah Laku GenServer
- Penyelia dan Struktur Aplikasi
- Kerja Serentak dengan Task dan Agent