HTTP/2, daha önce uygulamalarımızda yapılan HTTP/1.1 geçici çözümlerinin çoğunu geri almamızı ve bu endişeleri taşıma katmanında gidermemizi sağlayarak uygulamalarımızı daha hızlı, daha basit ve daha güçlü hale getirecek (nadir bir kombinasyon). Daha da iyisi, uygulamalarımızı optimize etmek ve performansı iyileştirmek için yepyeni fırsatların da kapısını aralar.
HTTP/2 için birincil hedefler; tam istek ve yanıt çoğullama özelliğini etkinleştirerek gecikmeyi azaltmak, HTTP başlık alanlarının verimli bir şekilde sıkıştırılmasıyla protokol ek yükünü en aza indirmek ve istek önceliklendirme ile sunucu aktarımı için destek eklemektir. Bu gereksinimlerin uygulanması için yeni akış denetimi, hata işleme ve yükseltme mekanizmaları gibi protokol geliştirmelerini destekleyen çok sayıda destek vardır. Ancak bunlar, her web geliştiricisinin anlaması ve uygulamalarında yararlanması gereken en önemli özelliklerdir.
HTTP/2, HTTP'nin uygulama anlamını hiçbir şekilde değiştirmez. HTTP yöntemleri, durum kodları, URI'ler ve başlık alanları gibi tüm temel kavramlar geçerliliğini korur. Bunun yerine HTTP/2, verilerin biçimlendirilme (çerçeve) ve istemci ile sunucu arasında aktarılma şeklini değiştirir. Her ikisi de tüm süreci yönetir ve tüm karmaşıklığı yeni çerçeveleme katmanındaki uygulamalarımızdan gizler. Sonuç olarak, mevcut tüm uygulamalar herhangi bir değişiklik yapılmadan teslim edilebilir.
Neden HTTP/1.2 olmasın?
HTTP/2, HTTP Çalışma Grubu tarafından belirlenen performans hedeflerine ulaşmak için önceki HTTP/1.x sunucuları ve istemcileriyle geriye dönük uyumlu olmayan yeni bir ikili çerçeveleme katmanı sunar. Bu nedenle de ana protokol sürümü HTTP/2'ye yükseltilir.
Bununla birlikte, ham TCP yuvalarıyla çalışarak bir web sunucusu (veya özel bir istemci) uygulamadığınız sürece herhangi bir fark görmezsiniz: Tüm yeni, alt düzey çerçeveleme sizin adınıza istemci ve sunucu tarafından gerçekleştirilir. Tek gözlemlenebilir farklılıklar; performansın ve istek önceliklendirme, akış kontrolü ve sunucu aktarımı gibi yeni özelliklerin kullanılabilirliğinde iyileştirmeler olacaktır.
SPDY ve HTTP/2'nin kısa geçmişi
Google'da geliştirilen ve 2009'un ortalarında duyurulan SPDY, birincil hedefi HTTP/1.1'in iyi bilinen performans sınırlamalarından bazılarını ele alarak web sayfalarının yükleme gecikmesini azaltmaya çalışmak olan deneysel bir protokoldür. Daha net ifade etmek gerekirse, proje hedefleri şu şekilde belirlendi:
- Sayfa yüklenme süresinde (PLT) %50 azalmayı hedefleyin.
- Web sitesi yazarlarının içerikte değişiklik yapması gerekmez.
- Dağıtım karmaşıklığını en aza indirin ve ağ altyapısında değişiklikler olmasını önleyin.
- Bu yeni protokolü açık kaynak topluluğuyla iş birliği yaparak geliştirin.
- Deneysel protokolü (geçersiz kılmak) için gerçek performans verileri toplayın.
İlk duyurudan kısa süre sonra, Google'ın her iki yazılım mühendisi Mike Belshe ve Roberto Peon, yeni SPDY protokolünün deneysel uygulaması için ilk sonuçlarını, belgelerini ve kaynak kodlarını paylaştılar:
Şu ana kadar SPDY'yi yalnızca laboratuvar koşullarında test ettik. Elde edilen ilk sonuçlar oldukça cesaret vericidir: Simüle edilmiş ev ağı bağlantıları üzerinden en iyi 25 web sitesini indirdiğimizde, performansta önemli bir artış gözlemledik. Sayfalar% 55'e kadar daha hızlı yükleniyor. (Chromium Blogu)
2012'ye geldiğimizde yeni deneysel protokol Chrome, Firefox ve Opera'da destekleniyordu. Altyapısında hem büyük hem de küçük (örneğin, Google, Twitter, Facebook) ve giderek artan sayıda site, SPDY'yi dağıtıyordu. Sonuç olarak, SPDY sektörde giderek daha fazla benimsenerek fiilen bir standart haline gelme yolundaydı.
HTTP Çalışma Grubu (HTTP-WG) bu trendi gözlemleyerek SPDY'den alınan dersleri almak, bunları geliştirip iyileştirmek ve resmi bir "HTTP/2" standardı sunmak için yeni bir çalışma başlattı. Yeni bir başlatma belgesi oluşturuldu, HTTP/2 teklifleri için açık bir çağrı yapıldı ve çalışma grubunda uzun bir tartışmadan sonra SPDY spesifikasyonu yeni HTTP/2 protokolünün başlangıç noktası olarak kabul edildi.
Sonraki birkaç yıl içinde SPDY ve HTTP/2 paralel olarak gelişmeye devam etti. SPDY, HTTP/2 standardı için yeni özellikleri ve teklifleri test etmek amacıyla kullanılan deneysel bir dal olarak hizmet verdi. Kağıt üzerinde iyi görünen şeyler, uygulamada işe yaramayabilir. Bunun tersi de geçerlidir. SPDY, HTTP/2 standardına dahil edilmeden önce her bir teklifi test edip değerlendirmek için bir rota sunmuştur. Sonuçta bu süreç üç yıl sürdü ve aralarda onlarca taslakla sonuçlandı:
- Mart 2012: HTTP/2 için teklif çağrısı
- Kasım 2012: HTTP/2'nin ilk taslağı (SPDY'ye göre)
- Ağustos 2014: HTTP/2 taslak-17 ve HPACK taslak-12 yayınlandı
- Ağustos 2014: HTTP/2 için Çalışma Grubu son çağrısı
- Şubat 2015: IESG onaylı HTTP/2 ve HPACK taslakları
- Mayıs 2015: RFC 7540 (HTTP/2) ve RFC 7541 (HPACK) yayınlandı
2015'in başlarında IESG, yayın için yeni HTTP/2 standardını inceleyip onayladı. Kısa bir süre sonra, Google Chrome ekibi TLS için SPDY ve NPN uzantısını kullanımdan kaldırmayı planladığını duyurdu:
HTTP/2'nin HTTP/1.1'den yaptığı birincil değişiklikler performansın iyileştirilmesine odaklanıyor. Multiplexing, üst bilgi sıkıştırma, önceliklendirme ve protokol anlaşması gibi bazı temel özellikler, daha önce açık olan ancak standart dışı bir protokol olan SPDY'de yapılan çalışmalardan gelişti. Chrome, Chrome 6'dan beri SPDY'yi desteklemektedir. Ancak avantajların çoğu HTTP/2'de mevcut olduğundan vedalaşmanın zamanı geldi. 2016'nın başlarında SPDY desteğini ve aynı zamanda Chrome'da ALPN'nin yerini alan NPN adlı TLS uzantısına yönelik desteği kaldırmayı planlıyoruz. Sunucu geliştiricilerin HTTP/2 ve ALPN'ye geçmeleri önemle tavsiye edilir.
HTTP/2'ye yol açan açık standartlar sürecine katkıda bulunmaktan mutluluk duyuyoruz. (Chromium Blogu)
SPDY ve HTTP/2'nin birlikte evrilmesi; sunucu, tarayıcı ve site geliştiricilerin, geliştirilme aşamasındaki yeni protokolle ilgili gerçek dünya deneyimi kazanmasını sağladı. Sonuç olarak HTTP/2 standardı, en iyi ve en kapsamlı şekilde test edilmiş standartlardan biridir. HTTP/2 IESG tarafından onaylandığında, kapsamlı bir şekilde test edilmiş ve üretime hazır düzinelerce istemci ve sunucu uygulaması bulunuyordu. Aslına bakılırsa, son protokolün onaylanmasından yalnızca haftalar sonra, birçok popüler tarayıcı (ve birçok site) tam HTTP/2 desteği dağıttığından birçok kullanıcı zaten avantajlarından yararlanıyordu.
Tasarım ve teknik hedefler
HTTP protokolünün önceki sürümleri bilerek, kolayca uygulanmasını sağlamak için tasarlanmıştı: HTTP/0.9, World Wide Web'i önyüklemek için kullanılan tek satırlı bir protokoldü; HTTP/1.0 popüler HTTP/0.9 uzantılarını bilgi standardıyla belgelemiştir; HTTP/1.1 resmi bir IETF standardını sunmuştur. HTTP'nin Kısa Geçmişi sayfasını inceleyin. Bu nedenle HTTP/0.9-1.x, tam olarak amacına uygun şekilde hizmet verdi: HTTP, internette en yaygın şekilde benimsenen uygulama protokollerinden biridir.
Maalesef uygulama basitliği, uygulama performansını da beraberinde getirdi: HTTP/1.x istemcilerinin eşzamanlılık sağlamak ve gecikmeyi azaltmak için birden çok bağlantı kullanması gerekir; HTTP/1.x istek ve yanıt başlıklarını sıkıştırmaz ve gereksiz ağ trafiğine neden olur; HTTP/1.x etkili kaynak önceliklendirmesine izin vermez ve bu da temel TCP bağlantısının kötü kullanımına yol açar.
Bu sınırlamalar ölümcül değildi, ancak web uygulamaları kapsam, karmaşıklık ve günlük hayatımızda önemini artırmaya devam ettikçe hem web geliştiricileri hem de web kullanıcıları üzerindeki yükü gittikçe artan bir
HTTP/2, başlık alanı sıkıştırması sağlayıp aynı bağlantıda birden fazla eş zamanlı exchange'e izin vererek ağ kaynaklarının daha verimli bir şekilde kullanılmasını ve gecikme algısını azaltır. Özellikle, istek ve yanıt mesajlarının aynı bağlantı üzerinde araya girmesine olanak tanır ve HTTP başlık alanları için verimli bir kodlama kullanır. Ayrıca, isteklerin önceliklendirilmesine olanak tanıyarak daha önemli isteklerin daha hızlı tamamlanmasını sağlayarak performansı daha da artırır.
HTTP/1.x ile karşılaştırıldığında daha az TCP bağlantısı kullanılabildiğinden, sonuçta ortaya çıkan protokol ağ için daha uygundur. Böylece diğer akışlarla daha az rekabet, daha uzun ömürlü bağlantılar ve dolayısıyla mevcut ağ kapasitesinin daha iyi kullanılması anlamına gelir. Son olarak, HTTP/2 ayrıca ikili mesaj çerçevelemesi kullanılarak mesajların daha verimli bir şekilde işlenmesini sağlar. (Hypertext Aktarım Protokolü sürüm 2, Taslak 17)
HTTP/2'nin önceki HTTP standartlarının yerini almadığını, genişlettiğini unutmayın. HTTP'nin uygulama semantiği aynıdır ve sunulan işlevlerde veya HTTP yöntemleri, durum kodları, URI'ler ve başlık alanları gibi temel kavramlarda herhangi bir değişiklik yapılmamıştır. Bu değişiklikler açık bir şekilde HTTP/2 çabasının kapsamı dışındaydı. Bununla birlikte, üst düzey API aynı kalsa da düşük seviyeli değişikliklerin önceki protokollerin performans sınırlamalarını nasıl ele aldığını anlamak önemlidir. İkili çerçeveleme katmanına ve özelliklerine kısaca değinelim.
İkili kadraja alma katmanı
HTTP/2'nin tüm performans geliştirmelerinin temelinde, HTTP mesajlarının istemci ile sunucu arasında nasıl kapsülleneceğini ve aktarılacağını belirten yeni ikili çerçeveleme katmanı yer alır.
"Katman", yuva arayüzü ile uygulamalarımızın maruz kaldığı daha yüksek HTTP API arasında optimize edilmiş yeni bir kodlama mekanizmasının kullanıma sunulmasına yönelik bir tasarım seçimini ifade eder: Fiiller, yöntemler ve başlıklar gibi HTTP anlamları etkilenmez ancak geçiş sırasında kodlanma şekilleri farklıdır. Yeni satırla sınırlandırılmış düz metin HTTP/1.x protokolünün aksine tüm HTTP/2 iletişimi, her biri ikili biçiminde kodlanan daha küçük mesajlara ve çerçevelere bölünür.
Sonuç olarak, hem istemci hem de sunucunun birbirlerini anlamak için yeni ikili kodlama mekanizmasını kullanması gerekir: Bir HTTP/1.x istemcisi yalnızca HTTP/2 sunucusunu anlamaz (veya tam tersi). Neyse ki istemci ve sunucu gerekli tüm çerçeveleme işini bizim adımıza yaptığı için uygulamalarımız tüm bu değişikliklerden hiçbir şekilde habersiz kalıyor.
Akışlar, mesajlar ve çerçeveler
Yeni ikili çerçeveleme mekanizmasının kullanıma sunulması, verilerin istemci ile sunucu arasında değişimini değiştirmektedir. Bu işlemi açıklamak için HTTP/2 terminolojisine aşinalık kazanın:
- Akış: Oluşturulan bir bağlantıda, bir veya daha fazla mesaj taşıyabilen çift yönlü bayt akışı.
- Mesaj: Mantıksal bir istek veya yanıt mesajıyla eşlenen tam bir kare dizisi.
- Çerçeve: Her biri en azından çerçevenin ait olduğu akışı tanımlayan bir çerçeve başlığı içeren HTTP/2'deki en küçük iletişim birimi.
Bu terimlerin ilişkisi aşağıdaki gibi özetlenebilir:
- Tüm iletişim, istenilen sayıda çift yönlü akışı taşıyabilen tek bir TCP bağlantısı üzerinden gerçekleştirilir.
- Her akışın benzersiz bir tanımlayıcısı ve iki yönlü mesajları taşımak için kullanılan isteğe bağlı öncelik bilgileri vardır.
- Her mesaj, bir veya daha fazla çerçeveden oluşan bir istek ya da yanıt gibi mantıksal bir HTTP mesajıdır.
- Çerçeve, belirli bir veri türünü taşıyan en küçük iletişim birimidir; örneğin, HTTP üstbilgileri, ileti yükü vb. Farklı akışlardan kareler, araya yerleştirilebilir ve her karenin başlığındaki yerleşik akış tanımlayıcısı aracılığıyla yeniden birleştirilebilir.
Kısacası, HTTP/2, HTTP protokolü iletişimini ikili kodlu çerçeveler alışverişine ayırır. Daha sonra bu çerçeveler, belirli bir akışa ait olan ve hepsi tek bir TCP bağlantısı içinde çoğulalan mesajlarla eşlenir. Bu, HTTP/2 protokolü tarafından sağlanan diğer tüm özellikleri ve performans optimizasyonlarını etkinleştiren temeldir.
İstek ve yanıt çoğullama
HTTP/1.x kullanırken istemci, performansı iyileştirmek için birden çok paralel istekte bulunmak isterse birden çok TCP bağlantısı kullanılmalıdır (bkz. Birden Çok TCP Bağlantısı Kullanma). Bu davranış, HTTP/1.x yayınlama modelinin doğrudan bir sonucudur ve bağlantı başına tek seferde yalnızca bir yanıt iletilebilir (yanıt sıraya ekleme). Daha da kötüsü, bu aynı zamanda satır başı engellemeye ve temel TCP bağlantısının verimsiz kullanılmasına neden olur.
HTTP/2'deki yeni ikili çerçeveleme katmanı, bu sınırlamaları ortadan kaldırır ve istemci ile sunucunun bir HTTP mesajını bağımsız çerçevelere ayırmasına, bunları boşluk bırakmasına ve diğer tarafta birleştirmesine olanak tanıyarak tam istek ve yanıt çoğullamasını sağlar.
Anlık görüntü, aynı bağlantıda yayındaki birden fazla akışı yakalar. İstemci sunucuya bir DATA
çerçevesi (akış 5) iletirken sunucu, 1 ve 3. akışlar için istemciye aralıklı bir kare dizisi iletmektedir. Sonuç olarak, yayında üç paralel akış vardır.
Bir HTTP mesajını bağımsız çerçevelere ayırma, bunlara boşluk ekleme ve ardından diğer uçta yeniden derleme yeteneği, HTTP/2'nin en önemli tek geliştirmesidir. Aslında, tüm web teknolojileri yığını genelinde sayısız performans avantajını bir dalga etkisine sahiptir ve bu da aşağıdakileri gerçekleştirmemizi sağlar:
- Birden fazla isteği, hiçbir isteği engellemeden paralel olarak aralıklandırın.
- Hiçbir yanıtı engellemeden, birden çok yanıtı paralel olarak aralıksız kullanın.
- Paralel olarak birden fazla istek ve yanıt göndermek için tek bir bağlantı kullanın.
- Gereksiz HTTP/1.x geçici çözümlerini kaldırın (birleştirilmiş dosyalar, birleşik resimler ve alan parçalama gibi HTTP/1.x için optimizasyon yapma bölümüne bakın).
- Gereksiz gecikmeyi ortadan kaldırıp mevcut ağ kapasitesinin kullanımını iyileştirerek daha düşük sayfa yükleme süreleri sunun.
- ve daha fazlası...
HTTP/2'deki yeni ikili çerçeveleme katmanı, HTTP/1.x'te bulunan satır başı engelleme sorununu çözer ve istek ile yanıtların paralel işlenmesini ve sunulmasını etkinleştirmek için birden fazla bağlantı ihtiyacını ortadan kaldırır. Sonuç olarak bu, uygulamalarımızın dağıtımını daha hızlı, basit ve ucuz hale getiriyor.
Akış önceliklendirme
Bir HTTP mesajı birçok ayrı çerçeveye ayrıldığında ve birden fazla akışa ait çerçevelerin çoğullaılmasına izin veririz. Bu durumda karelerin boşluklara eklenme ve hem istemci hem de sunucu tarafından sunulma sırası kritik bir performans değerlendirmesi haline gelir. Bunu kolaylaştırmak için HTTP/2 standardı, her akışın ilişkili bir ağırlığa ve bağımlılığa sahip olmasına izin verir:
- Her akışa 1 ile 256 arasında bir tam sayı ağırlığı atanabilir.
- Her akışa, başka bir akışa açık bir bağımlılık verilebilir.
Akış bağımlılıklarının ve ağırlıkların kombinasyonu, istemcinin yanıt almayı nasıl tercih edeceğini ifade eden bir "önceliklendirme ağacı" oluşturmasına ve iletmesine olanak tanır. Buna karşılık sunucu, bu bilgileri CPU, bellek ve diğer kaynakların tahsisini kontrol ederek akış işlemeye öncelik vermek için kullanabilir ve yanıt verileri kullanılabilir olduğunda yüksek öncelikli yanıtların istemciye en iyi şekilde iletilmesini sağlamak için bant genişliğinin ayrılmasını sağlayabilir.
HTTP/2 içindeki bir akış bağımlılığı, başka bir akışın benzersiz tanımlayıcısına üst öğe olarak referans verilerek tanımlanır. Tanımlayıcı atlanırsa akışın "kök akışa" bağlı olduğu söylenir. Bir akış bağımlılığının bildirilmesi, mümkünse üst akışa kaynakların bağımlılıklarından önce ayrılması gerektiğini belirtir. Başka bir deyişle, "Lütfen D yanıtını C yanıtından önce işleyip teslim edin".
Aynı üst öğeyi (diğer bir deyişle, kardeş akışlara) paylaşan akışlara, kaynaklar ağırlıklarıyla orantılı olarak ayrılmalıdır. Örneğin, A akışının ağırlığı 12 ve eşdüzey B'nin ağırlığı 4 ise bu akışların her birinin alması gereken kaynakların oranını belirlemek için:
- Tüm ağırlıkları toplayın:
4 + 12 = 16
- Her yayın ağırlığını toplam ağırlığa bölün:
A = 12/16, B = 4/16
Bu durumda, A akışı üçte üçünü, B akışı ise mevcut kaynakların dörtte birini alır. B akışı ise A akışı için ayrılan kaynakların üçte birini alır. Yukarıdaki resimde birkaç uygulamalı örnek daha üzerinden geçelim. Soldan sağa:
- A veya B akışı bir üst bağımlılığı belirtmez ve örtülü "kök akışa" bağımlı olduğu söylenir; A'nın ağırlığı 12, B'nin ağırlığı ise 4'tür. Bu nedenle, orantılı ağırlıklara göre: B akışı, A akışına ayrılan kaynakların üçte birini almalıdır.
- D akışı kök akışa, C ise D'ye bağlıdır. Bu yüzden D’nin kaynakları C’den önce tamamen tahsis etmesi gerekir. C'nin bağımlılığı daha güçlü bir tercih ilettiği için ağırlıklar alakasızdır.
- D akışı, C'den önce kaynakların tamamını tahsis etmelidir; C, A ve B'den önce kaynakların tam tahsisini almalıdır; B akışı ise A akışı için ayrılan kaynakların üçte birini almalıdır.
- D Akışı, E ve C'den önce kaynakların tam tahsisini almalıdır; E ve C, A ve B'den önce eşit tahsis almalıdır; A ve B, ağırlıklarına göre orantılı olarak tahsis almalıdır.
Yukarıdaki örneklerde olduğu gibi, akış bağımlılıklarının ve ağırlıkların birlikte kullanılması kaynak önceliklendirme için etkili bir dil sağlar. Bu, farklı bağımlılıklara ve ağırlıklara sahip birçok kaynak türüne sahip olduğumuzda tarama performansını iyileştirmek için kritik bir özelliktir. Daha da iyisi, HTTP/2 protokolü, istemcinin bu tercihleri herhangi bir zamanda güncellemesine de olanak tanır. Böylece, tarayıcıda daha fazla optimizasyon yapılabilir. Başka bir deyişle, kullanıcı etkileşimine ve diğer sinyallere göre bağımlılıkları değiştirebilir, ağırlıkları yeniden dağıtabiliriz.
Kaynak başına bir bağlantı
Yeni ikili çerçeveleme mekanizması sayesinde HTTP/2 artık paralel olarak Multiplex akışlara birden fazla TCP bağlantısına ihtiyaç duymuyor. Her akış, boşluk eklemeli ve öncelik verilebilecek birçok çerçeveye ayrılmıştır. Sonuç olarak, tüm HTTP/2 bağlantıları kalıcıdır ve kaynak başına yalnızca bir bağlantı gerekir. Bu da çeşitli performans avantajları sunar.
Hem SPDY hem de HTTP/2 için en önemli özellik, tek iyi tıkanıklık kontrollü bir kanalda rastgele çoğullamadır. Bunun ne kadar önemli olduğunu ve ne kadar iyi işlediğini beni şaşırtıyor. Bu konudaki en büyük metriklerden biri, oluşturulan ve yalnızca tek bir HTTP işlemi taşıyan (dolayısıyla bu işlemin tüm ek yükü) oluşturduğu bağlantılar bölümü. HTTP/1 için etkin bağlantılarımızın% 74'ü yalnızca tek bir işlem taşır. Kalıcı bağlantılar hepimizin istediğimiz kadar yararlı değildir. Ancak HTTP/2'de bu sayı %25'e düşer. Bu, genel giderlerin azalması açısından büyük bir avantajdır. (HTTP/2 Firefox'ta Yayında, Patrick McManus)
Çoğu HTTP aktarımı kısa ve kesintilidir. TCP ise uzun ömürlü, toplu veri aktarımları için optimize edilmiştir. HTTP/2, aynı bağlantıyı tekrar kullanarak hem her bir TCP bağlantısını daha verimli bir şekilde kullanabilir hem de genel protokol ek yükünü önemli ölçüde azaltabilir. Ayrıca daha az bağlantı kullanılması, tam bağlantı yolu boyunca (yani istemci, aracılar ve kaynak sunucular) bellek ve işlem ayak izini azaltır. Bu, genel işlem maliyetlerini azaltır ve ağ kullanımı ile kapasiteyi iyileştirir. Sonuç olarak HTTP/2'ye geçmek yalnızca ağ gecikmesini azaltmakla kalmamalı, aynı zamanda işleme hızını da artırmalı ve operasyonel maliyetleri düşürmelidir.
Akış kontrolü
Akış kontrolü, gönderenin istemediği veya işleyemediği verilerle alıcıyı bunaltmasını önleyen bir mekanizmadır: Alıcı meşgul, ağır yük altında olabilir veya belirli bir akış için yalnızca sabit miktarda kaynak tahsis etmek istiyor olabilir. Örneğin, istemci yüksek öncelikli büyük bir video akışı istemiş ancak kullanıcı videoyu duraklatmış ve artık gereksiz verilerin getirilmesini ve arabelleğe alınmasını önlemek için sunucudan yayınlanmasını duraklatmak veya kısmak istemektedir. Alternatif olarak, bir proxy sunucusu hızlı aşağı akış ve yavaş yukarı akış bağlantılarına sahip olabilir ve benzer şekilde aşağı akışın verileri yukarı akış hızıyla eşleştirerek kaynak kullanımını kontrol etmek için verileri ne kadar hızlı sunacağını düzenlemek isteyebilir.
Yukarıdaki şartlar size TCP akış kontrolünü hatırlatıyor mu? Sorun fiilen aynı olduğundan, test etmeleri gerekir (Akış Kontrolü bölümüne bakın). Ancak, HTTP/2 akışları tek bir TCP bağlantısı içinde çoğullaştırıldığından TCP akış denetimi yeterince ayrıntılı değildir ve ayrı akışların iletimini düzenlemek için gereken uygulama düzeyinde API'leri sağlamaz. HTTP/2, bu sorunu gidermek için istemci ile sunucunun kendi akış ve bağlantı düzeyinde akış denetimini uygulamasını sağlayan bir dizi basit yapı taşı sağlar:
- Akış kontrolü yönlüdür. Her alıcı, her akış ve bağlantının tamamı için istediği pencere boyutunu ayarlayabilir.
- Akış kontrolü kredi tabanlıdır. Her alıcı, ilk bağlantısını ve akış akışı kontrol penceresini (bayt cinsinden) bildirir. Bu pencere, gönderen bir
DATA
çerçevesi yayınladığında azalır ve alıcı tarafından gönderilen birWINDOW_UPDATE
çerçevesi aracılığıyla artırılır. - Akış kontrolü devre dışı bırakılamaz. HTTP/2 bağlantısı kurulduğunda, istemci ve sunucu değişimi
SETTINGS
çerçeveleri tarafından sağlanır. Bu çerçeveler, akış denetimi penceresi boyutlarını her iki yönde de ayarlar. Akış kontrol penceresinin varsayılan değeri 65.535 bayta ayarlanmıştır. Ancak alıcı, büyük bir maksimum pencere boyutu (2^31-1
bayt) ayarlayabilir ve herhangi bir veri alındığında birWINDOW_UPDATE
çerçevesi göndererek bunu koruyabilir. - Akış kontrolü uçtan uca değil, adım adımdır. Diğer bir deyişle, bir aracı, kendi ölçütleri ile buluşsal yöntemlere göre kaynak kullanımını kontrol etmek ve kaynak tahsis mekanizmalarını uygulamak için bunu kullanabilir.
HTTP/2, akış denetiminin uygulanması için özel bir algoritma belirtmez. Bunun yerine, basit yapı taşlarını sağlar ve uygulamayı istemciye ve sunucuya erteler. Bu istemciler, kaynak kullanımını ve tahsisini düzenlemek için özel stratejiler uygulamanın yanı sıra web uygulamalarımızın gerçek ve algılanan performansını iyileştirmeye yardımcı olabilecek yeni yayınlama özellikleri uygular (bkz. Hız, Performans ve İnsan Algısı).
Örneğin, uygulama katmanı akış kontrolü, tarayıcının belirli bir kaynağın yalnızca bir kısmını getirmesine olanak tanır. Akış akış kontrol penceresini sıfıra düşürerek getirmeyi beklemeye alabilir ve daha sonra devam ettirebilirsiniz. Başka bir deyişle, tarayıcının bir resmin önizlemesini veya ilk taramasını getirmesini, görüntülemesini, diğer yüksek öncelikli getirmelerin devam etmesine izin vermesini ve daha kritik kaynakların yüklenmesi bittiğinde getirme işlemini devam etmesini sağlar.
Sunucu push
HTTP/2'nin yeni ve güçlü bir diğer özelliği de sunucunun tek bir istemci isteği için birden fazla yanıt gönderebilmesidir. Yani orijinal istek yanıtına ek olarak sunucu, istemcinin her birini açıkça istemesine gerek kalmadan ek kaynakları istemciye aktarabilir (Şekil 12-5).
Tarayıcıda böyle bir mekanizmaya neden ihtiyacımız var? Tipik bir web uygulaması düzinelerce kaynaktan oluşur. Bunların tümü, istemci tarafından, sunucu tarafından sağlanan belge incelenerek keşfedilir. Sonuç olarak, fazladan gecikmeyi ortadan kaldırıp sunucunun ilgili kaynakları önceden aktarmasına izin vermeye ne dersiniz? Sunucu, istemcinin hangi kaynaklara ihtiyaç duyacağını zaten bilir. Bu, sunucu aktarımıdır.
Hatta bir CSS, JavaScript veya başka bir öğeyi veri URI'si yoluyla satır içine aldıysanız (bkz. Kaynakları Satır içine Alma) zaten sunucu aktarma konusunda uygulamalı deneyime sahipsiniz demektir. Kaynağı belgeye manuel olarak yerleştirerek, aslında bu kaynağı istemcinin istemesini beklemeden müşteriye iletiriz. HTTP/2 ile ek performans avantajlarıyla aynı sonuçları elde edebiliyoruz. Push kaynakları şunlar olabilir:
- İstemci tarafından önbelleğe alındı
- Farklı sayfalarda tekrar kullanılır
- Diğer kaynaklarla birlikte Multiplexed
- Sunucuya öncelik verilir
- Müşteri tarafından reddedildi
PUSH_PROMISE 101
Tüm sunucu push akışları PUSH_PROMISE
çerçeveleri aracılığıyla başlatılır. Bu çerçeveler, sunucunun açıklanan kaynakları istemciye aktarma niyetine işaret eder ve aktarılan kaynakları isteyen yanıt verilerinden önce teslim edilmesi gerekir. Bu teslimat siparişi kritik öneme sahiptir: İstemcinin, bu kaynaklar için yinelenen istekler oluşturmamak için sunucunun hangi kaynakları aktarmayı amaçladığını bilmesi gerekir. Bu gereksinimi karşılamak için en basit strateji, üst kaynağın yanıtından (yani DATA
kare) önce, taahhüt edilen kaynağın yalnızca HTTP başlıklarını içeren tüm PUSH_PROMISE
karelerini göndermektir.
İstemci bir PUSH_PROMISE
karesi aldıktan sonra isterse akışı reddetme (RST_STREAM
karesiyle) seçeneğine sahiptir. (Bu durum, örneğin kaynağın zaten önbellekte olmasından kaynaklanabilir.) Bu, HTTP/1.x'e göre önemli
bir iyileştirmedir. Buna karşılık, HTTP/1.x için popüler bir "optimizasyon" olan kaynak satır içine alma kullanımı, "zorunlu aktarmaya" eşdeğerdir: İstemci devre dışı bırakamaz, iptal edemez veya satır içi kaynağı tek tek işleyemez.
HTTP/2 ile istemci, sunucu push kullanımının nasıl kullanıldığını tam olarak kontrol eder. İstemci, eşzamanlı olarak aktarılan akışların sayısını sınırlayabilir, akış ilk açıldığında ne kadar veri aktarıldığını kontrol etmek için ilk akış kontrolü penceresini ayarlayabilir veya sunucu aktarımını tamamen devre dışı bırakabilir. Bu tercihler, HTTP/2 bağlantısının başındaki SETTINGS
çerçeveleri aracılığıyla iletilir ve herhangi bir zamanda güncellenebilir.
Aktarılan her kaynak, satır içi kaynaktan farklı olarak istemcinin ayrı ayrı çoğullama, önceliklendirilmesi ve işlenmesine olanak tanıyan bir akıştır. Tarayıcı tarafından zorunlu kılınan tek güvenlik kısıtlaması, aktarılan kaynakların aynı kaynak politikasına uyması gerektiğidir: Sunucu, sağlanan içerik için yetkili olmalıdır.
Başlık sıkıştırma
Her HTTP aktarımı, aktarılan kaynağı ve özelliklerini açıklayan bir dizi üst bilgi içerir. HTTP/1.x'te bu meta veriler her zaman düz metin olarak gönderilir ve aktarım başına 500-800 bayttan fazla ek yük ve HTTP çerezleri kullanılıyorsa bazen kilobaytlar daha fazla ekler. (bkz. Ölçüm ve Denetleyici Protokol Ek Yükünü.) HTTP/2, bu ek yükü azaltmak ve performansı iyileştirmek için istek ve yanıt başlığı meta verilerini, iki basit ama güçlü teknik kullanan HPACK sıkıştırma biçimini kullanarak sıkıştırır:
- İletilen başlık alanlarının statik bir Huffman kodu ile kodlanmasına olanak tanır. Bu da bağımsız aktarım boyutlarını küçültür.
- Hem istemcinin hem de sunucunun, daha önce görülen başlık alanlarının dizine eklenmiş bir listesini tutmasını ve güncellemesini gerektirir (diğer bir deyişle, paylaşılan bir sıkıştırma bağlamı oluşturur). Bu da daha sonra önceden iletilen değerleri verimli bir şekilde kodlamak için referans olarak kullanılır.
Huffman kodlaması, aktarım sırasında bağımsız değerlerin sıkıştırılmasına olanak tanır. Daha önce aktarılan değerlerin dizine eklenen listesi, tam başlık anahtarlarını ve değerlerini verimli bir şekilde aramak ve yeniden oluşturmak için kullanılabilecek dizin değerlerini aktararak yinelenen değerleri kodlamamıza olanak tanır.
Bir başka optimizasyon olarak HPACK sıkıştırma bağlamı, statik ve dinamik bir tablodan oluşur: Statik tablo, spesifikasyonda tanımlanır ve tüm bağlantıların kullanması muhtemel olan yaygın HTTP başlığı alanlarının bir listesini (ör.geçerli başlık adları) sağlar. Dinamik tablo başlangıçta boştur ve belirli bir bağlantıdaki alışveriş değerlerine göre güncellenir. Bunun sonucunda, daha önce görülmemiş değerler için statik Huffman kodlaması ve her iki taraftaki statik veya dinamik tablolarda zaten mevcut olan değerler için dizinlerin kullanılmasıyla her isteğin boyutu küçültülür.
HPACK güvenliği ve performansı
HTTP/2 ve SPDY'nin ilk sürümlerinde, tüm HTTP üst bilgilerini sıkıştırmak için özel bir sözlükle zlib kullanılıyordu. Bu sayede, aktarılan başlık verilerinin boyutunda% 85 ila% 88 azalma görüldü ve sayfa yükleme süresi gecikmesinde önemli bir iyileşme görüldü:
Yükleme bağlantısının yalnızca 375 Kb/sn olduğu düşük bant genişliğine sahip DSL bağlantısında, özellikle istek başlığı sıkıştırması belirli siteler (diğer bir deyişle, çok sayıda kaynak isteği gönderen siteler) için sayfa yükleme süresinin önemli ölçüde artmasını sağlamıştır. Sırf başlık sıkıştırma sayesinde sayfa yüklenme süresinin 45-1142 ms kısaldığını gördük. (SPDY teknik belgesi, chromium.org)
Ancak 2012 yazında, TLS ve SPDY sıkıştırma algoritmalarına karşı bir "CRIME" güvenlik saldırısı yayınlandı ve bu da oturumların ele geçirilmesine yol açabilir. Sonuç olarak, zlib sıkıştırma algoritmasının yerini HPACK aldı. HPACK, özellikle tespit edilen güvenlik sorunlarını gidermek, doğru şekilde uygulanması verimli ve basit olmak, ayrıca HTTP üst bilgisi meta verilerinin iyi bir şekilde sıkıştırılmasını sağlamak amacıyla tasarlanmıştır.
HPACK sıkıştırma algoritmasının tüm ayrıntıları için IETF HPACK - HTTP/2 için Üstbilgi Sıkıştırma sayfasına bakın.
Daha fazla bilgi
- "HTTP/2" – Ilya Grigorik tarafından yazılan makalenin tamamı
- "HTTP/2 kurulumu" – Surma tarafından farklı arka uçlarda HTTP/2 kurulumu nasıl yapılır?
- "HTTP/2 hazır, haydi optimize edelim!" – Velocity 2015'ten Ilya Grigorik'in sunumu
- "HTTP/2 Push İçin Küçük Resim Kuralları" – Tom Bergan, Simon Pelchat ve Michael Buettner'ın push'un ne zaman ve nasıl kullanılacağıyla ilgili analizi.