5 Stimmen

Ist Rails Metal (& Rack) ein guter Weg, um einen hohen Verkehr Web-Service-Api zu implementieren?

Ich arbeite an einer sehr typischen Webanwendung. Die Hauptkomponente der Benutzererfahrung ist ein Widget, das ein Website-Besitzer auf seiner Startseite installieren würde. Jedes Mal, wenn die Startseite geladen wird, kommuniziert das Widget mit unserem Server und zeigt einige der Daten an, die zurückkommen.

Diese Webanwendung besteht also aus zwei Komponenten:

  1. die Front-End-Benutzeroberfläche, die der Website-Besitzer zur Konfiguration seines Widgets verwendet
  2. die Backend-Komponente, die auf den Web-Api-Aufruf des Widgets antwortet

Zuvor lief das alles in PHP. Jetzt experimentieren wir mit Rails, was für #1 (die Front-End-UI) fantastisch ist. Die Frage ist, wie wir #2, die Bereitstellung von Widget-Informationen, effizient umsetzen können. Offensichtlich ist dies eine viel höhere Belastung als das Frontend, da es jedes Mal aufgerufen wird, wenn die Startseite auf einer der Websites unserer Kunden geladen wird.

Ich kann mir zwei offensichtliche Ansätze vorstellen:

A. Paralleler Stapel : Einrichten eines parallelen Stacks, der etwas anderes als Rails verwendet (z. B. unseren alten PHP-basierten Ansatz), aber auf dieselbe Datenbank wie das Frontend zugreift

B. Schiene Metall : Verwenden Sie Rails Metal/Rack, um den Rails-Routing-Mechanismus zu umgehen, aber behalten Sie den Api-Aufruf-Responder innerhalb der Rails-Anwendung

Meine wichtigste Frage:

  1. Ist Schienen/Metall ein vernünftiger Ansatz für etwas wie dieses?

Aber auch...

  1. Wird der Aufwand für das Laden der Rails-Umgebung immer noch zu groß sein?
  2. Gibt es eine Möglichkeit, mit Rails noch näher an das Metall heranzukommen, indem man den größten Teil der Umgebung umgeht?
  3. Wird Rails/Metal Leistung nähern sich die Perf einer ähnlichen Aufgabe auf gerade PHP (nur suchen für Ballpark hier)?

Und...

  1. Gibt es eine "C"-Option, die viel besser wäre als sowohl A als auch B? Das heißt, etwas, bevor die Längen der C-Code kompiliert, um binäre und installiert als ein nginx oder Apache-Modul?

Vielen Dank im Voraus für alle Erkenntnisse.

3voto

Ryan Bigg Punkte 104835

Nicht wirklich die ausführlichste Antwort, aber:

Ich würde dafür kein Metall verwenden, sondern stattdessen das Seiten-Caching. Auf diese Weise werden die Anfragen vom Webserver bedient, und es gibt überhaupt keine dynamischen Sprachen. Wenn Sie eine Ressource erstellen, löschen Sie die entsprechende index Seite. Ein sehr einfaches Beispiel wäre:

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

Für weitere Informationen lesen Sie der Caching-Leitfaden .

2voto

yfeldblum Punkte 64211

PHP lädt die gesamte Umgebung bei jeder Anfrage. Im Produktionsmodus lädt Rails die gesamte Umgebung einmal beim Starten des Servers. Es gibt sicherlich eine Menge Ruby-Code, der während normaler Controller-Aktionsaufrufe ausgeführt wird. Im Produktionsmodus hat jedoch keiner dieser Codes etwas mit dem Laden der Umgebung zu tun. Durch die Verwendung von Rails Metal anstelle des üblichen Rails-Controller-Stacks werden einige dieser Schichten entfernt, was zu einer zusätzlichen Zeitersparnis von einigen Millisekunden pro Anfrage führt.

2voto

Toby Hede Punkte 36095

Ich würde erst dann damit beginnen, Funktionen auf Rack/Metal zu verlagern, wenn ich die genaue Ursache für ein Leistungsproblem gefunden habe, das auftritt. Insbesondere in den neueren Versionen von Rails (insbesondere 3) und Ruby ist der Stack selbst nur sehr selten der Engpass. Fangen Sie an zu messen, erhalten Sie einige echte Metriken und optimieren Sie mit Bedacht.

Meine Faustregel lautet: Wenn Sie keine Metriken haben, können Sie keine intelligenten Überlegungen zu Ihrem Leistungsproblem und möglichen Lösungen anstellen.

Die Probleme sind meiner Erfahrung nach fast immer: die Ansichten und die Datenbank.

Wie Ryan vorschlägt, kann Caching unglaublich effektiv sein ... Sie können sogar Ihre Architektur verschieben, um einen Reverse-Proxy vor Ihrem Rails-Anforderungsstapel zu verwenden, um noch mehr Möglichkeiten zu bieten. Ein Cache wie Varnish bietet unglaubliche Leistung. Rails hat eine eingebaute Unterstützung für Etags und HTTP-Header, um eine Reverse-Proxy-Lösung zu ermöglichen.

Die andere Sache, die man tun sollte, ist, sich die db-Schicht selbst anzusehen. Der Cache kann hier einen langen Weg gehen, aber auch hier kann eine Optimierung nützlich sein. Die sinnvolle Verwendung von Active Record's :include ist ein guter Schritt, um N+1 Abfragen zu vermeiden, aber es gibt eine fantastische Unterstützung in Rails, um Memcached mit wenig oder gar keiner Konfiguration in den Stack einzubinden, was zu exzellenten Leistungssteigerungen führen kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X