http HEAD ve GET performansı


111

Mümkün olduğunca hızlı EVET veya HAYIR yanıtı vermesi gereken bir REST web hizmeti kuruyorum.

Bir HEAD hizmeti tasarlamak, bunu yapmanın en iyi yolu gibi görünüyor, ancak bir GET isteği yapmaya kıyasla gerçekten biraz zaman kazanıp kazanamayacağımı bilmek istiyorum.

Sanırım sunucumda vücut akışını açık / kapalı olmamak için kazanıyorum (yaklaşık 1 milisaniye?). Döndürülecek bayt miktarı çok düşük olduğundan, aktarımda, IP paket numarasında herhangi bir zaman kazanabilir miyim?

Cevabınız için şimdiden teşekkürler!

Düzenle:

Bağlamı daha fazla açıklamak için:

  • Aktif durumda iseler bazı işlemleri yürüten bir dizi REST hizmetim var.
  • Tüm bu ilk hizmetlerin durumunu gösteren başka bir REST hizmetim var.

Bu son hizmet çok büyük bir müşteri grubu tarafından çok sık çağrılacağından (her 5 ms'de bir çağrı bekleniyor), bir HEAD yöntemi kullanmanın değerli bir optimizasyon olup olmadığını merak ediyordum. Yanıt gövdesinde yaklaşık 250 karakter iade edilir. HEAD yöntemi en azından bu 250 karakterin taşınmasını sağlar, ancak bu etki nedir?

İki yöntem arasındaki farkı karşılaştırmaya çalıştım (HEAD vs GET), çağrıların 1000 katını çalıştırdım, ancak hiç kazanç görmedim (<1ms) ...


2
Aynı zamanda sunucu tarafında kullandığınız yaklaşıma da bağlıdır. Bir GET isteğini veya bir HEAD isteğini işlemek genellikle aynı sunucu süresini alabilir, çünkü sunucunun Content-Lengthbaşlık değerini hesaplamak için son gövdeyi bilmesi gerekebilir , ki bu bir HEAD isteğinin yanıtında önemli bir bilgi. Daha optimize edilmiş başka bir sunucu tarafı yaklaşımı olmadığı sürece, tek fayda, bant genişliğinin kaydedilmesi ve istemcinin yanıt gövdesini ayrıştırması gerekmemesidir. Yani temelde optimizasyon kazanımları hem sunucu hem de istemci uygulamalarına bağlıdır.
itsjavi

Yanıtlar:


173

RESTful URI, sunucuda bir "kaynağı" temsil etmelidir. Kaynaklar genellikle bir veritabanında veya dosya sistemindeki bir dosyada kayıt olarak saklanır. Kaynak büyük olmadığı veya sunucuya alınması yavaş olmadığı sürece, HEADyerine kullanarak ölçülebilir bir kazanç göremeyebilirsiniz GET. Meta verileri almak, tüm kaynağı almaktan daha hızlı olmayabilir.

Hangisinin daha hızlı olduğunu görmek için her iki seçeneği de uygulayabilir ve karşılaştırabilirsiniz, ancak mikro optimizasyon yerine ideal REST arayüzünü tasarlamaya odaklanırım. Temiz bir REST API genellikle uzun vadede daha hızlı olabilecek veya olmayabilecek bir kludgey API'sinden daha değerlidir. Kullanımından vazgeçmiyorum HEAD, sadece onu sadece "doğru" tasarımsa kullanmanızı öneriyorum.

Gerçekten ihtiyacınız olan bilgi, HTTP üstbilgilerinde güzel bir şekilde temsil edilebilen bir kaynakla ilgili meta verilerse veya kaynağın var olup olmadığını kontrol etmek HEADgüzel çalışabilir.

Örneğin, 123 kaynağının var olup olmadığını kontrol etmek istediğinizi varsayalım. A 200, "evet" ve 404"hayır" anlamına gelir:

HEAD /resources/123 HTTP/1.1
[...]

HTTP/1.1 404 Not Found
[...]

Ancak, REST hizmetinizden istediğiniz "evet" veya "hayır", meta verilerden ziyade kaynağın kendisinin bir parçasıysa, kullanmalısınız GET.


3
en iyi şeyler her zaman basittir, tıpkı bu cevap gibi. İşte bu kadar!
Afzal SH

Harika cevap! Bir sorum var: Bunu touchsunucudaki bir gönderinin görüntüleme sayısını güncellemek için bir komut olarak kullanmaya ne dersiniz ? Gönderi verileri zaten normal bir /postsarama yoluyla alındı , bu yüzden yalnızca kullanıcı gönderiyle bir şekilde etkileşim kurduktan sonra görüntüleme sayısını güncellemek istiyorum.
aalaap

1
@aalaap HEADİstekler için bir görüntüleme sayacını güncelleyecekseniz , bunu GETistekler için de yapmalısınız . Kullanım kararı GETveya HEADnihai olarak HTTP istemcisine bağlıdır. Sunucunuz, yanıt verirken hiçbir yanıt gövdesi olmaması dışında, her iki istek türü için de aynı şekilde davranmalıdır HEAD. Bunun görüntüleme sayacı gibi bir şeyi uygulamanın iyi bir yolu olup olmadığına gelince, emin değilim.
Andre D

-1 Adlandırılabilen herhangi bir bilgi bir kaynak olabilir. Dolayısıyla Tekdüzen Kaynak Konum Belirleyicisi. HTTP protokolünün tasarlandığı şekliyle bir kısmını kullanmanın "kludgey" veya "kirli" olduğu fikri tuhaftır.
Fraser

1
@Siddhartha, bu genellikle doğrudur, ancak her zaman değil. Content-Lengthkullanırken ihmal edilebilir Transfer-Encoding: chunked. Bununla bile Content-Length, sunucunun gerçek kaynağı getirmeden başlıklarda kullanılan kaynak boyutunu ve diğer meta verileri alması mümkündür. Belki de bu meta veriler çok hızlı erişim için bellekte önbelleğe alınır. Bunların hepsi uygulamaya özeldir.
Andre D

38

İstekte bulunan kişinin sorduğu soruyu ararken bu yanıtı buldum. Bunu ayrıca http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html adresinde buldum :

HEAD yöntemi, sunucunun yanıtta bir ileti gövdesi döndürmemesi ZORUNLU olması dışında GET ile aynıdır. Bir HEAD isteğine yanıt olarak HTTP başlıklarında bulunan meta bilgiler, bir GET isteğine yanıt olarak gönderilen bilgilerle aynı olmalıdır. Bu yöntem, kuruluşun kendisini devretmeden, talebin ima ettiği varlık hakkında meta bilgi elde etmek için kullanılabilir. Bu yöntem genellikle geçerlilik, erişilebilirlik ve son değişiklikler için hipermetin bağlantılarını test etmek için kullanılır.

Bana öyle geliyor ki, talepte bulunan kişinin sorusuna verilecek doğru yanıt, REST protokolünün neyin temsil ettiğine bağlı olmasıdır. Örneğin, benim özel durumumda, REST protokolüm oldukça büyük (10K'dan fazla olduğu gibi) görüntüleri almak için kullanılır. Sürekli olarak kontrol edilen çok sayıda bu tür kaynağım varsa ve istek başlıklarını kullandığım düşünüldüğünde, w3.org'un önerilerine göre HEAD isteğini kullanmak mantıklı olacaktır.


14

Bu tür bir yaklaşımı kesinlikle önermiyorum.

RESTful bir hizmet, HTTP fiillerinin anlamlarına saygı göstermelidir. GET fiili, kaynağın içeriğini almak anlamına gelirken, HEAD fiili herhangi bir içerik döndürmez ve örneğin, bir kaynağın değişip değişmediğini görmek, boyutunu veya türünü bilmek, olup olmadığını kontrol etmek için kullanılabilir. var ve benzeri.

Ve unutmayın: erken optimizasyon tüm kötülüklerin köküdür.


8

GET isteği yerine HEAD isteği kullanarak performansınız neredeyse hiç değişmeyecek.

Ayrıca, REST-ful olmasını istediğinizde ve GET verilerini almak istediğinizde, HEAD isteği yerine bir GET isteği kullanmalısınız.


8

GET baş + gövdeyi getirir, HEAD yalnızca başı getirir. Hangisinin daha hızlı olduğu bir fikir meselesi olmamalı. Yukarıdaki olumlu yanıtları anlamıyorum. META bilgisi arıyorsanız, bu amaç için tasarlanmış HEAD'e gidin.


3

'Vücut akımının açık / kapalı olması' konusundaki endişenizi anlamıyorum. Yanıt gövdesi, http yanıt başlıkları ile aynı akış üzerinde olacak ve ikinci bir bağlantı OLUŞTURMAYACAKTIR (bu arada 3-6 ms aralığında daha fazladır).

Bu, önemli ve hatta ölçülebilir bir fark yaratmayacak bir şey üzerinde çok erken bir optimizasyon girişimi gibi görünüyor. Gerçek fark, genel olarak REST ile uyumluluktur ve bu da veri almak için GET kullanılmasını önerir.

Cevabım HAYIR, mantıklıysa GET kullanın, HEAD kullanarak performans kazanımı olmaz.


İçeriğin 100 MB olduğunu varsayalım. Şüphesiz başlık, içerikten daha az olacaktır. Şimdi sizce bu kaynağı GET veya HEAD yöntemiyle talep ettiğimizde aralarında performans farkı yok mu ?!
Mohammad Afrashteh

3
OP, yanıtın gövdesinde 250 karakter belirtti. 100MB değil. Bu tamamen farklı bir soru.
smassey

1

BAŞ istekleri , yanıtın gövdesinin boş olması dışında GET istekleri gibidir . Bu tür bir istek, tek istediğiniz bir dosya hakkında meta veri olduğunda, ancak dosyanın tüm verilerini taşımanız gerekmediğinde kullanılabilir.


-1

Performansı kendiniz ölçmek için kolayca küçük bir test yapabilirsiniz. Bence performans farkı ihmal edilebilir, çünkü vücutta yalnızca 'Y' veya 'N' döndürüyorsanız, zaten açık olan bir akışa eklenen tek bir ekstra bayttır.

Daha doğru olduğu için GET ile de giderdim. İçeriği HTTP üstbilgilerinde değil, yalnızca meta verilerde döndürmeniz gerekir.


GET - bu sadece gizemli "tek ekstra bayt" değil. Sadece tüm vücut! Büyük belge durumunda, birkaç megabayt olabilir.
porfirion
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.