--------------------------------------------------------

做负载均衡时访问页面会把访问分发到不同的服务器,session是存在服务器端,如果首次访问被分发到A服务器,那么session就会被存到A服务器,再次访问时负载均衡会分发到B服务器那么第一次访问的session信息就会获取不到之前的session信息。解决方法有以下几种:

--------------------------------------------------------

(一)用nginx做负载均衡时可以配置ip_hash来解决,ip_hash技术能够将某个ip的请求定向到同一台后端应用服务器。

wKioL1fYo2fhbcRtAAAc-vlnDzE318.png

这样同一个ip请求时会分发到同一台后端的服务器。

缺点 :假如被分的服务器down掉的话,映射到这台的服务器的用户就郁闷了。

(二)利用数据库同步session

这个方法不可取,主要是把session放到数据库里,这样会加大数据库的负担。暂时不再赘述。。。

(三)利用cookie同步session数据原理如下

wKiom1fYqVnizzHSAACeL-ZPlho895.png

代码如下:

A服务器

<?php
    session_start();
 if(isset($_SESSION['username'])){
         echo 'ok you can go next';
     }else if(isset($_COOKIE['username'])){
         echo 'session is not in this server but cookie is exist';
         $_SESSION['username']=$_COOKIE['username'];
     }else{
        echo 'cookie and session does\'t in this server';
        $_SESSION['username']='lampol';
        setCookie('username','lampol',time()+30*24*60*60);
     }
echo '</br>';
echo 'this is A server';
echo '</br>';
var_dump($_SESSION);

B服务器

<?php
    session_start();
 if(isset($_SESSION['username'])){
         echo 'ok you can go next';
     }else if(isset($_COOKIE['username'])){
         echo 'session is not in this server but cookie is exist';
         $_SESSION['username']=$_COOKIE['username'];
     }else{
        echo 'cookie and session does\'t in this server';
        $_SESSION['username']='lampol';
        setCookie('username','lampol',time()+30*24*60*60);
     }
echo '</br>';
echo 'this is B server';
echo '</br>';
var_dump($_SESSION);

然后开始访问

第一次访问发到B服务器 没有session和cookie数据  然后会存到session和本地cookie

wKiom1fYs4HzktDJAAA7Jj6SYaI302.png

刷新第二次访问分发到A服务器  session不存在但是cookie再本地存在 此时会把本地的cookie同步到B服务器的cookie中

wKioL1fYs-zjItdvAAA6z4R9wRU839.png

缺点  如果禁用cookie那就完蛋了。。

(四)memcache或者redis存session(以memcache为例)

安装memcache及客户端和服务端,然后

<?php

ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "192.168.1.142:11211");

//以上配置可以再php.ini中配置
session_start();
$_SESSION['username']='lampol';

这样就把session信息存到了memache中 (redis同理)

然后在运行

<?php
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "192.168.1.142:11211");
session_start();
$mem = new Memcache;

$mem->connect('192.168.1.142',11211);

$id=session_id();

echo $mem->get($id);

wKiom1fZEw_yBpOMAAAmiQJQIEI845.png

获取到了session存在memcache中的数据

另外其实如果考虑到session共享的问题,完全没有必要存到session直接把数据存到memcache中即可

分布式中直接存到同一个memcache服务器中就可以了,另外memcache可以做主从,以后的文章中再继续探讨此问题。