2010-04-10 16 views
5

Çok tipik bir web uygulamasında çalışıyorum. Kullanıcı deneyiminin ana bileşeni, site sahibinin ön sayfalarına yükleyeceği bir widget'tır. Ön sayfa her yüklendiğinde, pencere öğesi sunucumuzla konuşur ve geri dönen verilerin bir kısmını görüntüler.Rails Metal (& Rack), yüksek trafikli bir web servisi api uygulamasının iyi bir yolu mu?

Yani bu web uygulamasına iki bileşeni vardır:

  1. site sahibi kendi eklendi Widget web API çağrısına yanıt
  2. arka uç bileşeni yapılandırmak için kullandığı ön uç UI

Daha önce PHP'de çalıştık. Şimdi # 1 (ön uç UI) için harika olan Rails ile deney yapıyoruz. Soru, etkin bir şekilde widget bilgilerinin arkaya sunulmasını # 2 yapmaktır. Açıkçası, bu, ön sayfanın müşterilerimizin web sitelerine yüklendiği her defasında çağrıldığı için, ön uçtan çok daha fazla yüktür.

İki bariz yaklaşımlar görebilirsiniz:

A. Paralel Stack: Ön aynı veritabanını raylar dışında bir şey (örneğin eski PHP tabanlı yaklaşım) kullanır ama erişen bir paralel yığını ayarlama sona

B. Raylar Metal: Kullanım Raylar Metal/Raf mekanizmasını yönlendirme Rayları bypass ama Raylar uygulama içindeki aPI çağrısı yanıtlayıcısını tutmak için

Benim asıl soru:

  1. Raylar/Metal böyle bir şey için makul bir yaklaşım mıdır?

Ama aynı zamanda ...

  1. Will Raylar ortamı hala çok ağır yüklenme havai?
  2. Rails ile metale daha da yakınlaşmanın, çevrenin çoğunu atlamanın bir yolu var mı?
  3. Rails/Metal performansı, benzer bir işin kusursuz bir şekilde, basit bir PHP'ye dönüşmesini sağlayacak mı (sadece burada basketbol sahası arıyor)?

Ve ...

  • A ve B hem çok daha iyi olacak bir 'C' seçeneği var mı

      ? Yani, ikili kodlanmış ve bir nginx veya apache modülü olarak kurulmuş C kodunun uzunluklarına gitmeden önce bir şey var mı?

    Herhangi bir anlayış için şimdiden teşekkür ederiz.

  • cevap

    1

    Karşılaşılan herhangi bir performans sorununun nedenini belirlediysem, yalnızca işlevlerini Rack/Metal'e çekmeye başlarım. Özellikle Rails (3, özellikle) ve Ruby'nin son sürümlerinde, yığının kendisi çok nadiren darboğazdır. Ölçmeye başlayın, bazı gerçek ölçümleri alın ve mantıklı bir şekilde optimize edin.

    Başparmak kuralı: metrikleriniz yoksa, performans sorunlarınız ve olası çözümleriniz hakkında akıllıca bir neden olamaz.

    Deneyimlerimdeki sorunlar neredeyse her zaman: görünümler ve veritabanı.

    Ryan'ın önerdiği gibi, önbellekleme son derece etkili olabilir ... hatta daha fazla kapasite sağlamak için Rails talep yığınının önünde bir ters proxy kullanmak üzere mimarinizi bile taşıyabilirsiniz. Varnish gibi bir önbellek inanılmaz derecede yüksek performans sağlar. Raylar, ters proxy çözümünü kolaylaştırmak için etags ve HTTP başlıkları için yerleşik desteğe sahiptir.

    Yapılacak diğer bir şey, db katmanının kendisine bakmaktır. Önbellek burada çok yol alabilir, ancak bazı optimizasyonlar burada da yararlı olabilir. Active Record'ları kullandığınızdan emin olmak: N + 1 sorgu durumlarından kaçınmak için mantıklı bir adımdır, ancak Rails'te mükemmel performans artışı sağlayan çok az konfigürasyonda veya hiçbir konfigürasyonda yığınının içine yığılması için harika bir destek vardır.

    +0

    Toby, çok teşekkürler - burada çok güzel bilgi var. Noktayı optimize etmeden önce önlemle tam anlaşma. Bu soruyla, tam olarak Rails yaklaşımının bu yola başlamadan önce makul olup olmadığını anlamaya çalışıyordum ve sizden gelen bilgiler, Adalet ve Ryan'ın oldukça sağlam bir evet olduğunu gösteriyor. Rails performansıyla ilgili bazı varsayımlardan dolayı suçluydum - son 18-24 ay içinde en son değerlendirdiğim tarihten bu yana çok yol kat ettim. – Greg

    3

    en ayrıntılı cevap değil ama gerçekten:

    ben yerine sayfa önbelleğe kullanmak istiyorsunuz, bunun için metal kullanmak ister. Böylelikle, istekler web sunucusu tarafından sunulacak ve hiçbir dinamik dil kullanılmayacaktır. Bir kaynak oluşturduğunuzda ilgili index sayfasını temizleyin.Bir çok temel bir örnek olacaktır: Daha fazla bilgi için

    class PostsController < ApplicationController 
        caches_page :index 
    
        def index 
        @posts = Post.all 
        respond_to do |format| 
         format.html 
         format.xml 
        end 
        end 
    
        def create 
        @post = Post.new(params[:post]) 
        respond_to do |format| 
         if @post.save 
         expire_page :action => :index 
         format.html { redirect_to posts_path } 
         format.xml 
         else 
         format.html { render :action => "new" } 
         end 
        end 
        end 
    end 
    

    the Caching Guide okuyun.

    +0

    Teşekkürler Ryan. Sadece açıklığa kavuşturmak için, web API'sı için sonuçları önbelleğe almak için önbelleğe alma mekanizmasını kullandığımı mı söylüyorsunuz? Eğer öyleyse, sanırım bunun faydaları zaman içinde hangi sonuçların değiştiğine bağlıdır. Yoksa senin noktanı mı kaçırıyorum? – Greg

    +0

    @Greg: Evet, API sonuçlarını önbelleğe almanızı öneriyorum. Sonuçlar, istek başına * değişiyorsa, önbellekleme yapmak çok fazla bir şey değildir, ancak her üç isteği de değiştiriyor olsalar bile, Rails yığınının üstüne basmayan 2 istek daha sunulacaktır ve bu da iyi bir şeydir. önbellek kullanacak kadar. –

    2

    PHP, her bir istek üzerine tüm ortamı yükler. Üretim modunda, Rails sunucu başlatıldığında tüm ortamı bir kez yükler. Normal denetleyici eylemleri sırasında kesinlikle çok fazla Ruby kodu çalıştırılıyor. Ancak, üretim modunda, bu kodun hiçbiri çevreyi yüklemeyle ilgili değildir. Her zamanki Rails denetleyici yığını yerine Rails Metal'in kullanılması, bu katmanların bir sayısını kaldırır ve istek başına kaydedilen birkaç ek milisaniye süre verir.

    +1

    Teşekkürler Adalet - bu çok ilginç. Sadece doğru sonucu çizdiğimden emin olmak için: Rails çevreyi bir kez yüklediğinden ve Metal Rails yığınının bir kısmını atladığından Rails/Metal saf PHP'ye dayalı bir yaklaşımdan bile daha hızlı olabilir mi? – Greg

    +0

    Bu doğru. – yfeldblum

    İlgili konular