Является ли Rails Metal (& Rack) хорошим способом реализации API веб-сервиса с высоким трафиком? - PullRequest
5 голосов
/ 10 апреля 2010

Я работаю над очень типичным веб-приложением. Основным компонентом взаимодействия с пользователем является виджет, который владелец сайта может установить на своей главной странице. Каждый раз, когда загружается их главная страница, виджет обращается к нашему серверу и отображает некоторые данные, которые возвращаются.

Итак, в этом веб-приложении есть два компонента:

  1. интерфейс пользователя, который владелец сайта использует для настройки своего виджета
  2. внутренний компонент, который отвечает на вызов веб-API виджета

Ранее все это работало на PHP. Сейчас мы экспериментируем с Rails, который является фантастическим для # 1 (пользовательский интерфейс). Вопрос в том, как сделать # 2, обратную доставку информации о виджетах, эффективно. Очевидно, что это намного более высокая нагрузка, чем внешний интерфейс, поскольку он вызывается каждый раз, когда главная страница загружается на веб-сайт одного из наших клиентов.

Я вижу два очевидных подхода:

A. Parallel Stack : настроить параллельный стек, который использует что-то отличное от rails (например, наш старый подход на основе PHP), но обращается к той же базе данных, что и внешний интерфейс

B. Rails Metal : Используйте Rails Metal / Rack для обхода механизма маршрутизации Rails, но сохраняйте ответчик вызова API в приложении Rails

Мой главный вопрос:

  1. Является ли Rails / Metal разумным подходом для чего-то подобного?

Но также ...

  1. Будут ли слишком тяжелыми накладные расходы на загрузку среды Rails?
  2. Есть ли способ приблизиться к металлу с помощью Rails, минуя большую часть окружающей среды?
  3. Подойдет ли производительность Rails / Metal к выполнению аналогичной задачи на обычном PHP (просто ищем примерный пример)?

И ...

  1. Есть ли опция 'C', которая была бы намного лучше, чем и A, и B? То есть что-то, прежде чем перейти к длинам кода C, скомпилированного в двоичный файл и установленного как модуль nginx или apache?

Заранее спасибо за любые идеи.

Ответы [ 3 ]

3 голосов
/ 10 апреля 2010

Не самый сложный ответ, но:

Я бы не использовал металл для этого, я бы вместо этого использовал кэширование страниц. Таким образом, запросы будут обслуживаться веб-сервером, а не динамическими языками вообще. При создании ресурса очистите соответствующую страницу index. Очень простой пример:

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

Для получения дополнительной информации прочитайте Руководство по кэшированию .

2 голосов
/ 11 апреля 2010

Я бы только начал использовать функциональность Rack / Metal, если бы точно определил причину возникновения проблемы с производительностью. В частности, в последних версиях Rails (в частности, 3) и Ruby, сам стек очень редко является узким местом. Начните измерять, получите реальные показатели и разумно оптимизируйте.

Мое эмпирическое правило: если у вас нет метрик, вы не можете разумно рассуждать о своей проблеме производительности и любом возможном решении.

Проблемы, с которыми я сталкивался, почти всегда: представления и база данных.

Как предполагает Райан, кэширование может быть невероятно эффективным ... вы даже можете переместить свою архитектуру, чтобы использовать обратный прокси-сервер перед вашим стеком запросов Rails, чтобы обеспечить еще больше возможностей. Кеш, такой как Varnish, обеспечивает невероятно высокую производительность. Rails имеет встроенную поддержку etags и HTTP-заголовков для упрощения решения обратного прокси.

Другая вещь, которую нужно сделать, это посмотреть на сам слой db. Кэш может иметь большое значение, но некоторая оптимизация может быть полезна и здесь. Убедитесь, что вы используете Active Record: include разумно, это отличный шаг, чтобы избежать ситуаций запроса N + 1, но в Rails есть фантастическая поддержка для сброса memcached в стек с минимальной конфигурацией или без нее, что может обеспечить превосходный прирост производительности.

2 голосов
/ 10 апреля 2010

PHP загружает всю среду при каждом запросе. В рабочем режиме Rails загружает всю среду один раз при запуске сервера. Конечно, при нормальных вызовах действия контроллера выполняется достаточное количество кода Ruby. Однако в производственном режиме ни один из этого кода не связан с загрузкой среды. А использование Rails Metal вместо обычного стека контроллеров Rails удаляет ряд этих слоев, давая несколько дополнительных миллисекунд времени, сэкономленного на запрос.

...