摘要:对于一个大并发的系统,我们需要对系统做负载均衡。那么相应的就有session存储问题,Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。
服务器也通过URL重写的方式来传递SessionID的值,因此不是完全依赖Cookie。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员透明。
haproxy的session存储方案:
用户IP 轮询的方法
haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx的IP hash 指令)
配置指令 balance source
实例访问http://sourceip.ppzedu.com:8080
cookie 识别
haproxy 将WEB服务端发送给客户端的cookie中插入(或添加加前缀)haproxy定义的后端的服务器COOKIE ID。
配置指令例举 cookie SESSION_COOKIE insert indirect nocache
http://cookie.ppzedu.com:8080
用firebug可以观察到用户的请求头的cookie里 有类似" Cookie 9ai9=0bc588656ca05ecf7588c65f9be214f5; SESSION_COOKIE=12" SESSION_COOKIE=12就是haproxy添加的内容
session 识别
haproxy 将后端服务器产生的session和后端服务器标识存在haproxy中的一张表里。客户端请求时先查询这张表。
配置指令例举 appsession ppzedu len 64 timeout 5h request-learn
注意 ppzedu 这个值替换成 你的php.ini 里session.name的值。
实例访问 http://appsession.ppzedu.com:8080
只做简单轮询对比
实例访问 http://nosession.ppzedu.com:8080
配置方案
案例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
vim /usr/local/haproxy/conf/haproxy.cfg global log 127.0.0.1 local0 info maxconn 4096 user haproxy group haproxy daemon nbproc 1 pidfile /var/run/haproxy.pid defaults mode http maxconn 2000 contimeout 5000 clitimeout 30000 srvtimeout 30000 option httplog option redispatch option abortonclose retries 3 listen admin_stats bind *:443 mode http log 127.0.0.1 local0 err stats uri /qhappy_stats stats realm ppzedu.com\ Qhappy stats auth haproxy:hapass stats refresh 5s listen site_status bind *:445 mode http log 127.0.0.1 local0 err monitor-uri /site_status frontend ppzedu_web bind 0.0.0.0:8080 mode http log global option httplog option httpclose option forwardfor acl COOKIE hdr_reg(host) -i ^(cookie.ppzedu.com) acl SOURCE hdr_reg(host) -i ^(sourceip.ppzedu.com) acl APPSESSION hdr_reg(host) -i ^(appsession.ppzedu.com) acl NOSESSION hdr_reg(host) -i ^(nosession.ppzedu.com) use_backend COOKIE_srv if COOKIE use_backend SOURCE_srv if SOURCE use_backend APPSESSION_srv if APPSESSION use_backend NOSESSION_srv if NOSESSION # default_backend ai_server backend COOKIE_srv mode http cookie SESSION_COOKIE insert indirect nocache server REALsrv_70 IP_SERVER1:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1 server REALsrv_120 IP_SERVER2:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1 backend SOURCE_srv mode http balance source server REALsrv_70 IP_SERVER1:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1 server REALsrv_120 IP_SERVER2:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1 backend APPSESSION_srv mode http appsession 9ai9 len 64 timeout 5h request-learn server REALsrv_70 IP_SERVER1:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1 server REALsrv_120 IP_SERVER2:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1 backend NOSESSION_srv mode http balance roundrobin server REALsrv_70 IP_SERVER1:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1 server REALsrv_120 IP_SERVER2:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1 backend ai_server mode http balance roundrobin cookie SERVERID server REALsrv_70 IP_SERVER1:80 cookie 2 check inter 1500 rise 3 fall 3 weight 1 server REALsrv_120 IP_SERVER2:80 cookie 1 check inter 1500 rise 3 fall 3 weight 1 |
这里粘贴一个测试用的代码
本实验中使用到相同的index.php代码 如下
1 2 3 4 5 6 7 8 9 |
<?php session_start(); $_SESSION['time'] =date("Y:m:d:H:s",time()); echo "本次访问时间"."<font color=red>".$_SESSION['time']."</font>"."<br>"; echo "访问的服务器地址是"."<font color=red>".$_SERVER['SERVER_ADDR']."</font>"."<br>"; echo "访问的服务器域名是"."<font color=red>".$_SERVER['SERVER_NAME']."</font>"."<br>"; echo "SESSIONNAME是"."<font color=red>".session_name()."</font>"."<br>"; echo "SESSIONID是"."<font color=red>".session_id()."</font>"."<br>"; ?> |