Как заставить Nginx и Phusion Passenger поддерживать сеансы между двумя экземплярами Rails? - PullRequest
0 голосов
/ 14 сентября 2010

Я использую Nginx с Phusion Passenger для запуска приложения Rails на компьютере с ECOS CentOS.

У меня довольно стандартная настройка с Nginx, Rails, Phusion Passenger и SSL (я думаю). Мой nginx.conf ниже. До сих пор все работало нормально, за исключением того, что каждый раз, когда два запроса попадают на сервер одновременно, создается новый экземпляр Rails для обслуживания второго запроса.

Проблема в том, что, как только второй запрос направляется во вновь созданный экземпляр Rails, он теряет аутентифицированный сеанс из исходного экземпляра Rails, что приводит к ошибкам. Мои сессии хранятся в памяти.

В качестве обходного пути я установил passenger_max_instances_per_app на 1, чтобы при создании новых экземпляров Rails создавалось, но это только временное исправление.

Кто-нибудь знает, как заставить Nginx поддерживать тот же сеанс для запросов из того же источника? Я мог бы упустить что-то очевидное здесь.

Спасибо!

worker_processes  1;  

events {
    worker_connections  1024;
}

http {
    ...
    passenger_pool_idle_time 0;
    passenger_max_instances_per_app 1;

    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on; 
    keepalive_timeout  65;   

    # this server isn't rails enabled. 
    # will redirect all traffic to https
    server {
        listen       80; 
        server_name  example.com;
        rewrite ^ https://www.example.com$request_uri permanent;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }   
    }   

    # HTTPS server
    # - by default everything is served by https
    server {
        listen       443;
        server_name  www.example.com;
        root   /rails/root/public;
        passenger_enabled on;
        rails_env production;

        ssl                  on;
        ssl_certificate      /path/to/cert/www.example.com.crt;
        ssl_certificate_key  /path/to/cert/www.example.com.key;
        ssl_session_timeout  5m;
    }
}

Ответы [ 2 ]

1 голос
/ 16 сентября 2010

У нас обычно есть passenger_max_pool_size 2;, если только мы не опускаем его полностью (принимая настройку по умолчанию) и две указанные вами настройки, passenger_pool_idle_time и passenger_max_instances_per_app, мы также оставляем по умолчанию.

Ключ сеанса должен храниться в cookie, чтобы Rails мог искать его между запросами. Предполагая, что это работает правильно, проблема в том, что несколько экземпляров Rails не разделяют память (функция, а не ошибка - это процессы, а не потоки) и, следовательно, не разделяют данные сеанса. Попробуйте перенести информацию о сеансе в ActiveRecord:

# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rake db:sessions:create")
ActionController::Base.session_store = :active_record_store

(код выше config/initializers/session_store.rb)

Таким образом, поскольку хранилище данных доступно для нескольких процессов Rails, все они должны иметь доступ к одному и тому же пулу активных сеансов.

0 голосов
/ 21 сентября 2011

Для повышения производительности следует избегать :active_record_store и использовать memcached вместо

config.action_controller.session_store = :mem_cache_store
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...