2. Cài đặt các thuật toán cân bằng tải trên HAproxy:
2.2. Thuật toán Lest Connection (LC)
Như đã đề cập ở chương 2, thuật toán LC sẽ phân tải dựa trên số kết nối hiện tại đến với server. Mỗi proxy sẽ lưu thông tin của tất cả các server của nó. Trong mỗi server đều có biến “cur_sess” lưu lại số session active của server. Chúng ta sẽ sử dụng một vòng lặp kiểm tra biến này, và lấy server có giá trị cur_sess thấp chia cho trọng số của mỗi server nhất để gửi yêu cầu tiếp theo.
Thực vậy, giả sử 2 server A, B có trọng số lần lượt là 1 và 2. Thuật toán sẽ đảm bảo cho số session active ở B luôn xấp xỉ gấp đôi số session active ở A, vì chúng ta đang so sánh “số session active/ trọng số server”.
Vì việc kiểm tra số lượng kết nối không phải được thực hiện ngay lập tức. Trong một hệ thống có tải cao, nếu một server là đang có ít active session nhất, nó sẽ nhận được yêu cầu, sau đó nó sẽ nhận được liên tục yêu cầu, do số lượng active session chưa kịp cập nhập. Vì vậy, trong thuật toán này, chúng ta cần tránh phân 2 yêu cầu liên tiếp vào cùng một server (chúng ta đang xét với bài toán không có cookie, nghĩa là 2 kết nối đến từ 2 clients khác nhau). Nghĩa là server vừa được phân tải sẽ trở thành server cần tránh trong lần phân tải tiếp theo. Ở đây chúng ta sử dụng biến “struct server *srvtoavoid”.
if(srv != srvtoavoid){ …
}
Sau khi chọn được server, chúng ta sẽ cập nhập lại giá trị srvtoavoid bằng một biến static
Static struct server *pre_server; …
Pre_server = t;
Dưới đây là hàm thực thi thuật toán least connections:
static inline struct server *get_server_lc(struct proxy *px, struct server *srvtoavoid) {
int s; /*Sử dụng để lấy số kết nối ít nhất của mỗi server dựa trên trọng số của chúng */
struct server *srv, *t;
/* Kiểm tra nếu kích thước của srv_map bằng không, nghĩa là không tồn tại server nào đang hoạt động, thuật toán trả về null */
if (px->srv_map_sz == 0) return NULL;
t = NULL; s = 10000000;
/* Thực hiện cho đến khi tìm được server phù hợp, tăng giá trị i và chọn server nào có ít kết nối nhất dựa trên biến cur_sess và trọng số */
for(srv = px->srv; srv != NULL; srv = srv->next) { if(srv != srvtoavoid) { if (!srv->maxconn || srv->cur_sess < srv_dynamic_maxconn(srv)){ if (s > (srv->cur_sess / srv->eweight ) || t==NULL) { t = srv; s = srv->cur_sess / srv->eweight; } } } } pre_server = t; return t; }