SLB adalah penyeimbang beban tanpa sesi untuk lalu lintas UDP, dan memecahkan masalah yang melekat pada penggunaan penyeimbang beban tradisional (kaya fitur) untuk lalu lintas tersebut.
Untuk protokol UDP yang sederhana dan tanpa kewarganegaraan, tidak ada gunanya mencoba mempertahankan "afinitas" (alias "sesi") antara klien dan instance back-end. Penyeimbang beban tradisional berasumsi bahwa afinitas sangat membantu, sehingga mereka akan mencoba merutekan paket dari klien ke server back-end yang konsisten. Sebaliknya, SLB secara merata (secara acak) mendistribusikan paket satu per satu ke seluruh back-end yang tersedia. Hal ini menghasilkan pemuatan backend yang seragam, dan peningkatan ketahanan ketika satu instance backend gagal (akan terjadi peningkatan kehilangan paket untuk semua klien dibandingkan kehilangan total lalu lintas untuk beberapa klien).
Secara default, SLB akan mendengarkan paket UDP masuk pada port 1812
dan 1813
dan meneruskannya ke target backend acak yang diketahuinya. Port yang didengarkannya dapat dilengkapi dengan opsi --server-port-range
, yang menerima satu port (misalnya 541
) atau serangkaian port (misalnya 4000-5000
).
Untuk membuat SLB sadar akan backend memerlukan pengiriman paket "watchdog" (alias "tetap hidup") ke port admin (lebih lanjut tentang ini di bawah). Secara default, port admin adalah 1111
, tetapi dapat dikonfigurasi menggunakan opsi --admin-port
. Jika ada beberapa kartu jaringan di sistem Anda, Anda dapat menentukan IP menggunakan opsi --admin-ip
. Jika IP yang ditentukan dengan --admin-ip
berada dalam rentang CIDR multicast ( 244.0.0.0/4
) SLB akan secara otomatis bergabung dengan grup multicast tersebut (lebih lanjut tentang ini di bawah).
Opsi lain dijelaskan dalam bantuan perintah:
SimplestLoadBalancer:
Sessionless UDP Load Balancer sends packets to backends without session affinity.
Usage:
SimplestLoadBalancer [options]
Options:
--server-port-range <server-port-range> Set the ports to listen to and forward to backend targets
(default "1812-1813") [default: 1812-1813]
--admin-ip <admin-ip> Set the IP to listen on for watchdog events [default is first private IP]
--admin-port <admin-port> Set the port that targets will send watchdog events [default: 1111]
--client-timeout <client-timeout> Seconds to allow before cleaning-up idle clients [default: 30]
--target-timeout <target-timeout> Seconds to allow before removing target missing watchdog events [default: 30]
--default-target-weight <default-target-weight> Weight to apply to targets when not specified [default: 100]
--unwise Allows public IP addresses for targets [default: False]
--stats-period-ms <stats-period-ms> Sets the number of milliseconds between statistics messages printed to the
console (disable: 0, max: 65535) [default: 1000]
--default-group-id <default-group-id> Sets the group ID to assign to backends that when a registration packet doesn't
include one, and when port isn't assigned a group [default: 0]
--version Show version information
-?, -h, --help Show help and usage information
Backend tidak dikonfigurasi pada baris perintah. Sebaliknya, mereka didaftarkan dan dibatalkan pendaftarannya secara dinamis menggunakan paket UDP berkala yang dikirim ke port admin ( --admin-port
). Isi paket tersebut mungkin berbeda berdasarkan cara Anda menggunakan SLB di lingkungan Anda.
Jika Anda menjalankan satu server SLB, backend dapat dikonfigurasi untuk mengirim paket ke satu IP tersebut dan pada port admin. Ini adalah skenario paling sederhana. Setiap backend akan mengirimkan pesan dengan dua "byte ajaib" untuk menunjukkan "pendaftaran backend" untuk konten:
0x11 0x11
SLB akan menafsirkan paket seperti itu sebagai "daftarkan pengirim sebagai backend". Secara opsional, pesan dapat berisi satu atau dua byte tambahan (bobot dan ID grup) yang tujuannya akan dibahas lebih detail di bawah.
0x11 0x11 [X] [X]
^ ^
| |
| one byte for group id
|
one byte for weight
Di beberapa lingkungan, paket registrasi tidak akan dikirim dari backend itu sendiri, dan SLB mendukung kasus penggunaan tersebut. Ketika paket registrasi dikirim dari "pihak ketiga", kontennya harus menyertakan alamat IP backend yang didaftarkan:
0x11 0x11 X X X X [X] [X]
^ ^ ^
| | |
| | one byte for group id
| |
| one byte for weight
|
four bytes for ip to add
Sekali lagi, byte bobot dan ID grup dapat ditambahkan secara opsional.
Ketika penerapan HA yang lebih kuat dengan beberapa SLB diperlukan, komunikasi antara backend dan SLB dapat disederhanakan dengan menggunakan IP grup multicast. Hal ini berguna karena setiap SLB harus mengetahui setiap backend. Dalam kasus seperti ini, server SLB harus menggunakan opsi --admin-ip
untuk menentukan alamat multicast yang akan menyebabkan SLB bergabung dengan grup multicast dan karenanya semua menerima pesan apa pun yang dikirim ke IP tersebut. Backend dapat dikonfigurasi dengan IP tunggal tersebut, meminimalkan beban kerja dan menyederhanakan konfigurasinya (terutama ketika SLB dirotasi masuk dan keluar dari layanan karena penskalaan otomatis dan/atau penggunaan instans spot).
Perhatikan bahwa penggunaan IP multicast memerlukan switch yang mendukung multicast, atau (lebih mungkin) berjalan di AWS VPC yang dikonfigurasi dengan domain multicast.
Format paket admin sangat sederhana pada versi 2.0. Dalam kasus penggunaan SLB tunggal yang paling sederhana, paket registrasi dari backend dapat terdiri dari tidak lebih dari dua byte ajaib ( 0x11
0x11
). Opsional, paket dapat berasal dari sumber berbeda (misalnya server manajemen) dan memasukkan empat byte untuk menentukan alamat ipv4 backend. Dalam kedua kasus tersebut, dua byte opsional tambahan untuk "bobot" lalu lintas relatif terhadap backend lain, dan untuk "grup" yang akan ditetapkan ke backend dapat ditambahkan (selengkapnya tentang grup di bawah). Dalam seni ASCII:
0x11 0x11 [X X X X] [X] [X]
^ ^ ^
| | |
| | one byte for group id
| |
| one byte for weight
|
four bytes for ip to add
Untuk segera menghapus target, kirim paket dengan 0x86
sebagai byte pertama, bukan 0x11
(jika dikirim dari server manajemen, tambahkan IP backend yang akan dihapus):
0x86 0x11 [X X X X]
^
|
four bytes for ip to remove
Bobot digunakan untuk mengontrol jumlah relatif lalu lintas yang dikirimkan ke setiap backend. Jika tidak ada bobot yang ditentukan, nilai default 100 (dapat dikonfigurasi dengan --default-target-weight
) akan diterapkan ke backend, dan masing-masing akan menerima volume paket yang sama. Oleh karena itu, backend diharapkan (dan disarankan) menyesuaikan nilai bobot dalam paket adminnya berdasarkan kemampuannya menangani lalu lintas (mungkin berkurang ketika CPU tinggi, pembaruan sedang diterapkan, dll.). Misalnya:
100
, 50
dan 50
, maka backend pertama akan menerima 50% lalu lintas dan backend kedua dan ketiga masing-masing mendapatkan 25%.31
dan 31
, maka masing-masing akan menerima 50% lalu lintas.Saat menggunakan grup, bobot relatif dievaluasi dibandingkan dengan backend lain dalam grup yang sama (tidak di semua grup).
Penting untuk mengirim paket admin dengan andal dan dengan kecepatan yang memadai. Setiap kali paket diterima oleh SLB, waktu "terakhir terlihat" di backend diperbarui. Jika 30 detik (dapat dikonfigurasi dengan
--target-timeout
) berlalu tanpa backend terlihat, backend akan dihapus dan tidak ada lalu lintas lebih lanjut yang akan dikirim ke sana.
Secara default, semua backend akan digunakan untuk melayani semua port yang dilayani oleh penyeimbang beban.
Namun, dimungkinkan untuk menetapkan port individual ke subkumpulan backend menggunakan pesan penetapan port SLB dan memberikan ID grup dalam pesan pendaftaran. Pertimbangkan, misalnya, Anda ingin memiliki lalu lintas keseimbangan beban SLB untuk port 1812-1813 tetapi tetapkan lalu lintas yang mencapai setiap port ke kumpulan server yang berbeda. Untuk melakukannya:
x66 x11
) dengan nomor port (dua byte) dan ID grup (satu byte). Pesan-pesan ini tidak perlu diulangi, dan dapat dikirim ketika perubahan pada penetapan grup port diinginkan (namun, tidak ada salahnya mengulangi pesan tersebut, yang dapat memudahkan untuk memastikan port-port tersebut ditetapkan grupnya dengan benar setelah layanan dimulai ulang). 0x66 0x11 X X X
^ ^
| |
| one byte for group ID
|
two bytes for port number, litten endian
Menggunakan Linux bash
mengirim paket admin sangatlah mudah. Ini dapat dilakukan dengan menggunakan perintah netcat
( nc
) atau sistem file /dev/udp
. Misalnya, jika penyeimbang beban Anda mendengarkan pada port admin default 1111
dan Anda ingin menambahkan target dengan IP 192.168.1.22
:
$ echo -e $( echo " x11x11 $( echo " 192.168.1.22 " | tr " . " " n " | xargs printf ' \x%02X ' ) " ) > /dev/udp/127.0.0.1/1111
Karena mengirimkan paket-paket tersebut secara manual agar serangkaian target tetap terdaftar bisa jadi membosankan, Anda dapat membuat skrip shell kecil, misalnya lb.sh
:
#! /bin/bash
echo -ne $( echo " x11x11 $( echo " 192.168.1.22 " | tr " . " " n " | xargs printf ' \x%02X ' ) " ) > /dev/udp/127.1.1.1/1111
echo -ne $( echo " x11x11 $( echo " 192.168.1.23 " | tr " . " " n " | xargs printf ' \x%02X ' ) " ) > /dev/udp/127.1.1.1/1111
echo -ne $( echo " x11x11 $( echo " 192.168.1.24 " | tr " . " " n " | xargs printf ' \x%02X ' ) " ) > /dev/udp/127.1.1.1/1111
echo -ne $( echo " x11x11 $( echo " 192.168.1.25 " | tr " . " " n " | xargs printf ' \x%02X ' ) " ) > /dev/udp/127.1.1.1/1111
echo -ne $( echo " x11x11 $( echo " 192.168.1.26 " | tr " . " " n " | xargs printf ' \x%02X ' ) " ) > /dev/udp/127.1.1.1/1111
echo -ne $( echo " x11x11 $( echo " 192.168.1.27 " | tr " . " " n " | xargs printf ' \x%02X ' ) " ) > /dev/udp/127.1.1.1/1111
Dan kemudian gunakan perintah watch
untuk memanggil skrip itu setiap beberapa detik:
$ watch -n10 ./lb.sh
Biner bawaan untuk Linux dan Windows x64, serta Linux ARM tersedia sebagai "Rilis" GitHub. Ini adalah proyek .Net 8.0 yang sangat sederhana, jadi untuk membangunnya, jalankan (dengan asumsi Anda telah menginstal dotnet-sdk-8.0):
dotnet build
Anda mungkin ingin membuat biner asli yang dapat dieksekusi, yang nyaman dan menawarkan beberapa manfaat kinerja.
Untuk Linux:
dotnet publish -o ./ -c Release -r linux-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true --self-contained
Untuk Windows:
dotnet publish -o ./ -c Release -r win10-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true --self-contained
Demikian pula, menjalankannya dengan mudah menggunakan dotnet run
di direktori proyek:
$ dotnet run
Atau, jika Anda telah membuat executable asli:
$ ./SimplestLoadBalancer
Silakan membuat masalah di sini di GitHub untuk pertanyaan dan laporan bug. Tidak ada templat atau persyaratan yang disediakan, namun harap buat sedeskriptif mungkin - ini akan membantu memastikan kami dapat merespons dengan cara yang masuk akal. Lihat juga, berkontribusi.
Menikmati!