Load Balancer Pool Distribution Analyzer
.calc-header {
margin-bottom: 30px;
padding: 25px;
background: linear-gradient(135deg, #FF6B6B 0%, #C92A2A 100%);
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
color: white;
}
.calc-header h2 {
margin-top: 0;
color: white;
font-size: 28px;
margin-bottom: 10px;
}
.calc-header p {
margin: 10px 0 20px 0;
opacity: 0.95;
font-size: 15px;
}
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
margin-top: 20px;
}
.form-grid-3 {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 15px;
margin-top: 15px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-group label {
font-weight: 600;
font-size: 14px;
color: white;
}
.form-group input,
.form-group select {
padding: 12px;
font-size: 15px;
border: 2px solid rgba(255,255,255,0.3);
border-radius: 6px;
background: rgba(255,255,255,0.95);
transition: all 0.3s ease;
font-family: 'Courier New', monospace;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #4CAF50;
background: white;
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.15);
}
.form-group select {
cursor: pointer;
font-family: inherit;
}
.submit-btn {
padding: 14px 35px;
font-size: 16px;
background: #4CAF50;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
margin-top: 15px;
width: 100%;
}
.submit-btn:hover {
background: #45a049;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
.submit-btn:active {
background: #3d8b40;
transform: translateY(0);
}
.secondary-btn {
padding: 10px 20px;
font-size: 14px;
background: rgba(255,255,255,0.2);
color: white;
border: 2px solid rgba(255,255,255,0.5);
border-radius: 6px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s ease;
}
.secondary-btn:hover {
background: rgba(255,255,255,0.35);
border-color: white;
}
.danger-btn {
padding: 8px 14px;
font-size: 13px;
background: #e53935;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
transition: all 0.2s ease;
}
.danger-btn:hover {
background: #c62828;
}
.result-section {
background: white;
border: 1px solid #e0e0e0;
border-radius: 8px;
margin-top: 20px;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
transition: all 0.3s ease;
display: none;
}
.result-section.show {
display: block;
}
.result-section:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.section-header {
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
color: white;
padding: 15px 20px;
}
.section-header h3 {
margin: 0;
font-size: 18px;
display: flex;
align-items: center;
gap: 10px;
}
.section-content {
padding: 20px;
background: #fafafa;
}
.data-row {
display: flex;
margin: 12px 0;
padding: 10px;
background: white;
border-radius: 4px;
border-left: 3px solid #4CAF50;
align-items: center;
}
.data-label {
font-weight: bold;
color: #555;
min-width: 220px;
flex-shrink: 0;
font-size: 14px;
}
.data-value {
color: #333;
font-family: 'Courier New', monospace;
word-break: break-word;
font-size: 18px;
}
.data-value.highlight {
color: #4CAF50;
font-weight: bold;
font-size: 22px;
}
.data-value.warning {
color: #FF6B6B;
font-weight: bold;
font-size: 22px;
}
.help-text {
margin-top: 15px;
font-size: 14px;
color: rgba(255,255,255,0.9);
background: rgba(0,0,0,0.1);
padding: 10px 15px;
border-radius: 4px;
}
.help-text strong {
color: white;
}
/* Member list table */
.member-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-size: 14px;
}
.member-table th {
background: #f0f0f0;
padding: 10px 12px;
text-align: left;
font-weight: 600;
color: #444;
border-bottom: 2px solid #ddd;
}
.member-table td {
padding: 10px 12px;
border-bottom: 1px solid #eee;
vertical-align: middle;
}
.member-table tr:last-child td {
border-bottom: none;
}
.member-table tr:hover td {
background: #f9f9f9;
}
/* Status badge */
.status-badge {
display: inline-block;
padding: 3px 10px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.status-badge.up {
background: #e8f5e9;
color: #2e7d32;
border: 1px solid #a5d6a7;
}
.status-badge.down {
background: #ffebee;
color: #c62828;
border: 1px solid #ef9a9a;
}
/* Balance score ring */
.balance-score-container {
display: flex;
align-items: center;
gap: 20px;
padding: 15px;
background: white;
border-radius: 8px;
border: 1px solid #e0e0e0;
margin-bottom: 15px;
}
.balance-score-ring {
width: 80px;
height: 80px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
font-weight: bold;
color: white;
flex-shrink: 0;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}
.balance-score-ring.excellent {
background: linear-gradient(135deg, #43a047, #1b5e20);
}
.balance-score-ring.good {
background: linear-gradient(135deg, #7cb342, #558b2f);
}
.balance-score-ring.fair {
background: linear-gradient(135deg, #fb8c00, #e65100);
}
.balance-score-ring.poor {
background: linear-gradient(135deg, #e53935, #b71c1c);
}
.balance-score-info {
flex: 1;
}
.balance-score-info h4 {
margin: 0 0 5px 0;
font-size: 18px;
color: #333;
}
.balance-score-info p {
margin: 0;
font-size: 13px;
color: #666;
line-height: 1.5;
}
/* Metrics grid */
.metrics-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
margin-bottom: 20px;
}
.metric-card {
background: white;
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 15px;
text-align: center;
border-top: 3px solid #4CAF50;
}
.metric-card .metric-value {
font-size: 22px;
font-weight: bold;
color: #333;
font-family: 'Courier New', monospace;
}
.metric-card .metric-label {
font-size: 12px;
color: #888;
margin-top: 4px;
}
/* Chart container */
.chart-wrapper {
background: white;
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.chart-wrapper h4 {
margin: 0 0 15px 0;
color: #444;
font-size: 15px;
font-weight: 600;
}
/* Algorithm explanation */
.algo-explanation {
background: #fff8e1;
border: 1px solid #ffe082;
border-radius: 6px;
padding: 12px 15px;
font-size: 13px;
color: #5d4037;
line-height: 1.6;
margin-top: 10px;
}
.algo-explanation strong {
color: #3e2723;
}
/* Hash ring visualization */
.ring-wrapper {
display: flex;
align-items: flex-start;
gap: 20px;
}
#hashRingCanvas {
border: 1px solid #e0e0e0;
border-radius: 50%;
display: block;
flex-shrink: 0;
}
.ring-legend {
flex: 1;
}
.ring-legend-item {
display: flex;
align-items: center;
gap: 10px;
padding: 6px 0;
font-size: 13px;
border-bottom: 1px solid #f0f0f0;
}
.ring-legend-dot {
width: 14px;
height: 14px;
border-radius: 50%;
flex-shrink: 0;
}
/* Redistribution info */
.redistribution-row {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
background: white;
border-radius: 4px;
border-left: 3px solid #FF6B6B;
margin-bottom: 6px;
font-size: 14px;
}
.redistribution-row .arrow {
color: #FF6B6B;
font-size: 18px;
flex-shrink: 0;
}
.redistribution-row .move-label {
color: #555;
flex: 1;
}
.redistribution-row .move-count {
font-family: 'Courier New', monospace;
font-weight: bold;
color: #333;
}
/* Slider styling */
.slider-group {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 5px;
}
.slider-group label {
font-weight: 600;
font-size: 14px;
color: white;
display: flex;
justify-content: space-between;
}
.slider-group label span {
font-family: 'Courier New', monospace;
background: rgba(0,0,0,0.2);
padding: 2px 8px;
border-radius: 4px;
font-size: 13px;
}
input[type="range"] {
width: 100%;
accent-color: #4CAF50;
height: 6px;
cursor: pointer;
}
/* Controls area inside header */
.header-controls {
margin-top: 20px;
}
.control-group-label {
font-weight: 600;
font-size: 13px;
color: rgba(255,255,255,0.8);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 8px;
margin-top: 18px;
}
.add-member-row {
display: flex;
gap: 8px;
align-items: flex-end;
flex-wrap: wrap;
}
.add-member-row .form-group {
flex: 1;
min-width: 120px;
}
/* Failure simulation section */
.failure-section {
background: rgba(0,0,0,0.1);
border-radius: 8px;
padding: 15px;
margin-top: 18px;
}
.failure-section .control-group-label {
margin-top: 0;
}
.failure-row {
display: flex;
gap: 10px;
align-items: flex-end;
flex-wrap: wrap;
}
.failure-row .form-group {
flex: 1;
min-width: 140px;
}
.failure-btn-group {
display: flex;
gap: 8px;
}
/* Responsive design */
@media (max-width: 768px) {
.form-grid,
.form-grid-3 {
grid-template-columns: 1fr;
}
.metrics-grid {
grid-template-columns: 1fr 1fr;
}
.data-row {
flex-direction: column;
align-items: flex-start;
}
.data-label {
margin-bottom: 4px;
min-width: auto;
}
.ring-wrapper {
flex-direction: column;
}
#hashRingCanvas {
width: 220px !important;
height: 220px !important;
align-self: center;
}
.balance-score-container {
flex-direction: column;
text-align: center;
}
.add-member-row {
flex-direction: column;
}
.add-member-row .form-group {
min-width: auto;
width: 100%;
}
.failure-row {
flex-direction: column;
}
}
@media (max-width: 480px) {
.calc-header h2 {
font-size: 22px;
}
.metrics-grid {
grid-template-columns: 1fr;
}
}
Chart.js CDN
========== ΚΕΦΑΛΙΑ / ΕΛΕΓΧΟΣ ===========
========== ΠΙΝΑΚΑΣ ΜΕΛΩΝ ===========
========== ΑΠΟΤΕΛΕΣΜΑΤΑ ΔΙΑΝΟΜΗΣ ==========
========== ΑΠΟΤΥΧΙΑ ΕΠΑΝΚΑΤΑΝΟΜΗ ===========
========== ΟΠΤΙΚΟΠΟΙΗΣΗ ΔΑΧΤΥΛΙΟΥ ΧΑΣ ==========
========== ΒΟΗΘΕΙΑ / ΕΝΝΟΙΕΣ ==========
Load Balancer Pool Distribution Analyzer
Προσομοιώστε τον τρόπο με τον οποίο διαφορετικοί αλγόριθμοι εξισορρόπησης φορτίου κατανέμουν την κυκλοφορία στα μέλη της ομάδας. Μοντελοποίηση σεναρίων αποτυχίας και σύγκριση της αποδοτικότητας ανακατανομής.
Αλγόριθμος & Πλήθος συνεδριών
Ρυθμιστικό πλήθους συνεδριών
Προσομοίωση αποτυχίας
Όγκος κυκλοφορίας
Διαχείριση μελών της πισίνας
Μέλη του Pool
Προσομοίωση Σεναρίου Αποτυχίας
Πώς λειτουργεί:Η δειγματοληψία των IP πελατών γίνεται από ένα υποδίκτυο /16 (10.0.0.0/16).
Για κατακερματισμό βάσει πηγής, κάθε μοναδική IP πελάτη αντιστοιχίζεται ντετερμινιστικά σε ένα μέλος.
Το Round robin αγνοεί την IP του πελάτη και διανέμει διαδοχικά. Σταθμισμένες χρήσεις αναλογικές
τυχαία ανάθεση. Ο συνεπής κατακερματισμός τοποθετεί τόσο τους πελάτες όσο και τα μέλη σε έναν εικονικό δακτύλιο.
Μέλη του Pool
| ταυτότητα | IP: Θύρα | Βάρος | Κατάσταση | Δράσεις |
|---|
Αποτελέσματα Διανομής
Βαθμολογία ισορροπίας + επεξήγηση αλγορίθμου
Πλέγμα μετρήσεων
Γράφημα ράβδων
Σειρές λεπτομερειών μέλους
Κατανομή συνεδρίας ανά μέλος
Ανάλυση ανακατανομής αποτυχίας
Συνεπής δακτύλιος κατακερματισμού
Διαβάζοντας το δαχτυλίδι:Κάθε μέλος τοποθετείται σε πολλά σημεία γύρω από το δακτύλιο
(εικονικοί κόμβοι). Μια IP πελάτη κατακερματίζεται σε μια θέση στο δαχτυλίδι και, στη συνέχεια, αποστέλλεται το αίτημα
στο πλησιέστερο μέλος δεξιόστροφα. Η προσθήκη ή η αφαίρεση ενός μέλους επηρεάζει μόνο το τόξο του
τηλεφωνήστε στην ιδιοκτησία — ελαχιστοποίηση της διακοπής της συνεδρίας.
Αναφορά αλγορίθμου
Round Robin
Οι συνεδρίες εκχωρούνται διαδοχικά: μέλος 1, 2, 3, ..., N, 1, 2, ... Κάθε μέλος
λαμβάνει ακριβώς το 1/Ν όλων των αιτημάτων. Αγνοεί τη χωρητικότητα του διακομιστή και τη συνάφεια πελάτη.
Απλό και προβλέψιμο, αλλά αποτυγχάνει σκληρά σε ετερογενές υλικό.
Πηγή IP Hash
Ένας κατακερματισμός του modulo IP του πελάτη, ο αριθμός μελών επιλέγει το backend. Ο ίδιος πελάτης
φτάνει πάντα στο ίδιο μέλος — χρήσιμο για κρατικές εφαρμογές. Προσθήκη ή αφαίρεση
ένα μέλος ανακαταλέγεταιόλοιαντιστοιχίσεις πελατών (Ν αλλαγή σε (Ν-1)/Ν όλων των περιόδων σύνδεσης).
σταθμισμένη
Κάθε μέλος λαμβάνει ένα μερίδιο ανάλογο με το βάρος του σε σχέση με το συνολικό βάρος
πισίνα. Ένα μέλος με βάρος=4 παίρνει 4 φορές τις συνεδρίες ενός μέλους βάρους=1. Χρησιμοποιείται για μοντελοποίηση
ετερογενής χωρητικότητα backend (π.χ. VM έναντι διακομιστή γυμνού μετάλλου).
Συνεπής κατακερματισμός
Τα μέλη και οι πελάτες αντιστοιχίζονται σε έναν κυκλικό δακτύλιο μέσω κατακερματισμού. Κάθε πελάτης πηγαίνει
στο πλησιέστερο μέλος δεξιόστροφα στο δαχτυλίδι. Εικονικοί κόμβοι (αντίγραφα ανά μέλος)
βελτίωση της ομοιομορφίας διανομής. Όταν ένα μέλος αποτυγχάνει, μόνο οι συνεδρίες του μετακινούνται στο
επόμενο μέλος στο δαχτυλίδι — 1/Ν περίοδοι σύνδεσης ενοχλήθηκαν έναντι 100% για κατακερματισμό modulo.