Jump to content

Recommended Posts

Ce este load balancing?

Impartirea incarcarii serverelor reprezinta distribuirea anumitor procese si comunicatii pe mai multe servere pentru ca nici unul din ele sa nu ajunga sa fie supraincarcat. In general, siturile cu foarte multa activitate folosesc mai multe servere care contin aceeasi informatie. Vizitatorii sunt distribuiti pe toate serverele, pentru a evita supraincarcarea unuia dintre ele.

In acest tutorial o sa va prezint mai multe solutii de load balancing utilizand aplicatii open source. Exista scule hardware care fac lucrul asta, insa pe multi bani, si de multe ori o sa vedeti ca o combinatie de genul FreeBSD+Haproxy sau nginx depaseste cu mult specificatiile unui load balancer hardware care ajunge la un pret foarte mare.

Folosire nginx ca load balancer:

In ciuda faptului ca nu este conceput pentru asta, nginx are suport pentru load balancing. De exemplu, puteti face un server pe care sa-l utilizati ca load balancer, iar in spatele acestuia se pot pune un numar nelimitat de servere web (o sa le numim generic "nodes").

In exemplul de mai jos, 10.0.0.8, 10.0.0.9, 10.0.0.10 si 10.0.0.11 reprezinta serverele web ce se afla in spatele balancerului. Numarul de requesturi primite de nginx se vor distribui in mod egal catre aceste servere. Pentru a fi usor observate sectiunile ce constituie subiectul acestui tutorial, am sa le fac de culoare rosie. Restul de valori din acest exemplu de configuratie sunt pur informative si au fost puse pentru a vedea ordinea si a va da seama mai bine cum se configureaza.

 
user nobody;
worker_processes 6;
timer_resolution 200ms;
worker_rlimit_nofile 240000;

events {
    use kqueue;
    worker_connections 22000;
}

http {
    include              mime.types;
    default_type         application/octet-stream;
    reset_timedout_connection on;
    msie_padding         off;
    sendfile             on;
    keepalive_requests   100;
    keepalive_timeout    5;
    tcp_nopush           off;
    tcp_nodelay          on;
    server_tokens        off;
    send_timeout         3;
    client_max_body_size      1024m;
    client_body_buffer_size   128k;
    client_header_buffer_size 64k;
    proxy_connect_timeout     120;
    proxy_send_timeout        120;
    proxy_read_timeout        120;
    proxy_buffer_size         16k;
    proxy_buffers      4      32k;
    proxy_busy_buffers_size   64k;
    proxy_temp_file_write_size 64k;
    gzip                      on;
    gzip_min_length           1000;
    gzip_buffers              4 8k;
    gzip_static               off;
    gzip_comp_level           9;
    gzip_proxied              expired no-cache no-store private auth;
    gzip_types                text/plain text/css text/xml application/xml text/javascript application/x-javascript;

[COLOR="#FF0000"]upstream backends {
        server 10.0.0.8;
        server 10.0.0.9;
        server 10.0.0.10;
        server 10.0.0.11;
}[/COLOR]

server {
        listen 0.0.0.0:80 default rcvbuf=32000 sndbuf=46000 backlog=1000 accept_filter=httpready accept_filter=dataready;
        server_name _;
        # Main location
        location / {
            [COLOR="#FF0000"]proxy_pass  http://backends;[/COLOR]
            proxy_redirect     off;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
        location /status {
         stub_status on;
         access_log  off;
        }
   }
}

In cazul in care doriti sa implementati si failover pe noduri (lucru recomandat), aveti la indemana optiunile "max_fails" si "fail_timeout". Sa spunem ca dorim sa nu mai fie trimise requesturi catre serverul cu adresa ip 10.0.0.10 in cazul in care este nefunctional (dupa ce face fail de 3 ori cu timeout de 20 de secunde).

Exemplu:

 
upstream backends {
        server 10.0.0.8;
        server 10.0.0.9;
        server 10.0.0.10 max_fails=3 fail_timeout=20;
        server 10.0.0.11;
}

Load balancer cu haproxy:

Daca nu ati auzit pana acum de haproxy sau nu ati folosit, va recomand sa cititi cate ceva despre el. Combinatia FreeBSD+haproxy poate inlocui cu succes un load balancer comercial care ajunge la costuri de multe zero-uri in euro.

Pagina oficiala haproxy este HAProxy - The Reliable, High Performance TCP/HTTP Load Balancer. Pentru documentatie, va invit sa vizitati HAProxy - The Reliable, High Performance TCP/HTTP Load Balancer

In exemplul de mai jos, am sa va arat un fisier de configurare ("haproxy.conf"), similar cu exemplul din tutorialul de mai sus, "Folosire nginx ca load balancer". Adresele IP 10.0.0.2, 10.0.0.3, 10.0.0.4, 10.0.0.5, 10.0.0.6, 10.0.0.7, 10.0.0.8 si 10.0.0.9 sunt nodurile balancerului (serverele web) iar 10.0.0.1 este adresa ip a balancerului, cea pe care vom primi request-urile. Am "botezat" nodurile acestui balancer cu numele planetelor din sistemul solar ;-)

Puteti vedea aici un screenshot cu pagina de status de la haproxy.

 
global
 log 127.0.0.1 local0
 maxconn 280000
 user nobody
 group nobody
 nbproc 8 # Number de procesoare (fizice)
 pidfile /var/run/haproxy.pid
 daemon

defaults
 mode    http
 option  httpclose
 option  abortonclose
 option  httplog
 option  dontlognull
 option  httpclose
 retries 3
 maxconn 240000
 monitor-uri /haproxy-ping
 option  redispatch
 contimeout      5000
 clitimeout      50000
 srvtimeout      50000

 listen HTTP_SERVERFARM 10.0.0.1:80
 mode http
 retries 3
 option redispatch
 maxconn 36000
 contimeout 5000
 clitimeout 50000
 srvtimeout 50000
 option httpclose
 option forwardfor # This sets X-Forwarded-For
 balance roundrobin # Load Balancing algorithm
 stats enable
 stats uri /balancer-status
 monitor-uri /haproxy-ping
 option httpchk

 server MERCURY  10.0.0.2:80 weight 1 maxconn 3000 check inter 160000
 server VENUS    10.0.0.3:80 weight 1 maxconn 3000 check inter 160000
 server EARTH    10.0.0.4:80 weight 1 maxconn 3000 check inter 160000
 server MARS     10.0.0.5:80 weight 1 maxconn 3000 check inter 160000
 server JUPITER  10.0.0.6:80 weight 1 maxconn 3000 check inter 160000
 server SATURN   10.0.0.7:80 weight 1 maxconn 3000 check inter 160000
 server URANUS   10.0.0.8:80 weight 1 maxconn 3000 check inter 160000
 server NEPTUNE  10.0.0.9:80 weight 1 maxconn 3000 check inter 160000

Load balancing cu packet filter pe FreeBSD:

In acest scurt tutorial nu am sa scriu despre load balancing-ul unor multiple conexiuni la internet, si am sa ma rezum strict la load balancing-ul serverelor web. Packet filterul suporta nativ definirea unei ferme de servere web catre care pot distribui request-urile venite. De asemenea, suporta metodele "round-robin" si "sticky-address"

Round-Rubin reprezinta o tehnica de load balancing prin care cererile sunt plasate/trimise catre o ferma de noduri. De exemplu, sa presupunem ca o companie detine un site foarte mare si doreste sa-l gazduiasca pe trei servere. In fata acestor servere o sa vina configurat un load balancer, care va distribui cererile sosite pe port 80 catre cele trei servere. In cazul "round-rubin", cand un utilizator va accesa site-ul web, requesturile acestuia vor fi trimise catre primul server, al II-lea utilizator va fi trimis catre al II-lea server iar al III-lea vizitator ce va accesa site-ul va fi trimis catre serverul al III-lea. Restul de requesturi de la utilizatori o sa fie trimise in acelasi mod catre noduri, pana lista (coada de asteptare) va ajunge la capat.

Sticky-Address reprezinta un procedeu in care request-urile venite de la aceeasi sursa, vor fi trimise catre aceeasi destinatie (same-path). Acest procedeu persista atata timp cat sunt "states" (sesiuni tcp) in lista de asteptare. Mai exact: Conexiunile de la o SURSA UNICA vor fi trimise catre acelasi server web (node).

In exemplul de mai jos, am sa definesc serverele web cu adresele IP: 10.0.0.2, 10.0.0.3, 10.0.0.4, iar configuratia o sa vina facuta pe serverul folosit ca load balancer (server care va avea configurata o adresa IP publica, pe care va primi cererile de la vizitatori)

 
ext_if     = "bce0"
webservers = "{ 10.0.0.2, 10.0.0.3, 10.0.0.4 }"
rdr on $ext_if inet proto tcp from any to $ext_if port 80 -> $webservers round-robin sticky-address

Nota: Nu se poate face failover.

Load balancing cu apache:

Utilizand apache, se poate face load balancing cu ajutorul modulelor mod_proxy si mod_proxy_balancer. Algoritmii de balansare sunt: Request Counting, Weighted Traffic Counting si Pending Request Counting. Acesti alogoritmi de balansare pot fi controlati prin lbmethod.

 
lbmethod=byrequests  pentru "Request Counting Algorithm"
lbmethod=bytraffic   pentru "Weighted Traffic Counting Algorithm"
lbmethod=bybusyness  pentru "Pending Request Counting Algorithm"

O sa definesc in exemplul de mai jos, nodurile cu 10.0.0.2, 10.0.0.3, 10.0.0.4

 
<Proxy balancer://webcluster>
 BalancerMember http://10.0.0.2:80
 BalancerMember http://10.0.0.3:80
 BalancerMember http://10.0.0.4:80
</Proxy>

ProxySet lbmethod=byrequests
ProxyPreserveHost on
ProxyRequests Off
ProxyPass / balancer://webcluster
ProxyPassReverse / balancer://webcluster

Puteti citi mai multe despre mod_proxy_balancer pe mod_proxy_balancer - Apache HTTP Server

Nota: Va recomand apache worker pentru load balancing cu apache. Apache prefork este un mare consumator de resurse. Limitati-va doar la modulele absolut necesare.

------------------------------------------------

Note:

- Daca folositi o parte din acest tutorial pe alt site, va rog sa specificati link-ul original:

 
<a href="https://rstforums.com/forum/topic/43853-http-load-balancing/" target="_blank" title="Tutorial HTTP Load Balancing">Tutorial HTTP Load balancing</a>

Ar fi de preferat sa cereti permisiunea unui admin dupa RST daca doriti sa luati un tutorial de aici pentru alt site. (Multumesc)

- In cazul in care aveti ceva de intrebat (la obiect), puteti pune intrebarile in acest thread. Va rog sa va limitati la subiect.

  • Upvote 5
Link to comment
Share on other sites

Cred ca se poate adauga si Round robin DNS cu care se poate face balansare


www IN A 10.0.0.8
IN A 10.0.0.9

Round rubin dns nu inlocuieste http load balancing pentru ca:

- Daca accesezi un domeniu cu round rubin, calculatorul tau o sa verifice DNS doar odata apoi isi face caching, astfel incat vei accesa un singur server.

- Nu se face balansare http intre servere, toate request-urile de la un client vor fi trimise catre acelasi server. (totul tine de raspunsul DNS si de dns caching)

- Prin HTTP Flood serverele pot fi atacate independent

Link to comment
Share on other sites

Mai aduc o alternativa Open Source:

UltraMonkey is a project to create load balanced and highly available services on a local area network using Open Source components on the Linux operating system, including heartbeat and ldirectord from the Linux-HA project.

Note:

Exista diverse servicii comerciale de load balancing, un nume destul de cunoscut ar fi

(Barracuda Load Balancer)

Vin des folosite pentru a opri diverse atacuri DOS ,load balancing anti DOS abuse management

Edited by pyth0n3
Link to comment
Share on other sites

@LegendKiller: Tocmai am spus in post-ul de mai sus ce dezavantaje au sistemele de rr dns.

Se poate seta TTL inclusiv la 5 minute, insa sunt niste standarde care ar trebui respectate. In plus, probabil stii ca multi provideri folosesc dns cache. Un bun exemplu este RDS.

Am vazut ca uneori se pastreaza cache in DNS-urile lor si pentru 7 zile. Probabil ai observat problemele de genul la hosting (cand un client nou isi schimba ns-urile pentru a muta hostingul)

Un alt dezavantaj este faptul ca nu exista failover decat la sistemele DNS distribuite (geo). Stiu ca "din exterior" se vad solutii rr dns la multe companii, insa ele sunt combinate cu sisteme geoip si load balancere.

Calculatorul omului de acasa nu iti va interoga niciodata NS-urile tale, el va face interogare la ISP iar ISP-ul in NS-urile tale (iar acolo se face cache, cum spuneam mai sus)

O explicatie simpla pentru a intelege indiferent daca sunt cunostinte tehnice sau nu:

Vizitatorul introduce www.rstcenter.com in browser iar OS-ul verifica in ordinea urmatoare:

- fisierul hosts

- caching

- dns-urile setate

Daca ajunge la DNS-urile setate interogarea pleaca asa:

CLIENT -> intrebare: who is www.rstcenter.com -> ISP -> ROOT DNS SERVERS -> NS-urile domeniului solicitat (aici se returneaza IP catre ISP)

ISP-ul face cache si raspunde clientului: www.rstcenter.com a record is xx.xxx.xxx.xx

Pentru subiectul DNS recomand citirea rfc-urilor urmatoare: 1034, 1035, 1123, 1537, 1912, 1996, 2142 si 2308

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...