Nginx,apache,Lighttpd Performans Kıyaslaması

Çalışma mantığı ve yaklaşım farkları :
Apache Multithread çalışıyor. ( Her bir domain ve/veya projeniz için ayrı bir apache process’i yaratıldığını düşünün. )
Nginx Singlethread ve yanısıra Worker desteği ile çalışıyor. ( Her bir isteğin tek bir thread karşılandığını ancak duruma göre farklı bir Worker üzerine aktarıldığını düşünebilirsiniz. )
Lighttpd Singlethread çalışıyor. ( Tüm istekleri tek bir thread üzerinden alıp aynı thread ile işleyip yine geriye aynı yol üzerinden cevap veriyor. )
İhtiyaç duydukları donanım türüne göre performans sıralaması :

Ram Kullanımı : Lighttpd < Nginx < Apache
Burda en çok ram kullanımı apache de en az lighttpd

Cpu Kullanımı : Nginx < Lighttpd < Apache

En çok cpu yu apache kullanıyor yine en az cpu kullanan nginx.
Sunucuya göre;

Eğer sunucumda cpu ve ram problemim yoksa her an herşeye çözüm üretmem gerekecekse ve geniş destek içeriğine ihtiyacım varsa Apache.
Eğer sunucum bir VPS ise özellikle cpu kullanım oranı benim için problem olacaksa Nginx .
Eğer sunucum bir  VPS ise özellikle ram kullanımı benim için sıkıntı oluyorsa Lighttpd.

tavsiye ediliyor.

Projemde çok fazla istek yapılmıyor ( çok fazla ziyaretçim yoksa, ajax, rpc gibi diğer isteklerin cevapları önemli miktarda değil ise )  ancak çok fazla yazılımsal iş yükü varsa Apache.
Projemde istek ve sayfa gösterim oranları çok yüksek yazılımsal iş yükü ağır ve projelerimde bol dinamik içerik varsa Nginx.
Projemde yazılımsal iş yükü fazla yoksa, dinamik içerikden ziyade statik içeriği aşırı yoğun ziyaretçi yüküne karşı hatasız sunmam gerekiyorsa Lighttpd.

tavsiye ediliyor.
Nginx Apache ve lighttp arasında ram kullanım grafiği

Bir saniyede cevap verilen request sayısının grafiği

CSS dosyasına erişim (bootstrap.min.css)Nginx Ve Apache
Tek bir istek için karşılaşılan sonuç :

Toplu isteklerde

Bu test sonucunda, Nginx’in statik içerikleri sunma noktasında “toplu isteklerde” Apache2’ den en az 3 kat daha performanslı olduğu sonucuna ulaşıyoruz.

Salt PHP (“Merhaba Dünya”) Testi
Bu test ile en basit PHP kodunun çalıştırılıp istemciye ulaştırılmasında Apache ve Nginx’ in başarımlarının nasıl olduğunu öğreniyoruz. tek bir istek için :
Toplu istekler için sonuç:
Bu test ile; en basit PHP kodunun işletilmesi ve istemciye iletilmesinde, Nginx’in 1 request için %25 daha performanslı olduğunu; istek sayısı arttıkça bu farkın %100’e yaklaştığını gözlemliyoruz.


Symfony 3.1 (“Merhaba {name}”) Testi
Bu test ile en basit Symfony kodunun çalıştırılıp client’a ulaştırılmasında Apache ve Nginx’ in başarımlarının nasıl olduğunu öğreniyoruz. Tek istek için

Toplu istekler için Apache2 ve Nginx’ten aldığımız requests/second değerleri:
Önceki testin bulgusu olan, Nginx’in en basit PHP kodu işletimi ve istemciye iletimindeki %25’lik performans farkı; aynı işi Symfony3 ile yaptığımızda yaklaşık %30’luk bir performans farkına dönüşüyor ve fark daha da artıyor.

Veritabanına 10 yeni kayıt gir
Doctrine ORM ile çok basit bir entity ’nin art arda oluşturulan 10 instance’ ının veritabanına kaydedilmesine ait kodun çalıştırılıp “işlem başarılı” mesajının istemciye ulaştırılmasında Apache ve Nginx’in başarımlarının nasıl olduğunu değerlendirdim. Bir tane istek için aşağıdaki karşılaştırmayı alıyoruz:
Toplu istekler için Apache2 ve Nginx’ten aldığımız requests/second değerleri:
Bir istek için Nginx, Apache2’den %100 daha performanslı olsa da, istek sayısı arttıkça aradaki farkın kapandığını görüyoruz. Ancak bu seviyede INSERT yaparken halâ Nginx kayda değer ölçüde daha performanslı.

Veritabanından 1000 kayıt oku ve görüntüle
Doctrine ORM ile çok basit bir entity’ye ait veritabanında 1000 kaydın sorgulanması, Object olarak hydrate edilmesi ve Basit bir twig döngüsü içinde kullanıcıya gösterilmesi Adımlarını içeren kodun çalıştırılıp istemciye ulaştırılmasında Apache ve Nginx’in başarımlarının nasıl olduğunu görüyoruz. Bir tane istek için aşağıdaki karşılaştırmayı alıyoruz:
Toplu istekler için Apache2 ve Nginx’ten aldığımız requests/second değerleri:
Neredeyse bütün testler Nginx, Apache2’yi ezmiş olsa da; bu testin sonucu Apache2’nin tartışılmaz galibiyeti ile sonuçlandı. Bu durum dikkat çekici.
Test Sonuçları — Toplu olarak
Share:

Django-Nginx-Postgresql Ubuntu Sunucusu Oluşturma

Django Virtualenv Pip Kurulum
Önce python3 ve pip3' ü kuruyoruz.
sudo apt-get install python3-pip python3-dev
Ardından gunicorn, virtualenv ve django'yu
pip install django virtualenv gunicorn

Postgresql kurulum ve ayarlar
sudo apt-get install postgresql postgresql-contrib libpq-dev
Yüklememiz bittikten sonra
pip install psycopg2
psycopg2' yi kuruyoruz. Veri tabanı oluşturmak için.Sırasıyla
su - postgres
psql
Kullanici ve şifresi oluşturduk.
CREATE USER userAdi WITH PASSWORD 'userSifresi';
veritabaniAdi adında bir veritabani oluşturup sahipliğide oluşturduğumuz kullanıcıya verdik.Aşağıda ki komutla.
CREATE DATABASE veritabaniAdi OWNER userAdi;

Yeni Linux Kullanici Oluşturulması
Bu komutla linuxKullaniciAdi adında bir kullanici oluşturuyoruz.
sudo useradd -m -s /bin/bash linuxKullaniciAdi
Bu komutla da şifresini ayarlıyoruz.
sudo passwd linuxKullaniciAdi
linuxKullaniciAdi adında ki kullanciya giriş yapalım.
su - linuxKullaniciAdi
Proje için myproject bir klasör oluturuyoruz.
mkdir myproject
Virtualenv oluşturuyoruz myproject klasörü içine
virtualenv --python=python3 myproject/
myproject klasörüne girelim ve virtualenvi aktifleştirelim
cd myproject/
source bin/activate
Pip kullanarak oluşturduğumuz virtualenv'e python,django ve psycopg2 yi kuralım.
pip install django gunicorn psycopg2
Örnek olarak hello_django adında bi uygulama başlatalım.

Postgresql ile birlikte Yeni Uygulama Oluşturmak
django-admin startproject hello_django
proje klasörü içinde hello_django adında bir klasör oluşturuldu. hello_django/settings.py içinde ki settings.py klasörünü düzenlemek için herhangi bir metin editörüyle açtığımızda Veritabanina bağlanmak için gereken ayarlar bulunmakta.Aşağıda ki şekilde değiştiriyoruz.Database Settings kısmını 76.Satırda.

        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'veritabaniAdi',
        'USER': 'userAdi',
        'PASSWORD': 'userSifresi',
        'HOST': 'localhost',
        'PORT': '',
Ardından settings.py içerisine STATIC_ROOT u eklemek zorundayız.Bunu eklemezsek css dosyalarını bulamıyor nginx.
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Kaydedip çıkalım.Ardından sırasıyla
python manage.py migrate
admin paneline giriş için kullanıcı oluşturuyoruz.
python manage.py createsuperuser
Static dosyaları otomatik olarak oluşturmak için.
python manage.py collectstatic
Dedikten sonra projeyi başlatalım.Böyle yaparsak server yerelde çalışacaktır.
python manage.py runserver 
Kendi ip'miz üzerinden yayın yapmak istiyorsak.
python manage.py runserver 0.0.0.0:8000
diyerek yayın yapabiliriz artık ipv4 adresi: 8000 yazılarak sunucuya bağlanılabilir. Mesela bende 192.168.1.4:8000 yaptığım zaman diğer cihazlardan çalışan sunucuya bağlanabiliyorum.

Django projesi ve Gunicorn Ayarları proje klasörüne girip virtualenv'i aktifleştirelim.
cd /myproject/
source bin/activate
bin klasörünün içine gunicorn_start adında yeni bir dosya oluşturalım.
nano bin/gunicorn_start
Dosyanın içine

#!/bin/bash

# Project Name
NAME="hello_django"                        

# Django Project Directory
DJANGODIR=/home/linuxKullaniciAdi/myproject/hello_django           

# Run gunicorn on the socket file
SOCKFILE=/home/linuxKullaniciAdi/myproject/hello_django/run/gunicorn.sock
 
# Gunicorn running as user and group
USER=linuxKullaniciAdi
GROUP=linuxKullaniciAdi
 
# Workers
NUM_WORKERS=3
 
#Module Setting
#replace hello_django with your project name
DJANGO_SETTINGS_MODULE=hello_django.settings
DJANGO_WSGI_MODULE=hello_django.wsgi
 
echo "Starting $NAME as `whoami`"
 
# Activate the virtual environment
cd $DJANGODIR
source ../bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
 
# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
 
# Start your Django Unicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--bind=unix:$SOCKFILE \
--log-level=debug \
--log-file=-
Kaydedip çıkalım. Sonra chmod kullanarak oluşturduğumuz gunicorn_start dosyayı çalıştırılabilir hale getirelim
chmod u+x bin/gunicorn_start

Supervisor Kurulumu ve Ayarları
Supervisor linux ortamlarinda processleri kontrol altinda tutmaya yarayan yazilim. Surekli calismasini istediginiz bir yazilim varsa veya bunu bir sekilde yazilim crash ettiginde vb servis (bkz: service) gibi yeniden calistirma ozelligine sahiptir. supervisor kurulumu için
sudo apt-get install supervisor
Supervisor'un ayar dosyaları
/etc/supervisor
, içinde bulunmakta.Bu klasöre gidelim ve yeni bir dosya oluşturalım.

cd /etc/supervisor/conf.d/
nano hello-django.conf
Dosyanın içine

[program:hello_django]
command = sh /home/linuxKullaniciAdi/myproject/bin/gunicorn_start
user = linuxKullaniciAdi
stdout_logfile = /home/linuxKullaniciAdi/myproject/logs/gunicorn_supervisor.log
redirect_stderr = true
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8
Şimdi oluşturduğumuz linuxKullaniciAdi adında ki kullanıcıya giriş yapalım.
su - linuxKullaniciAdi
Gunicorn socket dosyası oluşturmak için proje içinde run adında bi klasör oluşturalım.
mkdir -p myproject/hello_django/run/
Supervisor loglarının tutulduğu klasör oluşturalım

mkdir -p myproject/logs/
touch myproject/logs/gunicorn_supervisor.log
şimdi supervisor servisini başlatacağız.
 sudo systemctl start supervisor 
Logları kontrol edelim.

sudo supervisorctl
tail -f hello_django
Dediğimizde çalıştırdığımız servisin loglarını görürüz. Örneğin şöyle bir çıktı

Nginx kurulumu ve Ayarları
Nginx kurulumu için
sudo apt-get install nginx
Nginx config dosyaları
/etc/nginx/sites-available/
içinde bulunmakta klasör içine girelim ve nginx config dosyası oluşturalım.

cd /etc/nginx/sites-available/
nano hello_django
içine

# Django running with Gunicorn Sock file
upstream hello_django_project {
    server unix:/home/linuxKullaniciAdi/myproject/hello_django/run/gunicorn.sock fail_timeout=0;
}
 
server {
 
    listen   80;
    server_name yayinYapilacakOlanAdresinAdi.com;
 
    client_max_body_size 4G;
 
    access_log /home/linuxKullaniciAdi/myproject/logs/nginx-access.log;
    error_log /home/linuxKullaniciAdi/myproject/logs/nginx-error.log;
 
    location /static/ {
        alias   /home/linuxKullaniciAdi/myproject/hello_django/static/;
    }
 
    location /media/ {
        alias   /home/linuxKullaniciAdi/myproject/hello_django/media/;
    }
 
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
 
    # Try to serve static files from nginx, no point in making an
    # *application* server like Unicorn/Rainbows! serve static files.
    if (!-f $request_filename) {
        proxy_pass http://hello_django_project;
        break;
        }
    
 
# Error pages
    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /home/linuxKullaniciAdi/myproject/hello_django/static/;
        }
    }
}
Kaydedip çıktıptan sonra test edelim.
sudo ln -s /etc/nginx/sites-available/hello_django /etc/nginx/sites-enabled/
sudo nginx -t
hata yoksa sıkıntı yok. Nginx i yeniden başlatalım.
systemctl restart nginx
Bitti.Artık siteye girip test kontrol edebiliriz.

netstat -pl
komutu ile de kontrol edebiliriz.
Share:

SSH Sonlandırdıktan Sonra Processlerin Çalışmaya Devam Etmesi

Bir processin ssh bağlantısı sonlandırdıktan sonra sonlanmasını önlemek için bir çok yöntem var. Bu yöntemlerden biri screen aracını kullanmak
ssh ile bağlantı yaptıktan sonra
$>ssh username@domain-adi
$>screen            
$>çalışmasını istediğimiz processadı

çalıştırdıktan sonra CTRL + A ardından CTRL + D ile screen sessiona detach ediyoruz processi
ardından çıkış yapsakda process çalışmaya devam ediyor.
Share: