
Bugün, "yük dengeleme" yani ecnebilerin deyimiyle "load balancing" kavramını Nginx ve NodeJS özelinde inceleyeceğiz.
Neden yük dengeleme yapmamız gerektiğine, "bir elin nesi var iki elin sesi var" diyerek iyi bir cevap vermiş atalarımız. Aynen öyle. Eğer web uygulamanız tek bir sunucu üzerinde çalışıyorsa ve tüm yükü bu sunucu çekiyorsa haliyle biraz zorlanacatır. Ancak siz bu yükü, aynı işi yapan birden fazla sunucuya paylaştırırsanız, iş çok daha hızlı tamamlanacaktır.
Senaryomuz şöyle olsun;
Üç adet sunucumuz bulunsun. Sunuculardan biri yük paylaşımının yapılacağı, diğer ikisi ise web uygulamasının bulunacağı sunucular olsun.
Server 1
Nginx web sunucusunun kurulu olacağı ve gelen isteklerin diğer web sunucularına nasıl paylaştırılacağına karar veren sunucumuz.
Name: loadbalancer
IP: 192.168.1.11
Server 2
Nodejs web uygulamasının bulunacağı sunucu.
Name: web1
IP: 192.168.1.12
Server 3
Nodejs web uygulamasının bulunacağı diğer sunucu.
Name: web2
IP: 192.168.1.13
Vagrant Yapılandırması
Öncelikle dizin planımızı şöyle hazırlayalım. Resimdeki gibi üç ayrı dizin oluşturalım ve her birinin içerisine Vagrantfile
adında birer dosya oluşturalım.
Vagrantfile
içeriklerimiz aşağıdaki gibi olsun;
server1 / Vagrantfile
NAME = 'loadbalancer'
IP = "192.168.1.11"
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.hostname = NAME
config.vm.network "public_network", ip: IP
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", '2048']
end
end
server2 / Vagrantfile
NAME = 'web1'
IP = "192.168.1.12"
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.hostname = NAME
config.vm.network "public_network", ip: IP
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", '2048']
end
end
server3 / Vagrantfile
NAME = 'web2'
IP = "192.168.1.13"
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.hostname = NAME
config.vm.network "public_network", ip: IP
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", '2048']
end
end
Vagrantfile içeriklerinde değişien tek şey IP adresleri ve sunucu isimleri oldu. Dilerseniz ek konfigürasyonlar ekleyebilirsiniz tabiki.
Şimdi Vagrant sunucularımızı ayağa kaldıralım.
Server1 için;
[email protected]:~/Desktop/loadbalancing/server1$ vagrant up
Server2 için;
[email protected]:~/Desktop/loadbalancing/server2$ vagrant up
Server3 için;
[email protected]:~/Desktop/loadbalancing/server3$ vagrant up
Sunucu konfigürasyonları
Server2 ve Server3
Aşağıdaki işlemleri server2 ve server3 için ayrı ayrı yapmamız gerekiyor.
Bu iki sunucumuzda da aynı web uygulaması bulunacak. Aynı kurulumlar yapılacak.
Web uygulaması NodeJS ile çalışacak. Hızlı bir kurulum yapıp test edebilmek adına express
ile çalışacağız.
NodeJS Kurulumu
[email protected]:~/Desktop/loadbalancing/server2$ vagrant ssh
[email protected]:~$ sudo apt-get update
[email protected]:~$ sudo apt-get install nodejs npm -y
[email protected]:~$ sudo ln -s /usr/bin/nodejs /usr/bin/node
Express kurulumu ve uygulamayı ayağa kaldırmak
[email protected]:~$ sudo npm install express-generator -g
[email protected]:~$ sudo mkdir /var/www && cd /var/www
[email protected]:~$ sudo express .
[email protected]:~$ sudo npm install
[email protected]:~$ npm start
Uygulamamızı ayağa kaldırdık. Hemen test edelim.
Web tarayıcımızdan, web1 ve web2 sunucularımızda koşturan NodeJS uygulamasına erişelim.
http://192.168.1.12:3000
veya
http://192.168.1.13:3000
adreslerine erişmeye çalıştığımızda express' in aşağıdaki karşılama ekranı ile karşılaşacağız. Eğer iki IP adresinde de bu ekran ile karşılaşıyorsak nodejs uygulamasını başarıyla çalıştırmışız demektir.
Server 1
Aşağıdaki komut ile sunucumuzun komut satırı arayüzüne erişelim.
[email protected]:~/Desktop/loadbalancing/server1$ vagrant ssh
Nginx kurulumunu yapalım.
[email protected]:~$ sudo apt-get install nginx -y
Nginx konfigürasyonunu yapalım.
vagra[email protected]:~$ sudo vi /etc/nginx/sites-available/default
Nginx'in varsayılan ayarlarının bulunduğu dosyayı bir komut satırı editörü olan vi
ile açtık. Şimdi bu dosyanın içeriğini tamamen silelim ve aşağıdaki kodları yapıştıralım.
Vi editörünü kullanarak dosya üzerinde değişiklik yapabilmek için insert moduna geçmeniz gerekiyor. Klavyenizden
i
tuşuna basarak bu moda geçebilirsiniz. Insert modundan çıkmak içinescape
tuşuna basmalısınız. Herhangi satırı komple simek için, insert modunda değilkend
tuşuna ardarda iki kere basmalısınız. Dosyayı kaydedip çıkmak için ise yine insert modunda değilken:wq
yazıpenter
tuşuna basmanız gerekiyor. Kaydetmeden çıkmak için ise:q!
. Daha fazlası şurada.
upstream servers {
server 192.168.1.12:3000;
server 192.168.1.13:3000;
}
server {
listen 80;
location / {
proxy_pass http://servers;
}
}
Yukarıdaki kodun upstream
kısmında bulunan IP adresleri web uygulamalarımızın çalıştığı sunucunun ip adresini ve dinlediği portu belirtmekte.
Kaydedip çıkalım ve Nginx'i yeniden başlatalım.
[email protected]:~$ sudo service nginx reload
Şimdi web tarayıcımıza gidelim loadbalancer sunucumuzun IP adresine erişmeye çalışalım.
Eğer bu ekran ile karşılaşıyorsanız, hayırlı olsun nur topu gibi bir load balancer'ınız oldu.
"Yok arkadaş ben inanmadım, kanıtla" dersen de şöyle bir şey yapabiliriz. Web uygulamamızın koştuğu iki ayrı sunucu vardı. Bu sunucuların döndüğü cevabı değiştirelim ve tekrar test edelim. Göreceksiniz ki her refresh yapışınızda farklı sunucuya yönlendirileceksiniz.
Server 2 için (web1)
[email protected]:~/Desktop/loadbalancing/server2$ vagrant ssh
[email protected]:~$ sudo vi routes/index.js
Aşağıdaki satırı,
res.render('index', { title: 'Express' });
Aşağıdaki satır ile değiştirelim.
res.render('index', { title: 'Served from Web1' });
Server 3 için (web2)
[email protected]:~/Desktop/loadbalancing/server3$ vagrant ssh
[email protected]:~$ sudo vi routes/index.js
Aşağıdaki satırı,
res.render('index', { title: 'Express' });
Aşağıdaki satır ile değiştirelim.
res.render('index', { title: 'Served from Web2' });
Şimdi http://192.168.1.11/ adresine gidin ve sayfayı hızlıca yenileyin. Göreceksiniz ki en müsait sunucu hangisi ise ona yönlendirileceksiniz.
Performans testleri
Şimdi load balancerdan önce ve sonraki performans durumuna bakalım.
Apache Benchmark
aracı ile testimizi yapalım.
n: Gerçekleştirilecek istek sayısı
c: Bir seferde gerçekleştirilecek birden çok istek sayısı.
Load balancer olmadan
[email protected]:~$ ab -n 2000 -c 100 http://192.168.1.12:3000/
Sonuç
Server Software:
Server Hostname: 192.168.1.12
Server Port: 3000
Document Path: /
Document Length: 197 bytes
Concurrency Level: 100
Time taken for tests: 16.932 seconds
Complete requests: 2000
Failed requests: 0
Total transferred: 786000 bytes
HTML transferred: 394000 bytes
Requests per second: 118.12 [#/sec] (mean)
Time per request: 846.616 [ms] (mean)
Time per request: 8.466 [ms] (mean, across all concurrent requests)
Transfer rate: 45.33 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.4 0 10
Processing: 55 826 138.7 819 1171
Waiting: 55 825 138.7 819 1171
Total: 57 827 138.1 820 1172
Percentage of the requests served within a certain time (ms)
50% 820
66% 857
75% 894
80% 916
90% 954
95% 1017
98% 1086
99% 1154
100% 1172 (longest request)
Load balancer ile
[email protected]:~$ ab -n 2000 -c 100 http://192.168.1.11/
Sonuç
Server Software: nginx/1.4.6
Server Hostname: 192.168.1.11
Server Port: 80
Document Path: /
Document Length: 197 bytes
Concurrency Level: 100
Time taken for tests: 12.773 seconds
Complete requests: 2000
Failed requests: 0
Total transferred: 846000 bytes
HTML transferred: 394000 bytes
Requests per second: 156.59 [#/sec] (mean)
Time per request: 638.629 [ms] (mean)
Time per request: 6.386 [ms] (mean, across all concurrent requests)
Transfer rate: 64.68 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.9 0 19
Processing: 39 622 182.3 592 1024
Waiting: 39 622 182.3 592 1024
Total: 41 623 182.1 595 1024
Percentage of the requests served within a certain time (ms)
50% 595
66% 672
75% 743
80% 821
90% 900
95% 938
98% 967
99% 974
100% 1024 (longest request)
Kapanış
Test sonuçlarına baktığımızda 2000 isteğin karşılanması için;
Geçen Zaman
Load balancer olmadan: 16.932sn
Load balancer ile: 12.773sn
Saniyede karşılanan istek sayısı
Load balancer olmadan: 118.12
Load balancer ile: 156.59
Fark ortada. Toplam 2000 istekte 4 saniyenin biraz üzerinde kârımız var ve saniyede 38 tane fazladan istek işlemiş olduk.
Oldu o zaman kaçtım ben.
