Simulasi Bully Algorithm menggunakan 5 Docker node Go yang berkomunikasi satu sama lain via HTTP, lengkap dengan web dashboard real-time.
Bully Algorithm (Garcia-Molina, 1982) adalah protokol election klasik di sistem terdistribusi. Aturannya sederhana:
Node dengan ID tertinggi selalu menang ("membully") node lain untuk jadi koordinator.
1. Node X mendeteksi coordinator mati
2. Node X broadcast pesan ELECTION ke semua node ber-ID > X
3. Jika ada yang balas OK → X kalah, menunggu COORDINATOR
4. Jika tidak ada yang balas → X menang, broadcast COORDINATOR ke semua
5. Semua node update coordinator mereka
| Pesan | Dari → Ke | Arti |
|---|---|---|
ELECTION |
Node X → semua node ID > X | "Saya mau jadi leader, ada yang lebih tinggi?" |
OK |
Node Y → X (jika Y > X) | "Saya lebih tinggi, kamu kalah" |
COORDINATOR |
Pemenang → semua | "Saya koordinator baru" |
HEARTBEAT |
Coordinator → semua | "Saya masih hidup" |
┌──────────────────────────────────────────────────────┐
│ Docker Network (bully-net) │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ NODE-1 │ │ NODE-2 │ │ NODE-3 │ │
│ │ :8080 │ │ :8080 │ │ :8080 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ └─────────────┼─────────────┘ │
│ │ HTTP │
│ ┌─────────┐ ┌─────┴───┐ │
│ │ NODE-4 │ │ NODE-5 │ ← highest ID = leader │
│ │ :8080 │ │ :8080 │ │
│ └─────────┘ └─────────┘ │
│ │
│ ┌──────────────────────┐ │
│ │ DASHBOARD :3000 │ ← monitor & control │
│ └──────────────────────┘ │
└──────────────────────────────────────────────────────┘
- Docker & Docker Compose terinstall
docker compose up -d --buildopen http://localhost:3000Crash coordinator:
./scripts/bully.sh crash-coordinator
# Tunggu ~6 detik → election otomatis terjadiCrash node tertentu:
./scripts/bully.sh crash 5 # crash NODE-5
./scripts/bully.sh recover 5 # recover NODE-5Trigger election manual:
./scripts/bully.sh elect 2 # mulai election dari NODE-2Skenario cascade failure:
./scripts/bully.sh scenario-cascade
# Crash node 5 → election → crash node 4 → election → recover 5 → 5 bully balik jadi leaderStress test:
./scripts/bully.sh scenario-splitbully-algorithm/
├── docker-compose.yml # 5 node + 1 dashboard
├── node/
│ ├── main.go # Bully Algorithm implementation
│ ├── go.mod
│ └── Dockerfile
├── dashboard/
│ ├── main.go # Dashboard proxy server
│ ├── go.mod
│ ├── Dockerfile
│ └── static/
│ └── index.html # Real-time web dashboard
└── scripts/
└── bully.sh # Helper commands
| Endpoint | Method | Deskripsi |
|---|---|---|
GET /status |
GET | Status lengkap node |
POST /message |
POST | Terima pesan election/heartbeat |
POST /crash |
POST | Simulasi crash |
POST /recover |
POST | Simulasi recovery |
POST /election |
POST | Trigger election manual |
- Heartbeat interval: 2 detik (coordinator → semua node)
- Leader dead timeout: 6 detik tanpa heartbeat → trigger election
- Election response timeout: 2 detik per node
- Wait for COORDINATOR: 5 detik setelah dapat OK
Saat node pertama kali start, mereka menunggu dengan jitter berdasarkan ID:
- NODE-5 menunggu paling sedikit → menang pertama kali
- NODE-1 menunggu paling lama → menerima hasil election
Saat node crash recovery, ia langsung memulai election. Jika ID-nya adalah yang tertinggi, ia akan mem-bully node lain dan merebut kembali posisi coordinator.
[15:04:01.000] NODE-3 | 💔 Coordinator NODE-5 appears DEAD — starting election
[15:04:01.010] NODE-3 | 🗳️ Starting ELECTION (term 2)
[15:04:01.020] NODE-3 | 📨 Sent ELECTION to NODE-4, NODE-5
[15:04:01.100] NODE-4 | 📨 Received ELECTION from NODE-3 (term 2)
[15:04:01.110] NODE-4 | ✅ Sent OK to NODE-3 (I have higher ID)
[15:04:01.120] NODE-4 | 🗳️ Starting ELECTION (term 2)
[15:04:01.200] NODE-3 | 📬 Got OK from NODE-4 — stepping down
[15:04:03.200] NODE-4 | ⚠️ No response from NODE-5 (may be down)
[15:04:03.210] NODE-4 | 👑 No higher nodes alive — I win ELECTION (term 2)
[15:04:03.220] NODE-4 | 📢 Broadcasting COORDINATOR (term 2)
[15:04:03.300] NODE-1 | 👑 NODE-4 is the new COORDINATOR (term 2)
[15:04:03.310] NODE-2 | 👑 NODE-4 is the new COORDINATOR (term 2)
[15:04:03.320] NODE-3 | 👑 NODE-4 is the new COORDINATOR (term 2)
