什么是会话保持
- 当用于登录一个网站服务器, 网站服务器会将用户的登录信息存储下来(存储session),以保证我们能一直处于登录在线的状态
为什么要做会话保持
- 由于我们使用的是负载均衡轮询机制,会导致用户请求分散在不同的节点,从而造成会话无法保持
如何实现会话保持
- 1、粘性session:指nginx每次都将统一用户的所有请求转发到同一台服务,使用IP_hash机制
- 2、session复制:即每次session发生变化时,就广播给集群中的服务器,是所有的服务器的session相同,tomcat_cluster中会自动同步
- 3、session共享:缓存session到内存数据库中,使用redis,memcached
- 4、session持久化:将session存储到数据库中,像操作数据一样操作session
演示案例【phpmyadmin】
LB | 192.168.200.120 |
web-01 | 192.168.200.121 |
web-02 | 192.168.200.122 |
redis | 192.168.200.123 |
mysql | 192.168.200.127 |
web-01安装、配置
cat > /etc/yum.repos.d/nginx.repo << OK
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=0
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
OK
## 下载nginx
[root@nginx]# yum -y install nginx
[root@nginx conf.d]# cd /etc/nginx/conf.d/
[root@nginx conf.d]# rpm -e $(rpm -a | grep php)
[root@nginx conf.d]# rm -rf /etc/php.ini.rpmsave
[root@nginx PHP]# cat > /etc/yum.repos.d/php.repo << OK
[webtatic-php]
name = php Repository
baseurl = http://us-east.repo.webtatic.com/yum/el7/x86_64/
gpgcheck = 0
OK
## 下载php
[root@nginx PHP]# yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb
## 修改nginx、php启动用户
[root@nginx conf.d]# sed -i '/^user/c user www;' /etc/nginx/nginx.conf
[root@nginx conf.d]# sed -i '/^user/c user = www' /etc/php-fpm.d/www.conf
[root@nginx conf.d]# sed -i '/^group/c group = www' /etc/php-fpm.d/www.conf
[root@nginx conf.d]# mv default.conf{,.bak}
## 创建虚拟主机配置文件
[root@nginx conf.d]# vim phpmyadmin.conf
server {
listen 80;
server_name www.php-myadmin.org;
root /code/phpmy;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
## 检查语法
[root@nginx conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx conf.d]# systemctl enable php-fpm.service
[root@nginx conf.d]# systemctl start php-fpm.service
[root@nginx conf.d]# systemctl enable nginx.service
[root@nginx conf.d]# systemctl start nginx.service
## 创建目录、下载代码包
[root@nginx conf.d]# mkdir /code/
[root@nginx conf.d]# cd /code/
[root@nginx code]# unzip phpMyAdmin-4.9.11-all-languages.zip
[root@nginx code]# chown -R www.www phpMyAdmin-4.9.11-all-languages
[root@nginx code]# ln -s phpMyAdmin-4.9.11-all-languages /code/phpmy
## 配置
[root@nginx code]# cp phpmy/config.sample.inc.php /code/phpmy/config.inc.php
[root@nginx code]# vim phpmy/config.inc.php
.....
$cfg['Servers'][$i]['host'] = '192.168.200.127';
.....
[root@nginx code]# chown -R www.www /var/lib/php/session/
[root@nginx code]# systemctl reload nginx.service
mysql创建用户
[root@mysql-master ~]# yum -y install mariadb-service mariadb
[root@mysql-master ~]# systemctl start mariadb
[root@mysql-master ~]# systemctl enable mariadb
[root@mysql-master ~]# mysqladmin -uroot password
[root@mysql-master ~]# mysql -uroot -p111
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> grant all on *.* to myadmin@'%' identified by '111';
Query OK, 0 rows affected (0.00 sec)
测试访问
web-02安装、配置
cat > /etc/yum.repos.d/nginx.repo << OK
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=0
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
OK
## 下载nginx
[root@nginx]# yum -y install nginx
[root@nginx conf.d]# cd /etc/nginx/conf.d/
[root@nginx conf.d]# rpm -e $(rpm -a | grep php)
[root@nginx conf.d]# rm -rf /etc/php.ini.rpmsave
[root@nginx PHP]# cat > /etc/yum.repos.d/php.repo << OK
[webtatic-php]
name = php Repository
baseurl = http://us-east.repo.webtatic.com/yum/el7/x86_64/
gpgcheck = 0
OK
## 下载php
[root@nginx PHP]# yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb
## 修改nginx、php启动用户
[root@nginx conf.d]# sed -i '/^user/c user www;' /etc/nginx/nginx.conf
[root@nginx conf.d]# sed -i '/^user/c user = www' /etc/php-fpm.d/www.conf
[root@nginx conf.d]# sed -i '/^group/c group = www' /etc/php-fpm.d/www.conf
[root@nginx conf.d]# mv default.conf{,.bak}
## 创建虚拟主机配置文件
[root@nginx conf.d]# vim phpmyadmin.conf
server {
listen 80;
server_name www.php-myadmin.org;
root /code/phpmy;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
## 检查语法
[root@nginx conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx conf.d]# systemctl enable php-fpm.service
[root@nginx conf.d]# systemctl start php-fpm.service
[root@nginx conf.d]# systemctl enable nginx.service
[root@nginx conf.d]# systemctl start nginx.service
## 创建目录、下载代码包
[root@nginx conf.d]# mkdir /code/
[root@nginx conf.d]# cd /code/
[root@nginx code]# unzip phpMyAdmin-4.9.11-all-languages.zip
[root@nginx code]# chown -R www.www phpMyAdmin-4.9.11-all-languages
[root@nginx code]# ln -s phpMyAdmin-4.9.11-all-languages /code/phpmy
## 配置
[root@nginx code]# cp phpmy/config.sample.inc.php /code/phpmy/config.inc.php
[root@nginx code]# vim phpmy/config.inc.php
.....
$cfg['Servers'][$i]['host'] = '192.168.200.127';
.....
[root@nginx code]# chown -R www.www /var/lib/php/session/
[root@nginx code]# systemctl reload nginx.service
接入LB
[root@nginx conf.d]# vim phpmyadmin.conf
upstream phpmy {
server 192.168.200.121:80;
server 192.168.200.122:80;
}
server {
listen 80;
server_name www.php-myadmin.org;
location / {
proxy_pass http://phpmy;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@nginx conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx conf.d]# systemctl reload nginx.service
测试【域名解析到LB】
[root@lb conf.d]# vim phpmyadmin.conf
upstream phpmy {
server 192.168.200.121:80;
server 192.168.200.122:80;
}
server {
listen 80;
server_name www.php-myadmin.org;
location / {
proxy_pass http://phpmy;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@lb conf.d]# systemctl reload nginx.service
- 接入LB后,发现登录不上了,因为是轮询调度,session一直在发生变化
配置IP_hash【会话保持】测试
upstream phpmy {
ip_hash;
server 192.168.200.121:80;
server 192.168.200.122:80;
}
server {
listen 80;
server_name www.php-myadmin.org;
location / {
proxy_pass http://phpmy;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@nginx conf.d]# systemctl reload nginx.service
- 登录成功,但是发现无论怎么刷新,都是被调度到固定节点,显然使用ip_hash如果同一时间出现高并发,后端某台服务压力瞬增
安装、配置redis实现【会话保持】
[root@redis~]# yum -y install redis
[root@nginx ~]# sed -i '/^bind/c bind 127.0.0.1 192.168.200.123' /etc/redis.conf
[root@nginx ~]# systemctl enable redis
[root@nginx ~]# systemctl start redis
[root@nginx ~]# netstat -lntp | grep redis
tcp 0 0 192.168.200.123:6379 0.0.0.0:* LISTEN 2260/redis-server 1
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 2260/redis-server 1
配置将web的php应用服务的session信息,存储到redis中
- php使用php71w-pecl-redis-3.1.6模块
- 如果redis有密码,要将auth=111添加到配置文件中
[root@nginx code]# rpm -qa | grep php | grep redis
php71w-pecl-redis-3.1.6-1.w7.x86_64
## 修改配置
[root@nginx code]# vim /etc/php.ini
;session.save_handler = files
session.save_handler = redis
session.save_path = "tcp://192.168.200.123:6379?&weight=1&timeout=2.5"
## 注释一下内容
[root@nginx code]# vim /etc/php-fpm.d/www.conf
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session
[root@nginx code]# systemctl restart php-fpm
配置LB
[root@nginx conf.d]# vim /etc/nginx/conf.d/phpmyadmin.conf
upstream phpmy {
server 192.168.200.121:80;
server 192.168.200.122:80;
}
server {
listen 80;
server_name www.php-myadmin.org;
location / {
proxy_pass http://phpmy;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@nginx conf.d]# systemctl reload nginx.service
测试
登录redis查看session
[root@nginx ~]# redis-cli
127.0.0.1:6379> KEYS *
1) "PHPREDIS_SESSION:76700eb33b48322e8159cfbbd9921d08"