Wie erhalte ich Nginx und Phusion Passagier-Sitzungen zwischen zwei Rails Instanzen aufrecht zu erhalten?
-
02-10-2019 - |
Frage
Ich bin mit Nginx mit Phusion Passagiere eine Rails-Anwendung auf einer EC2 CentOS Maschine laufen zu lassen.
Ich habe ein ziemlich Standard-Set up mit Nginx, Rails, Phusion Passagier- und SSL (glaube ich). Mein nginx.conf ist unten. Bisher hat es außer fein ausgearbeitet, dass jedes Mal zwei Anfragen trafen den Server in der gleichen Zeit, eine neuen Rails-Instanz erstellt wird, um die zweite Anforderung zu bedienen.
Das Problem ist, dass, sobald die zweite Anforderung an die Rails-Instanz erstellt neu ausgerichtet wird, ist es die authentifizierte Sitzung von der ursprünglichen Rails Instanz verliert, was zu Fehlern. Meine Sitzungen werden im Speicher abgelegt.
Als Abhilfe können habe ich Set passenger_max_instances_per_app
bis 1 so auf neue Rails-Instanzen erstellt werden, aber dies ist nur eine temporäre Lösung.
Wer weiß, wie man Nginx die gleiche Sitzung für Anfragen aus der gleichen Quelle halten? Ich könnte etwas offensichtlich hier fehlen.
Danke!
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;
}
}
Lösung
Wir haben in der Regel passenger_max_pool_size 2;
wenn wir es nicht ganz wegzulassen (die Standardeinstellung unter) und die beiden Einstellungen sind Spezifizierungs, passenger_pool_idle_time
und passenger_max_instances_per_app
wir auch auf den Standard verlassen.
Der Sitzungsschlüssel sollte in einem Cookie gehalten werden, so Rails es oben zwischen den Anforderungen aussehen kann. das ist vorausgesetzt, richtig funktioniert, ist das Problem, dass mehrere Rails-Instanzen ohne einen gemeinsamen Speicher (Feature, kein Bug - sie sind Prozesse, keine Threads) und daher nicht teilen Sitzungsdaten. Versuchen Sie bewegen Ihre Sitzungsinformationen in Active:
# 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
(der obige Code ist in config/initializers/session_store.rb
)
Auf diese Weise, weil der Datenspeicher zugänglich zu Prozessen mehrerer Rails ist, sie sollten alle Zugänge zu dem gleichen Pool von aktiven Sitzungen haben.
Andere Tipps
For better performance, you should avoid :active_record_store
and use memcached instead
config.action_controller.session_store = :mem_cache_store