OpenLiteSpeed ile WebSocket Desteği Yapılandırması

Gerçek zamanlı uygulamalar geliştirip production’a almaya çalışırken WebSocket bağlantılarının neden çalışmadığını anlamak için saatler harcadıysanız, bu yazı tam size göre. OpenLiteSpeed, LiteSpeed’in açık kaynak versiyonu olarak harika bir performans sunuyor ancak WebSocket yapılandırması konusunda dokümantasyon biraz dağınık ve Türkçe kaynak neredeyse yok. Bu yazıda sıfırdan başlayarak OpenLiteSpeed üzerinde WebSocket desteğini nasıl yapılandıracağınızı, sık karşılaşılan sorunları ve gerçek dünya senaryolarını ele alacağım.

WebSocket Nedir ve Neden OpenLiteSpeed ile Uğraşıyoruz?

WebSocket, HTTP’nin aksine kalıcı bir bağlantı kurarak sunucu ile istemci arasında çift yönlü iletişim sağlayan bir protokoldür. Chat uygulamaları, canlı bildirimler, oyun sunucuları, gerçek zamanlı dashboard’lar ve hisse senedi takip uygulamaları WebSocket’in olmazsa olmaz olduğu yerlerdir.

Apache veya Nginx ile karşılaştırdığınızda OpenLiteSpeed’in WebSocket için farklı bir yapılandırma mantığı var. Nginx’te proxy_pass ile birkaç satır ekleyip işi bitiriyorsunuz. OpenLiteSpeed’de ise web arayüzü üzerinden veya konfigürasyon dosyaları aracılığıyla biraz daha fazla adım atmanız gerekiyor. Ama bir kez doğru kurduğunuzda, OpenLiteSpeed’in event-driven mimarisi sayesinde Nginx’ten bile daha iyi concurrent connection yönetimi elde ediyorsunuz.

Ön Gereksinimler

Başlamadan önce şunlara ihtiyacınız var:

  • OpenLiteSpeed 1.7.x veya üzeri kurulu bir sistem
  • Arka tarafta çalışan bir WebSocket uygulaması (Node.js, Python, Go, vs.)
  • Temel Linux komut satırı bilgisi
  • OpenLiteSpeed admin paneline erişim (varsayılan port 7080)

Sisteminizde OpenLiteSpeed kurulu değilse hızlıca kuralım:

# Ubuntu/Debian için
wget -O - https://repo.litespeed.sh | sudo bash
sudo apt-get install openlitespeed

# CentOS/RHEL için
sudo rpm -Uvh https://repo.litespeed.sh/lsrepo-1.1-1.el7.noarch.rpm
sudo yum install openlitespeed

# Kurulumu doğrula
/usr/local/lsws/bin/lshttpd -v

OpenLiteSpeed kurulduktan sonra admin şifresini ayarlamanız gerekiyor:

sudo /usr/local/lsws/admin/misc/admpass.sh

Test WebSocket Sunucusu Oluşturma

Yapılandırmayı test etmek için basit bir Node.js WebSocket sunucusu ayarlayalım. Bu, gerçek dünyada kullanacağınız uygulamanın yerini tutacak:

# Node.js kurulu değilse
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# ws modülünü kur
mkdir /opt/wsapp && cd /opt/wsapp
npm init -y
npm install ws

Sonra basit bir WebSocket sunucusu oluşturalım:

cat > /opt/wsapp/server.js << 'EOF'
const WebSocket = require('ws');
const http = require('http');

const server = http.createServer((req, res) => {
  if (req.url === '/health') {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('OK');
    return;
  }
  res.writeHead(426, { 'Content-Type': 'text/plain' });
  res.end('Upgrade Required');
});

const wss = new WebSocket.Server({ server });

wss.on('connection', (ws, req) => {
  console.log(`Yeni bağlantı: ${req.socket.remoteAddress}`);
  
  ws.on('message', (message) => {
    console.log(`Mesaj alındı: ${message}`);
    ws.send(`Echo: ${message}`);
  });

  ws.on('close', () => {
    console.log('Bağlantı kapandı');
  });

  ws.send('Bağlantı başarılı!');
});

const PORT = 3000;
server.listen(PORT, '127.0.0.1', () => {
  console.log(`WebSocket sunucusu port ${PORT} üzerinde çalışıyor`);
});
EOF

Uygulamayı systemd ile yönetelim ki sistem yeniden başlatıldığında otomatik çalışsın:

cat > /etc/systemd/system/wsapp.service << 'EOF'
[Unit]
Description=WebSocket Test Uygulamasi
After=network.target

[Service]
Type=simple
User=nobody
WorkingDirectory=/opt/wsapp
ExecStart=/usr/bin/node /opt/wsapp/server.js
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=wsapp
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable wsapp
systemctl start wsapp
systemctl status wsapp

Servisin çalıştığını doğrulayın:

# Port dinleniyor mu?
ss -tlnp | grep 3000

# Health endpoint çalışıyor mu?
curl http://127.0.0.1:3000/health

OpenLiteSpeed WebAdmin Üzerinden Yapılandırma

OpenLiteSpeed’in güçlü yanlarından biri web tabanlı admin paneli. Tarayıcınızdan http://sunucu-ip:7080 adresine gidin ve giriş yapın.

External App (Proxy) Tanımlama

WebSocket trafiğini yönlendirmek için önce bir External App tanımlamanız gerekiyor.

Sol menüden Server Configuration > External App yolunu izleyin. Add butonuna tıklayın ve şu değerleri girin:

  • Type: Web Server
  • Name: wsbackend
  • Address: 127.0.0.1:3000
  • Max Connections: 100
  • Connection Keepalive Timeout: 60
  • Response Timeout: 300
  • Retry On Failure: Yes

WebSocket için önemli olan kısım burada: Keep-Alive Timeout değerini yüksek tutmanız gerekiyor. Aksi takdirde OpenLiteSpeed bağlantıyı erken kesecek ve WebSocket handshake’i başarısız olacak.

Virtual Host Context Yapılandırması

Şimdi virtual host’unuza gidip WebSocket yönlendirmesi için bir context ekleyelim. Virtual Hosts > [VHost Adınız] > Context bölümüne geçin.

Add butonuna tıklayın:

  • Type: Proxy
  • URI: /ws/
  • Web Server: wsbackend
  • Header Operations: X-Forwarded-Proto $scheme ve X-Forwarded-For $remote_addr ekleyin

Bu konfigürasyonla /ws/ path’ine gelen tüm istekler arka taraftaki Node.js uygulamanıza yönlendirilecek.

Konfigürasyon Dosyası ile Yapılandırma

Web arayüzü bazen yavaş kalabiliyor ve CI/CD pipeline’larınızda dosya bazlı yapılandırma çok daha pratik. OpenLiteSpeed konfigürasyon dosyaları /usr/local/lsws/conf/ altında bulunuyor.

ls -la /usr/local/lsws/conf/

Virtual host konfigürasyon dosyasını düzenleyelim:

# Virtual host konfigürasyonu genellikle burada
cat /usr/local/lsws/conf/vhosts/Example/vhconf.conf

WebSocket desteği için extapp ve context bölümlerini ekleyin:

# /usr/local/lsws/conf/vhosts/yoursite/vhconf.conf
# extapp bloğunu ekleyin

extApp proxy wsbackend {
  address                 127.0.0.1:3000
  maxConns                100
  pcKeepAliveTimeout      60
  initTimeout             60
  retryTimeout            0
  respBuffer              0
}

context /ws/ {
  type                    proxy
  handler                 wsbackend
  addDefaultCharset       off
}

Değişiklikleri uygulamak için graceful restart yapın:

# Graceful restart - mevcut bağlantıları kesmez
kill -USR1 $(cat /usr/local/lsws/logs/lsws.pid)

# Ya da admin panel üzerinden
# Actions > Graceful Restart

SSL/TLS ile WebSocket (WSS) Yapılandırması

Production ortamında mutlaka WSS (WebSocket Secure) kullanmalısınız. HTTP üzerinden çalışan WS bağlantıları man-in-the-middle saldırılarına açık. OpenLiteSpeed ile Let’s Encrypt entegrasyonu oldukça kolay:

# certbot kurulumu
sudo apt-get install certbot

# Sertifika al (OpenLiteSpeed 80 portundan çekmeyi deneyin)
sudo systemctl stop lsws
sudo certbot certonly --standalone -d yourdomain.com
sudo systemctl start lsws

Veya OpenLiteSpeed’in kendi ACME client’ını kullanabilirsiniz. Admin panelinden WebAdmin > SSL bölümüne gidin.

SSL konfigürasyonunu dosya bazlı yapmak isterseniz:

# vhconf.conf içinde SSL listener konfigürasyonu
vhssl  {
  keyFile                 /etc/letsencrypt/live/yourdomain.com/privkey.pem
  certFile                /etc/letsencrypt/live/yourdomain.com/fullchain.pem
  certChain               1
  sslProtocol             24
  enableECDHE             1
  renegProtection         1
  sslSessionCache         1
  enableSpdy              15
}

WSS için listener’ı da güncellemeniz gerekiyor. httpd_config.conf dosyasında:

listener HTTPS {
  address                 *:443
  secure                  1
  keyFile                 /etc/letsencrypt/live/yourdomain.com/privkey.pem
  certFile                /etc/letsencrypt/live/yourdomain.com/fullchain.pem
  map                     yourdomain.com yourdomain.com
}

Gerçek Dünya Senaryosu: Chat Uygulaması

Diyelim ki bir müşteri için gerçek zamanlı müşteri destek chat sistemi kuruyorsunuz. Uygulama birden fazla instance çalıştırıyor ve yük dengelemeniz gerekiyor. Bu senaryoda OpenLiteSpeed cluster yapılandırması işe yarıyor.

Birden fazla WebSocket sunucusu için load balancing:

# Backend cluster tanımı
extApp proxy wscluster {
  address                 127.0.0.1:3000, 127.0.0.1:3001, 127.0.0.1:3002
  maxConns                100
  pcKeepAliveTimeout      60
  initTimeout             60
  retryTimeout            0
  respBuffer              0
}

context /chat/ {
  type                    proxy
  handler                 wscluster
  addDefaultCharset       off
}

Önemli not: WebSocket uygulamalarında sticky session (oturum yapışkanlığı) kritik önem taşıyor. Bir kullanıcının bağlantısı her seferinde farklı bir backend’e giderse oturum bilgileri kaybolur. Bu sorunu aşmak için Redis gibi bir shared state store kullanın veya IP hash bazlı yönlendirme yapın.

Sorun Giderme

502 Bad Gateway Hatası

Bu en sık karşılaşılan sorundur. Birkaç şeyi kontrol edin:

# Backend uygulaması çalışıyor mu?
systemctl status wsapp
ss -tlnp | grep 3000

# OpenLiteSpeed error loguna bakın
tail -f /usr/local/lsws/logs/error.log

# Virtual host loguna bakın
tail -f /usr/local/lsws/logs/yoursite.access.log

WebSocket Handshake Başarısız

Tarayıcı konsolunda WebSocket connection failed hatası görüyorsanız:

# Header'ları kontrol edin
curl -v -H "Upgrade: websocket" 
     -H "Connection: Upgrade" 
     -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" 
     -H "Sec-WebSocket-Version: 13" 
     http://yourdomain.com/ws/

OpenLiteSpeed’in WebSocket upgrade header’larını doğru iletip iletmediğini kontrol etmek için backend uygulamanıza gelen header’ları loglayın. Sorun genellikle Upgrade ve Connection header’larının proxy’den geçememesidir.

Bağlantı Zaman Aşımı

Uzun süre aktif olmayan WebSocket bağlantıları düşüyorsa:

# vhconf.conf'ta timeout değerlerini artırın
extApp proxy wsbackend {
  address                 127.0.0.1:3000
  pcKeepAliveTimeout      300    # 5 dakika
  initTimeout             120
  respBuffer              0
}

Ayrıca uygulama tarafında ping/pong mekanizması ekleyin:

# Node.js WebSocket sunucusuna heartbeat ekleyin
wss.on('connection', (ws) => {
  ws.isAlive = true;
  
  ws.on('pong', () => {
    ws.isAlive = true;
  });
});

const heartbeatInterval = setInterval(() => {
  wss.clients.forEach((ws) => {
    if (!ws.isAlive) {
      return ws.terminate();
    }
    ws.isAlive = false;
    ws.ping();
  });
}, 30000);

Güvenlik Yapılandırması

WebSocket endpoint’lerinizi herkese açık bırakmak ciddi güvenlik riskleri doğurur. OpenLiteSpeed üzerinde birkaç temel güvenlik katmanı ekleyin.

Rate limiting için admin panelinden Server Configuration > Security > Per Client Throttle bölümüne gidin:

  • Static Requests/Second: 50
  • Dynamic Requests/Second: 20
  • Outbound Bandwidth: İhtiyaca göre

Belirli IP’lerden gelen bağlantıları engellemek veya izin vermek için rewrite kuralları kullanabilirsiniz:

# Rewrite kuralı ile WebSocket endpoint koruması
# vhconf.conf içine ekleyin

rewrite  {
  enable                  1
  rules                   <<<END_rules
RewriteCond %{HTTP:Upgrade} !websocket [NC]
RewriteCond %{REQUEST_URI} ^/ws/
RewriteRule .* - [F]
END_rules
}

Bu kural /ws/ path’ine gelen ve WebSocket upgrade header’ı içermeyen tüm istekleri reddeder. Normal HTTP ile API endpoint’lerinizi taramaya çalışan botları bu şekilde engelleyebilirsiniz.

Performans İyileştirmeleri

OpenLiteSpeed zaten event-driven bir mimariyle geliyor ama WebSocket için özel bazı ayarlar yapmanız performansı önemli ölçüde artırıyor.

httpd_config.conf dosyasında tuner bölümünü güncelleyin:

tuning  {
  maxConnections          20000
  maxSSLConnections       10000
  connTimeout             300
  maxKeepAliveReq         1000
  keepAliveTimeout        15
  sndBufSize              0
  rcvBufSize              0
  maxReqURLLen            32768
  maxReqHeaderSize        65536
  maxReqBodySize          2047M
  maxDynRespHeaderSize    32768
  maxCachedFileSize       4096
  totalInMemCacheSize     20M
  totalMMAPCacheSize      40M
  useSendfile             1
  fileETag                28
  enableGzipCompress      1
  enableBrCompress        4
  enableDynGzipCompress   1
  gzipCompressLevel       6
  brCompressLevel         6
}

maxConnections değerini sunucu RAM’inize göre ayarlayın. Her WebSocket bağlantısı ortalama 10-50KB memory kullanır. 4GB RAM’li bir sunucuda güvenli olarak 10.000-20.000 concurrent WebSocket bağlantısı tutabilirsiniz.

Ayrıca işletim sistemi seviyesinde bazı ayarlar yapmanız gerekiyor:

# /etc/sysctl.conf dosyasına ekleyin
cat >> /etc/sysctl.conf << 'EOF'
# WebSocket ve yüksek bağlantı sayısı için
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
fs.file-max = 1000000
EOF

sysctl -p

# Açık dosya limiti için
cat >> /etc/security/limits.conf << 'EOF'
nobody soft nofile 200000
nobody hard nofile 200000
EOF

Monitoring ve Logging

WebSocket bağlantılarını izlemek için OpenLiteSpeed’in built-in istatistiklerini kullanabilirsiniz:

# Anlık bağlantı sayısı
cat /tmp/lshttpd/.rtreport | grep -E "conn|req"

# Log formatını özelleştirin, WebSocket upgrade isteklerini ayrı tutun
# vhconf.conf içinde
accessLog /usr/local/lsws/logs/ws_access.log {
  useServer               0
  logFormat               "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i" "%{Upgrade}i""
  logHeaders              9
  rollingSize             10M
  keepDays                7
}

Gerçek zamanlı monitoring için watch komutu ile basit bir takip yapabilirsiniz:

# Aktif WebSocket bağlantılarını sayın
watch -n 2 'ss -tnp | grep :3000 | wc -l'

Production ortamında Prometheus + Grafana kombinasyonu çok daha iyi görünürlük sağlar. OpenLiteSpeed için bir lsws_exporter scripti yazarak metrikleri Prometheus’a gönderebilirsiniz.

Sonuç

OpenLiteSpeed üzerinde WebSocket yapılandırması ilk başta karmaşık görünebilir, özellikle Apache veya Nginx’ten geliyorsanız. Ama temel mantığı kavradıktan sonra, yani External App tanımı, Proxy Context ve doğru timeout değerleri üçlüsünü oturtunca gerisi oldukça düzgün işliyor.

Özetlemek gerekirse en kritik noktalar şunlar:

  • pcKeepAliveTimeout değerini yeterince yüksek tutun, yoksa bağlantılar beklenmedik şekilde kapanır
  • Backend uygulamanızda ping/pong heartbeat mekanizması mutlaka olsun
  • Production’da her zaman WSS kullanın, plain WS sadece geliştirme ortamına uygun
  • Yüksek concurrent bağlantı bekliyorsanız işletim sistemi seviyesindeki limitleri unutmayın
  • Sticky session gerektiren uygulamalarda shared state store (Redis) kullanmayı ihmal etmeyin

OpenLiteSpeed’in gerçekten öne çıktığı nokta HTTP/3 ve QUIC protokolleri ile WebSocket’i birlikte çalıştırabilmesi. Nginx hala bu konuda çeşitli sınırlamalar içerirken OpenLiteSpeed bu alanda oldukça ileri durumda. Yüksek trafikli gerçek zamanlı uygulama altyapısı kuruyorsanız OpenLiteSpeed’i ciddiye almanızı tavsiye ederim.

Sorularınız veya karşılaştığınız farklı senaryolar varsa yorumlarda paylaşın, birlikte çözeriz.

Yorum yapın