NGINX实现负载均衡,并利用PHP实现session入库
环境介绍:只有一台Centos 7的服务器,利用docker搭建3台lnmp服务器来测试。
Step 1 :利用docker来搭建三台lnmp服务器
docker pull imagine10255/centos6-lnmp-php56 docker run -itd --name lnmp1 -p 8081:80 imagine10255/centos6-lnmp-php56 docker run -itd --name lnmp2 -p 8082:80 imagine10255/centos6-lnmp-php56 docker run -itd --name lnmp3 -p 8083:80 imagine10255/centos6-lnmp-php56
Step 2 :在每台lnmp服务器网站根目录创建index.php文件。端口映射为8081的lnmp,index.php文件中写“8081”,以此类推写好另外两个lnmp docker服务器。
Step 3:修改服务器的nginx.conf文件,来配置负载均衡。
upstream up1{
server 47.91.209.222:8081;
server 47.91.209.222:8082;
server 47.91.209.222:8083;
}
server {
listen 80;
server_name www.zpfei.net;
location / {
proxy_pass http://up1;
}
.....
....
}
这样在访问nginx.zpfei.net的时候页面上就会以此出现 8081、8082、8083、8081..... 这是负载均衡最简单的实现方式,默认采用轮询的方式。
Step 4:那么问题来了,比如用户在8081的时候登录了网站,然后打开第二个页面的时候,发现被退出了,原因是8081的session并没有同步到8082服务器上来...
当然这里也可以采用ip_hash的方式来防止出现这种问题,但是ip_hash的原理是让同一个ip的用户在下次请求网站时依然分发到第一次请求的服务器,这样做很难做到真正的负载均衡。
怎么解决?可以利用session入库。
顾名思义,session入库就是把session写入到数据库中达到多台服务器同步session的目的。这里主要用到了“session_set_save_handler”这个函数,该函数的主要作用就是用于接管session的六个状态。废话少说,直接看代码。
<?php
header('content-type:text/html;charset=utf-8');
//将session存储方式设置为存入数据库的方式
//session.save_handler = files
ini_set("session.save_handler", "user");
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
//打开并连接数据库
function open()
{
//使用pdo
$pdo = new PDO('mysql:host=47.91.209.222;dbname=session','user','000');
$pdo->exec('set names utf8');
}
//关闭连接
function close()
{
//使用pdo
$pdo = new PDO('mysql:host=47.91.209.222;dbname=session','user','000');
$pdo->exec('set names utf8');
$pdo = null;
}
//从表中中读信息
function read($session_id)
{
//使用pdo
$pdo = new PDO('mysql:host=47.91.209.222;dbname=session','user','000');
$pdo->exec('set names utf8');
$read = $pdo->query("select * from session where session_id='$session_id'")->fetch(PDO::FETCH_ASSOC);
return $read["session_info"];
}
//将session存入数据库
function write ($session_id,$session_info)
{
// echo $session_id. " " . $session_info;
//使用pdo
$pdo = new PDO('mysql:host=47.91.209.222;dbname=session','user','000');
$pdo->exec('set names utf8');
$read = $pdo->query("select * from session where session_id='$session_id'")->fetch(PDO::FETCH_ASSOC);
if(empty($read))
{
$time = time();
$pdo->exec("insert into session (session_id, session_info, session_life) values ('$session_id', '$session_info', '$time')");
}
else
{
$sql = "update session set session_info='$session_info' where session_id='$session_id'";
$pdo->exec($sql);
}
}
//销毁指定session
function destroy($session_id)
{
//使用pdo
$pdo = new PDO('mysql:host=47.91.209.222;dbname=session','user','000');
$pdo->exec('set names utf8');
$pdo->exec("delete from session where session_id='$session_id'");
}
//删除所有过期的session
function gc()
{
}
session_start();
//判断是否有session
var_dump($_SESSION);
?>
经过测试,这样不管用户怎么刷新,session都会保持不变。
浙公网安备 33010602011771号