Yazının başlığı her ne kadar HTTP/2 hakkında her şey olsa da bu yazıda günlük hayatımızın bir parçası haline gelmiş olan bu popüler protokolün yeni bir sürümüne neden ihtiyaç duyduğumuzu açıklamaya çalışacağım, HTTP/2 standardının ayrıntılarına ise çok fazla değinmeyeceğim.
HTTP/2
HTTP/2 standardı HTTP protokolünün 1999 yılında yayınlanmış 1.1 sürümünden sonraki ilk yeni sürümü olacak. SPDY üzerine kurulu olan HTTP/2, IETF'nin httpbis çalışma grubu tarafından geliştiriliyor.
Hedefler
- İstemci ve sunucuların HTTP 1.1, 2.0 ve hatta olası diğer protokolleri kullanmayı seçebilmelerini sağlayan bir müzakere mekanizması sunmak.
- HTTP 1.1 ile yüksek oranda uyumlu olmak.
-
Gecikmeyi azaltarak web tarayıcılarının sayfa yükleme performansını artırmak amacıyla:
- HTTP başlıklarını sıkıştırma
- Server push teknolojileri
- HTTP 1.1 içindeki HOL blocking problemini çözme
- Tek bir TCP bağlantısı üzerinden sayfa elemanlarını paralel olarak yükleme
Tarayıcı desteği
- Chrome
- Firefox 34+: Şu anda yalnızca TLS üzerinden HTTP/2 gerçeklenmiş durumda.
- Windows 10 Technical Preview üzerinde IE 11: Şu anda yalnızca TLS üzerinden HTTP/2 gerçeklenmiş durumda.
HTTP persistent connection
Şimdi HTTP/2'ye giden yoldan hep beraber yürümeye çalışalım. İlk sapağımız olan HTTP persistent connection(kalıcı bağlantı), HTTP keep-alive ya da HTTP connection reuse olarak da isimlendirilebiliyor. Bu yöntem her bir istek/yanıt çifti için yeni bir bağlantı açmak yerine tek bir TCP bağlantısı üzerinden birden fazla HTTP istek ve yanıtını gönderip almayı sağlıyor.
HTTP 1.0
HTTP 1.0 sürümünde eğer istemci keep-alive destekliyorsa isteğe Connection: Keep-Alive başlığını ekler. Sunucu bir yanıt ürettiğinde o da yanıta Connection: Keep-Alive başlığını ekler.
HTTP 1.1
HTTP 1.1 sürümünde aksi belirtilmediği sürece tüm bağlantılar kalıcı kabul edilirler. Aşağıdaki şekilde kalıcı ve çoklu bağlantıların zamana göre akışını görebiliyoruz.
Avantajları
- Daha az CPU ve bellek kullanımı (çünkü daha az bağlantı açılır)
- HTTP pipelining kullanılabilmesine olanak sağlar
- Ağ tıkanıklığını azaltır (daha az TCP bağlantısı)
- Art arda isteklerde daha az gecikme (TCP handshaking yapılmadığı için)
HTTP pipelining
İkinci sapağımız olan HTTP pipelining tek bir TCP bağlantısı üzerinden birden fazla HTTP isteğinin karşılık gelen yanıtları beklemeden gönderilmesi yöntemidir. Aşağıdaki şekilde HTTP pipelining yokken ve varken oluşan akışı görebiliyoruz.
HTTP pipelining ile gelen hız kazancı geniş bant bağlantılarda daha az hissedilir. Bunun ana nedeni HTTP 1.1 standardına göre sunucunun yanıtları isteklerin alınma sırasına göndermek zorunda olmasıdır. Bu sebeple tüm bağlantı first-in-first-out olur ve HOL blocking oluşabilir.
Web tarayıcıların büyük kısmında HTTP pipelining varsayılan olarak devre dışıdır. Bunun nedeni olarak uygulamada karşılaşılan aşağıdaki durumları sayabiliriz:
- Muhafazakar sunucular: Bazı sunucular pipelining kullanılarak gönderilen istekleri yavaşlatabilir ya da istemci pipelining yapmaya çalıştığında bağlantıyı kapatabilir.
- Şaşkın sunucular: Bazı sunucular pipelining kullanılarak gönderilen isteklere yanlış sırada yanıt verebilir. Hatta bazıları yanıtları bozabilir.
- HOL blocking.
- HTTP pipelining düzgün bir başarısızlık senaryosu tanımlamaz. Sunucu bağlantıyı kapattığında hangi isteklerin düzgün şekilde işlendiğini bilmenin bir yolu yoktur. Bu durum POST gibi non-idempotent istekler için pipelining kullanılmamasının en önemli nedenidir.
HOL blocking
Şimdiye dek önemli bir problem olarak karşımıza çıkan HOL blocking sorununun ne olduğuna da değinmek gerekiyor. HTTP 1.x çoklu istekleri için gönderilen yanıtlar istek sırasına göre olmalıdır. Bir HTTP istemcinin sunucuya aynı TCP bağlantısı üzerinden iki istek gönderdiğini düşünelim. İlk yanıtın içerik boyutu çok büyük iken ikinci yanıtın içerik boyutu görece küçük olsun. HTTP 1.x protokolünün doğası gereği ikinci yanıt ilk yanıtın tamamlanmasını beklemek zorundadır. Bu durumda ikinci yanıt birinci yanıt tarafından head-of-line bloklanmıştır.
HTTP/2 ve SPDY gibi çoklanmış protokoller ile HOL-blocking engellenebilmektedir. Çünkü bu protokoller ile yanıtlar istemciye paralel olarak gönderilebilmektedir. Böylece yukarıdaki örnekte belirtilen ikinci yanıt ilk yanıttan önce istemciye ulaşabilmektedir.
HTTP/2 protokolü
Yazının başında da belirttiğim gibi bu yazıda HTTP/2 protokolünün ayrıntılarına çok fazla değinmeyeceğim. Yine de protokolün özelliklerinden kısaca bahsetmeye çalışayım. Daha fazla ayrıntı için HTTP/2 draft'ı okuyabilirsiniz.
HTTP/2 tek bir bağlantı üzerinde çoklamayı sağlayabilmek için stream adı verilen mantıksal bağlantılar/yollar kullanır. Veri akışı frame adı verilen paketler aracılığıyla sağlanır. Her frame'in başlangıcında hangi stream'e ait olduğu bilgisini de taşıyan 9 bayt uzunluğunda bir başlık yer alır. Frame formatı aşağıdaki gibidir:
Length (24 bit) : Payload boyutu (9 baytlık başlık hariç) Type (8 bit) : Frame türü Flags (8 bit) : Bayraklar R (1 bit) : Rezerve. Değeri 0 olmalıdır. Stream Identifier (31 bit) : Stream tanımlayıcı. 0 değeri bağlantının tümünü ilgilendiren frame'ler için ayrılmıştır. Payload : Length ile belirtilmiş kadar bayt uzunluğundadır.
- İstemci tarafından başlatılan stream'lerin id'leri tek, sunucu tarafından başlatılanlar çift olmalıdır.
-
Stream identifier'lar tekrar kullanılamazlar. Yeni bir stream başlatamayan istemci yeni stream için yeni bir bağlantı açabilir. Yeni bir stream başlatamayan sunucu ise
GOAWAYframe'i göndererek istemciyi yeni stream'ler için yeni bir bağlantı açmaya zorlayabilir.
Bu yazının HTTP/2 konusunda bilgi sahibi olmak adına güzel bir özet olduğunu umuyorum. Şimdiden HTTP/2 desteği veren tarayıcıları ve sunucuları takip ederek standart yayınlandığı andan itibaren performans kazancının tadını çıkarmanızı dilerim.