-
Notifications
You must be signed in to change notification settings - Fork 1
Load Balancing
Cloud Load balancing adalah sebuah proses mendistribusikan beban kerja (workload) kepada seluruh sumber daya di lingkungan komputasi awan tertentu dengan konsiderasi jaringan lalu lintas.
Cara kerjanya, load balancer mendapat workload dan me-routing ke sumber daya sehingga workload yang lain diurus terus-menerus tanpa ada waiting yang panjang. Tidak hanya dalam beberapa server, load balancing bisa melakukan distribusi secara geographical.
Contoh Penyedia Layanan Cloud Load Balancing:
- Amazon Web Services (AWS) menggunakan Elastic Load Balancing (ELB).
- Google Cloud Platform (GCP) menggunakan Google Cloud Load Balancing.
- Microsoft Azure menggunakan Azure Load Balancer.
Dibagi menjadi 2
-
Static
- Round robin Pembagian menggunakan DNS dalam bentuk rotasi.
- Weighted round robin Pembagian berdasarkan beban yang ditentukan. Jika bisa handle traffic besar, makan weight nya makin besar.
- IP hash Menggunakan fungsi matematika untuk mengubah IP Address ke hash. Berdasarkan hash tersebut, koneksi dihubungkan pada server tersebut.
-
Dynamic
- Least connection Melihat server yang memiliki koneksi yang sedikit (Asumsi seluruh kekuatan proses sama).
- Weighted response time Melihat rata-rata waktu respons tiap server, tetapi juga melihat jumlah koneksi pada server.
- Resource-based Melihat sumber daya (eg. CPU) pada server. Memerlukan 'agent' yang dapat memonitor sumber daya server.
Dan masih banyak lagi!
Merupakan program open source yang digunakan untuk web serving, reverse proxy, caching, load balancing, streaming, dll.
Untuk host, akan menggunakan Docker dan Docker Compose dengan FastAPI dan MongoDB sebagai Database.
Jadi, mari menginstall ketiga library tersebut dengan:
- Docker dan Docker Compose
Sudah dijelaskan di modul sebelumnya ya ;)
- FastAPI
pip install fastapi
Kemudian mengisntall uvicorn dengan
pip install uvicorn
- MongoDB
Untuk library ini, hanya akan menginstal
pydanticuntuk keperluan input database danpymangountuk mengkoneksikan FastAPI dangan database.
pip install pymango pydantic
Silakan mengikuti struktur berikut
.
└── Awan/
├── app/
│ ├── Dockerfile
│ ├── main.py
│ └── requirement.txt
├── app2/
│ ├── Dockerfile
│ ├── main.py
│ └── requirement.txt
├── app3/
│ ├── Dockerfile
│ ├── main.py
│ └── requirement.txt
├── docker-compose.yml
└── locustfile.py
mengimport library
from fastapi import FastAPI, Body, Request # FastAPI utama
from fastapi.encoders import jsonable_encoder # JSON Handler
import pymongo # Menghubungkan ke Database MongoDB
from pydantic import BaseModel #
from bson.objectid import ObjectId # Identifikasi ID pada mongoDB
import uuid # Default ID Generator
import socket # Identifier tiap docker
import time # Simulasi waktu requestselanjutnya, mari kita menghubungkan python dengan database mongoDB.
MONGO_DETAILS = "mongodb://admin:admin@mongodb:27017/" # nama aplikasi docker mongodb
client = pymongo.MongoClient(MONGO_DETAILS)
db = client['tes'] # nama databesnya 'tes'
collection = db['tes'] # nama collectionnya 'tes'untuk nama database dan collection bisa disesuaikan.
Selanjutnya, mendefinisikan jenis data di dalam collection:
class Item(BaseModel):
name: str
age: int
rank: strcollection mongoDB akan menggunakan struktur di atas.
Kemudian, mari mendefinisikan fungsi-fungsi untuk me-return data:
def myData(data):
return {
"id": str(data["_id"]),
"name": data["name"],
"age": data["age"],
"rank": data["rank"],
}
def myFullData(datas):
return [myData(data) for data in datas]
def ResponseModel(data, message = "Success"):
return {
"data": [data],
"code": 200,
"message": message,
}
def ErrorResponseModel(error, code, message):
return {
"error": error,
"code": code,
"message": message
}Penjelasannya:
-
myDatauntuk me-return data dengan format menyesuaikan struktur data atau lainnya. -
myFullDatauntuk mengembalikan seluruh isi data pada collection. -
ResponseModelsebagai handler data jika berhasil dilakukan. -
ErrorResponseModelsebagai handler data jika gagal dilakukan.
Setelah seluruh handler telah dibuat, mari kita ke main course, yaitu pembu8atan REST API dengan FastAPI.
Deklarasikan aplikasi
app = FastAPI()
Kita akan menggunakan 6 endpoint untuk mensimulasikan aplikasi REST API sederhana.
-
GET /sebagai testing. -
GET /fastsebagai testing dengan response cepat. -
GET /slowsebagai testing dengan response lambat. -
GET /allmendapatkan semua data pada collection. -
POST /creatememasukkan data baru pada collection. -
GET /get/{id}mendapatkan data sesuai id.
berikut implementasinya:
@app.get('/')
async def home():
return {
"message": "This is server A",
"hostname": socket.gethostname()}
@app.get('/fast')
async def hello():
time.sleep(0.5)
return {
"message": "Hello world from server A",
"opt": "fast"}
@app.get('/slow')
async def hello():
time.sleep(1)
return {
"message": "Hello world from server A",
"opt": "slow"}
@app.get("/all")
async def get_all_data():
# print(client.tes.tes.find())
# print(myFullData(client.tes.tes.find()))
return ResponseModel(myFullData(collection.find()), "All Good")
# insert new data
@app.post("/create", response_model=Item)
async def create_data(request: Request, lister: Item = Body(..., embed=True)):
lister = jsonable_encoder(lister)
new_data = client.tes.tes.insert_one(lister)
# return response with data inserted
return lister
# get data by id
@app.get("/get/{id}")
async def get_data(id: str):
Objinstance = ObjectId(id)
data = collection.find_one({"_id": Objinstance})
if data:
return ResponseModel(myData(data), "A")
else:
return ErrorResponseModel("An error occurred.", 404, "Data doesn't exist.")Adapun isi docker diisi berikut:
FROM python:3.9-slim
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Docker akan membuat folder app dan akan menginstall seluruh requirement di dalam file requirement.txt
Saat docker diluncurkan, DOcker python akan menjalankan uvicorn pada port 8000
uvicorn akan menjalankan file main dengan aplikasi app (akan dijelakan pada pembuatan FastAPI).
silakan memasukkan library-library yang akan digunakan:
fastapi==0.78.0
uvicorn==0.18.2
pymongo
pydantic
uuid
Pada nginx, kita akan mengkonfigurasikan Dockerfile dan file konfigurasi.
FROM nginx
RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
dengan file konfigurasi nginx.conf sebagai berikut:
upstream app {
server app:8000;
server app2:8000;
server app3:8000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://app;
}
}mengingat seluruh app akan dijalankan di docker port 8000 dan nginx akan dijalankan pada host port 80
proxy_pass http://app nama app menyesuaikan nama uvicorn yang dijalankan (main:app)
Dari upstream yang kita masukkan, load balancer yang akan digunakan adalan Round-Robin.
Pada docker compose, ada beberapa docker image yang akan digunakan, berupa:
- nginx
- mongo dan mongo-express
buatlah docker-compose dengan isi seperti di bawah ini:
version: '3'
services:
app:
build: ./app
ports:
- "8001:8000"
depends_on:
- mongodb
app2:
build: ./app2
ports:
- "8002:8000"
depends_on:
- mongodb
app3:
build: ./app3
ports:
- "8003:8000"
depends_on:
- mongodb
nginx:
build: ./nginx
ports:
- "80:80"
- "443:443"
depends_on:
- app
- app2
- app3
mongodb:
image: mongo
ports:
- "27017:27017"
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=admin
volumes:
- mongodb_data:/data/db
mongo-express:
image: mongo-express
ports:
- "8082:8081"
environment:
- ME_CONFIG_MONGODB_ADMINUSERNAME=admin
- ME_CONFIG_MONGODB_ADMINPASSWORD=admin
- ME_CONFIG_MONGODB_SERVER=mongodb
- ME_CONFIG_MONGODB_ENABLE_ADMIN=true
- ME_CONFIG_BASICAUTH_USERNAME=admin
- ME_CONFIG_BASICAUTH_PASSWORD=admin
depends_on:
- mongodb
volumes:
mongodb_data:
driver: localpada service app app2 app3, pastikan arah file sudah menuju folder yang memiliki Dockerfile yang telah dibuat sebelumnya.
adapun host ports yang akan digunakan tiap service adalah 8001 8002 8003 dan docker port seluruhnya diarahkan ke 8000
Why? karena kita menjalankan uvicorn tiap app di port 8000 namun tiap docker harus dijalankan di port host yang berbeda.
Karena aplikasi akan menghubungkan database, dan databse perlu di load terbih dahulu, maka tambahkan mongodb
build diarahkan ke folder berisi Dockerfile nginx.
port yang akan digunakan minimal 80:80.
nginx akan bergantung penggunaanya dengan app yang ada, sehingga ditambahkan depends_on ke tiap app.
Karena kita tidak menkonfigurasikan Dockerfile, kita akan load image dari repository Docker bernama mongo.
Port mongo dijalankan di 27017:27017 (default).
WAJIB memasukkan MONGO_INITDB_ROOT_USERNAME dan MONGO_INITDB_ROOT_PASSWORD untuk setup awal database.
Agar isi database tidak berubah setiap docker-composer di up, deklarasikan volumes dan mengisi sesuai isi di atas.
di luar strukture services, jangan lupa deklarasikan:
volumes:
mongodb_data:
driver: localMedia penampilan database mongodb pada webUI.
Deklarasikan image mongo-express karena tidak ada konfigurasi tambahan.
Defaut port mongo-express adalah 8081 Jalankan pada ports 8082:8081.
Adapun environtment yang perlu disetup:
-
ME_CONFIG_MONGODB_ADMINUSERNAME=adminusername ke mongodb -
ME_CONFIG_MONGODB_ADMINPASSWORD=adminpassword ke mongodb -
ME_CONFIG_MONGODB_SERVER=mongodbnama server mongodbyang digunakan (sesuai nama services) -
ME_CONFIG_MONGODB_ENABLE_ADMIN=truemenghidupkan admin -
ME_CONFIG_BASICAUTH_USERNAME=adminusername untuk mengakses webUI -
ME_CONFIG_BASICAUTH_PASSWORD=adminpassword untuk mengakses webUI
karena mongo-express harus menunggu mongodb selesai load, maka harus menambahkan mongodb pada depends_on.
Apabila sudah sesuai, jalankan docker compose dengan
docker-compose up --build
Kemudiian buka localhost dan coba refresh beberapa kali



untuk setup mongodb, maka buka localhost:8082, kemudian masukkan username dan password yang sudah ditentukan sebelumnya.

Langkah selanjutnya:
masukkan nama databse baru > Tekan create database > Buka database > masukkan nama koleksi baru > tekan Create collection
Pada halaman koleksi, mari buat dokumen baru dengan struktur seperti berikut:
{
"_id": ObjectId(),
"name": "Lorem ipsum",
"age": 20,
"rank": "admin"
}Jangan lupa mengganti nama database dan collection di main.py, kemudian docker-compose up ulang

Setelah itu instal locust dengan cara pip install locust lalu buat buat kode locustfile.py nya seperti dibawah
from locust import HttpUser, task, between
class HelloWorldUser(HttpUser):
wait_time = between(0.5, 2.5)
# a = 0
# b = 0
# c = 0
@task
def test_index(self):
response = self.client.get('/')
message = response.json()['message']
# print(message)
# if message == 'This is server A':
# self.a += 1
# elif message == 'This is server B':
# self.b += 1
# elif message == 'This is server C':
# self.c += 1
# print(f'A: {self.a}, B: {self.b}, C: {self.c}')
@task
def test_fast(self):
self.client.get('/fast')
@task
def test_slow(self):
self.client.get('/slow')
@task
def test_slow(self):
self.client.get('/all')
@task
def test_get_id(self):
response = self.client.get('/get/[ID]')
message = response.json()['message']
# if message == 'A':
# self.a += 1
# elif message == 'B':
# self.b += 1
# elif message == 'C':
# self.c += 1
# print(f'A: {self.a}, B: {self.b}, C: {self.c}')lalu di terminal masukkan command locust lalu akses di localhost:8089
test endpoint loadbalancer nginx nya disitu
Modul 1
- Prerequisite
- Dasar Teori
- Installasi
- Membuat Virtualisasi
- Konfigurasi Resource Virtual Machine
- Cara Bermain
- Konfigurasi Internet Pada Virtual Machine
- Sinkronisasi Folder
- Provisioning Aplikasi Pada Virtual Machine
- Soal Latihan
- Referensi
Modul 2
- Dasar Teori
- Installasi
- Terminologi Dasar
- Simple Provisioning Vagrant dengan Ansible
- Provisioning Multiple VM dengan Ansible
- Soal Latihan
- Referensi
Modul 3
- Virtual Machine vs Container
- Docker Instalasi
- Docker
- Docker Image
- Docker Container
- Docker Volume
- Dockerfile
- Docker Compose
- Soal Latihan
- Referensi
Modul 4
Modul 5
