[英]How do I get Nginx and Phusion Passenger to maintain sessions between two Rails instances?
I'm using Nginx with Phusion Passenger to run a Rails app on an EC2 CentOS machine. 我将Nginx与Phusion Passenger结合使用,以在EC2 CentOS计算机上运行Rails应用程序。
I have a pretty standard set up with Nginx, Rails, Phusion Passenger and SSL (I think). 我为Nginx,Rails,Phusion Passenger和SSL(我认为)建立了相当不错的标准。 My nginx.conf is below.
我的nginx.conf在下面。 So far it has worked out fine except that every time two requests hit the server at the same time, a new Rails instance is created to serve the second request.
到目前为止,它工作得很好,只是每次两个请求同时到达服务器时,都会创建一个新的Rails实例来服务第二个请求。
The problem is that once the second request is directed to the newly created Rails instance, it loses the authenticated session from the original Rails instance, resulting in errors. 问题在于,第二个请求一旦定向到新创建的Rails实例,它将失去原始Rails实例的经过身份验证的会话,从而导致错误。 My sessions are stored in memory.
我的会话存储在内存中。
As a workaround, I've set passenger_max_instances_per_app
to 1 so on new Rails instances are created, but this is only a temporary fix. 作为一种解决方法,我将
passenger_max_instances_per_app
设置为1,这样就可以创建新的Rails实例,但这只是一个临时解决方案。
Does anyone know how to make Nginx maintain the same session for requests from the same source? 有谁知道如何使Nginx为来自相同来源的请求维护相同的会话? I might be missing something obvious here.
我可能在这里缺少明显的东西。
Thanks! 谢谢!
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;
}
}
We generally have passenger_max_pool_size 2;
我们通常有
passenger_max_pool_size 2;
unless we leave it out entirely (taking the default setting) and the two settings you're specifying, passenger_pool_idle_time
and passenger_max_instances_per_app
we also leave to the default. 除非我们完全省略(采用默认设置)和您指定的两个设置(
passenger_pool_idle_time
和passenger_max_instances_per_app
),否则我们也保留默认设置。
The session key should be kept in a cookie so Rails can look it up between requests. 会话密钥应保存在cookie中,以便Rails可以在请求之间进行查找。 Assuming that's working properly, the problem is that multiple Rails instances aren't sharing memory (feature, not a bug - they're processes, not threads) and therefore don't share session data.
假设工作正常,问题在于多个Rails实例不共享内存(功能,不是错误-它们是进程,不是线程),因此不共享会话数据。 Try moving your session information into ActiveRecord:
尝试将会话信息移到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
(the above code is in config/initializers/session_store.rb
) (以上代码在
config/initializers/session_store.rb
)
That way, because the data store is accessibly to multiple Rails processes, they should all have access to the same pool of active sessions. 这样,由于数据存储可访问多个Rails进程,因此它们都应有权访问相同的活动会话池。
为了获得更好的性能,应避免使用:active_record_store
,而应使用memcached
config.action_controller.session_store = :mem_cache_store
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.