CodeIgniter会话在非粘性会话负载平衡服务器上中断

时间:2014-04-23 12:11:55

标签: codeigniter session load-balancing

我有一个棘手的问题;我已经有一个月左右了,所以我进行了广泛的研究。

我有一个托管的CodeIgniter网站 - 不是我选择的,也不是我有权改变的 - 由第三方在2台服务器上,由第三方负载平衡。有趣的是,负载均衡器随机选择服务器,没有粘性会话。

现在,默认情况下,CI应该使用cookie或在DB中存储会话来处理此问题。我们已将会话设置为自动加载,

$autoload['libraries'] = array('session', 'user_agent', 'rest_client', 'lib_log');

配置适用于会话和cookie:

/*
|--------------------------------------------------------------------------
| Session Variables
|--------------------------------------------------------------------------
|
| 'sess_cookie_name'        = the name you want for the cookie
| 'sess_expiration'         = the number of SECONDS you want the session to     last.
|   by default sessions last 7200 seconds (two hours).  Set to zero for no expiration.
| 'sess_expire_on_close'    = Whether to cause the session to expire automatically
|   when the browser window is closed
| 'sess_encrypt_cookie'     = Whether to encrypt the cookie
| 'sess_use_database'       = Whether to save the session data to a database
| 'sess_table_name'         = The name of the session database table
| 'sess_match_ip'           = Whether to match the user's IP address when reading the session data
| 'sess_match_useragent'    = Whether to match the User Agent when reading the session data
| 'sess_time_to_update'     = how many seconds between CI refreshing Session Information
|
*/
$config['sess_cookie_name']     = 'e1fdc095-98e2-4294-9584-362ba355bacf';

$config['sess_expiration']      = 3600;
$config['sess_expire_on_close']= TRUE;
$config['sess_encrypt_cookie']  = TRUE;
$config['sess_use_database']    = FALSE; // obviously used TRUE when trying to use DB
$config['sess_table_name']      = 'ci_sessions';
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent']= TRUE;
$config['sess_time_to_update']  = 300;

/*
|--------------------------------------------------------------------------
| Cookie Related Variables
|--------------------------------------------------------------------------
|
| 'cookie_prefix' = Set a prefix if you need to avoid collisions
| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
| 'cookie_path'   =  Typically will be a forward slash
| 'cookie_secure' =  Cookies will only be set if a secure HTTPS connection exists.
|
*/
$config['cookie_prefix']    = "";
$config['cookie_domain']    = "";
$config['cookie_path']  = "/";
$config['cookie_secure']    = TRUE;
$config['cookie_httponly']  = TRUE;

(我希望希望那个配置中的某些东西是wromg?sess_cookie_name太长了?sess_match_ip应该是真的吗?)

1)使用cookie:该站点在单个节点上工作,但当请求被定向到另一个服务器时,会话消失。当请求被定向到原始服务器时,会话返回。这通常(但并非总是如此 - 有时用户会很幸运,并且所有请求都转到一台服务器)会导致无限重定向循环(直到浏览器停止尝试)。

有趣的是,在这种情况下,登录时的标准行为是从创建会话的控制器/方法(A/login)移动到另一个控制器(B/index)中的方法,转移到同一个控制器(B/welcome)。始终B/welcome无法识别会话,并重定向回A/login。然后循环开始,因为A/login识别会话。

2)使用数据库:没有创建会话,显然(我无法监控数据库)也没有在数据库中创建会话。这还没有完全探索,部分原因是因为DB中会话的唯一ID必须存储在客户端上,而唯一的地方就是cookie。如果完全使用cookie,为什么要使用数据库?

(也是第三方主持人回滚了那次尝试,很难让他们再做任何事情)

因此,如果负载完全只在一台服务器上运行,那么我的服务器上有一个100%在我的(单个)服务器上运行的站点,但是当负载均衡器按预期运行时会失败。对于cookie和DB存储方法都是如此。

我在我的智慧结束。如果有人有任何可能的解决方案或建议,请告诉我。

1 个答案:

答案 0 :(得分:0)

我终于可以访问类似的设置,并复制了问题。但是,我也解决了这个问题..我只是不知道如何。这是通过黑客攻击并最终替换CI的整个/系统文件夹,我得到了它。

FWIW,上面的配置设置

$config['cookie_secure']    = TRUE;
$config['cookie_httponly']  = TRUE;

没用;即使网站有证书,cookie_secure也必须是假的。我在其他地方读到,在负载平衡环境中安装证书的方式会影响这一点。 cookie_httponly是非标准的,显然没有效果。

抱歉,我没有更好的建议。