主要内容:
Session 和 Cookie、部署 memcached,Session共享
提前准备需要的环境:
1)由于最小化安装缺少许多工具包:
bash
[root@web1 ~]# yum -y install vim //安装vim编辑器
[root@web1 ~]# yum -y install net-tools //安装网络相关软件包(包含ifconfig)
[root@web1 ~]# yum -y install bash-completion //安装支持tab键的软件包
[root@web1 ~]# yum -y install psmisc //安装killall命令软件包
2)使用yum安装基础依赖包:
bash
[root@web1 ~]# yum -y install gcc make //安装编译工具
[root@web1 ~]# yum -y install pcre-devel //依赖包,使nginx支持正则
[root@web1 ~]# yum -y install openssl-devel //依赖包,支持基于ssl技术的网站
3)LNMP安装软件包:
① 安装Nginx
bash
[root@proxy lnmp_soft]# tar -xf nginx-1.17.6.tar.gz //释放nginx的源码包
[root@proxy lnmp_soft]# cd nginx-1.17.6/ //切换到源码包目录
[root@proxy nginx-1.17.6]# ./configure
[root@proxy nginx-1.17.6]# make //编译
[root@proxy nginx-1.17.6]# make install //安装
[root@proxy ~]# useradd -s /sbin/nologin nginx //添加Nginx用户
② 安装MariaDB
bash
[root@proxy ~]# yum -y install mariadb-server //安装数据库服务端
[root@proxy ~]# yum -y install mariadb //安装数据库客户端
[root@proxy ~]# yum -y install mariadb-devel //安装数据库依赖包(支持lnmp)
③ 安装PHP、安装PHP扩展
bash
[root@proxy ~]# yum -y install php //安装PHP环境(相当于解释器)
[root@proxy ~]# yum -y install php-mysql //安装PHP与数据库关联的软件包
[root@proxy ~]# yum -y install php-fpm //安装可使Nginx具备动态网站解析能力的软件包
4)将Nginx压缩包通过proxy远程拷贝给web1和web2
bash
[root@proxy ~]# cd ~/lnmp_soft/
[root@proxy lnmp_soft]# scp nginx-1.17.6.tar.gz php_scripts/php-memcached-demo.tar.gz 192.168.2.100:/root
[root@proxy lnmp_soft]# scp nginx-1.17.6.tar.gz php_scripts/php-memcached-demo.tar.gz 192.168.2.200:/root
一、Session & Cookies基本概念
Session 和 Cookies 是 Web 开发中用于跟踪用户状态和存储用户信息的两种主要机制。它们在客户端和服务器之间协同工作,以确保用户在浏览网站时能够保持一致的体验。
1)Session
Session 是一种服务器端机制,用于存储用户会话信息。Session 通常与 Cookies 结合使用,服务器通过一个唯一的 Session ID 来识别用户会话,并将实际的会话数据存储在服务器端。
- 存储位置:服务器端
- 大小限制:通常没有严格的限制,取决于服务器资源
- 生命周期:可以设置过期时间,通常与会话保持一致(用户关闭浏览器或长时间无活动后失效)
- 安全性:数据存储在服务器端,相对更安全
示例:
服务器生成 Session ID 并发送给客户端:
bash
Set-Cookie: session_id=1234567890; Expires=Wed, 21 Oct 2023 07:28:00 GMT; Secure; HttpOnly
客户端在后续请求中发送 Session ID:
bash
Cookie: session_id=1234567890
服务器根据 Session ID 查找会话数据:
bash
# 服务器端存储的会话数据示例(伪代码):
{
"session_id": "1234567890",
"user_id": "john_doe",
"last_accessed": "2023-10-21T07:28:00Z"
}
2)Cookies
Cookies 是存储在用户浏览器中的小型文本文件,用于存储用户的相关信息。服务器可以通过 HTTP 响应头将 Cookies 发送给客户端,客户端在后续的请求中会自动将这些 Cookies 发送回服务器。
- 存储位置:客户端(浏览器)。
- 大小限制:通常每个 Cookie 最大为 4KB。
- 生命周期:可以设置过期时间,可以是会话级别的(关闭浏览器后失效)或持久性的(长期有效)。
- 安全性 :可以通过设置
Secure
和HttpOnly
标志来提高安全性。
示例:
服务器通过 HTTP 响应头设置 Cookie:
Set-Cookie: username=john_doe; Expires=Wed, 21 Oct 2023 07:28:00 GMT; Secure; HttpOnly
客户端在后续请求中自动发送 Cookie:
Cookie: username=john_doe
Session 和 Cookies 通常结合使用,以实现用户状态的跟踪和数据的持久化。具体流程如下:
用户首次访问网站:
- 服务器生成一个唯一的 Session ID。
- 服务器通过 HTTP 响应头将 Session ID 作为 Cookie 发送给客户端。
用户后续访问网站:
- 客户端在每个请求中自动发送包含 Session ID 的 Cookie。
- 服务器根据 Session ID 查找对应的会话数据,以识别用户并恢复其会话状态。
**共同之处:**Cookie 和 Session 都是用于在 Web 开发中跟踪用户状态和存储用户信息的机制
区别之处:
**① 存储位置:**Cookie存储在客户端(用户的浏览器);Session存储在服务器端。
备注:服务器端本地的Session信息存放在:/var/lib/php/session/
**② 数据大小:**通常每个 Cookie 最大为 4KB,总大小也有限制;而Session通常没有严格的限制,取决于服务器资源。
**③ 生命周期:**Cookie可以设置过期时间,可以是会话级别的(关闭浏览器后失效)或持久性的(长期有效);Session通常与会话保持一致,用户关闭浏览器或长时间无活动后失效。
④ 安全性: Cookie数据存储在客户端,可能受到跨站脚本(XSS)和跨站请求伪造(CSRF)等攻击。可以通过设置
Secure
和HttpOnly
标志来提高安全性;Session数据存储在服务器端,相对更安全。敏感数据不会直接暴露给客户端。**⑤ 性能影响:**Cookie由于数据存储在客户端,不会对服务器性能造成直接影响;Session由于数据存储在服务器端,可能会对服务器资源造成一定压力,特别是在高并发情况下。
补充:处于安全性考虑
Cookie 安全性:使用 Secure 标志确保 Cookie 只在 HTTPS 连接中传输,使用 HttpOnly 标志防止通过 JavaScript 访问 Cookie。
Session 安全性:确保 Session ID 的随机性和唯一性,定期更新 Session ID,使用加密传输和存储敏感数据。
补充:解决集群主机过多而导致用户重复登陆网站的问题
在一个集群中,如果网站需要用户输入用户名和密码登陆之后才能继续访问,那么当用户登陆其中一台集群主机之后随着继续访问页面,请求可能被代理服务器轮询到另外一台服务器上,那么对于另外一台服务器来说用户并没有登陆,想查看登陆之后的页面还需要再次登陆,这样集群主机越多需要客户重复登陆的次数就越多,想要解决该问题就要从Session与Cookies入手
二、本地Session
1)部署Nginx调度器(proxy)
- ① Nginx安装并启动Nginx服务
- ② 安装memcached软件
- ③ 修改配置文件实现反向代理
2)部署后端LNMP主机(web1、web2)
- ① Nginx安装
- ② MariaDB安装
- ③ PHP安装
- ④ 启动Nginx、MariaDB、PHP服务
- ⑤ 在后端两台LNMP主机部署测试页面
- ⑥ 验证Session
案例1:PHP的本地Session信息
使用4台RHEL7虚拟机,其中一台作为Nginx前端调度器服务器eth0:192.168.4.5,eth1:192.168.2.5,两台虚拟机部署为LNMP服务器,分别为Web1服务器:192.168.2.100、Web2服务器:192.168.2.200
步骤1:部署后端LNMP服务器相关软件(web1、web2)
部署LNMP服务器需在两台后端服务器做相同的操作,以Web1(192.168.2.100)为例:
首先关闭:防火墙服务、HTTP服务、SELinux机制
bash
[root@web1 ~]# systemctl stop firewalld
[root@web1 ~]# systemctl stop httpd
[root@web1 ~]# setenforce 0
1)安装yum安装基础依赖包
bash
[root@web1 ~]# yum -y install gcc make openssl-devel pcre-devel
2)源码安装Nginx
bash
[root@web1 ~]# tar -xf nginx-1.17.6.tar.gz
[root@web1 ~]# cd nginx-1.17.6
[root@web1 nginx-1.17.6]# ./configure
[root@web1 nginx-1.17.6]# make && make install
3)安装Mariadb服务
bash
[root@web1 ~]# yum -y install mariadb mariadb-server mariadb-devel
4)安装PHP服务
bash
[root@web1 ~]# yum -y install php php-mysql php-fpm
5)启动Nginx、MariaDB、PHP服务
bash
[root@web1 ~]# /usr/local/nginx/sbin/nginx
[root@web1 ~]# systemctl start mariadb
[root@web1 ~]# systemctl start php-fpm
6)修改Nginx配置文件(修改默认首页与动静分离)
bash
[root@web1 ~]# vim /usr/local/nginx/conf/nginx.conf
location / {
root html;
index index.php index.html index.htm;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf; //将fastcgi_params修改为fastcgi.conf
}
[root@web1 ~]# /usr/local/nginx/sbin/nginx -s reload //重新加载配置文件
7)部署测试页面(web1为例)
测试页面可以参考lnmp_soft/php_scripts/php-memcached-demo.tar.gz
bash
[root@web1 ~]# ls
anaconda-ks.cfg nginx-1.17.6 nginx-1.17.6.tar.gz php-memcached-demo.tar.gz
[root@web1 ~]# tar -xf php-memcached-demo.tar.gz //释放带登录功能的网页
[root@web1 ~]# ls php-memcached-demo
home.php images index.php login.php README.md style.css
[root@web1 ~]# cp -r php-memcached-demo/* /usr/local/nginx/html/
测试:浏览器直接访问后端服务器http://192.168.2.100/index.php测试页面
8)查看服务器本地的Session信息
bash
[root@web1 ~]# cd /var/lib/php/session/ //查看服务器本地的Session信息
[root@web1 ~]# ls
sess_fu8omna7mvusaaet9adj2uh387
[root@web1 ~]# cat sess_fu8omna7mvusaaet9adj2uh387
为方便观察,修改/usr/local/nginx/html/index.php添加WEB1标记(WEB2主机也进行相同操作)
步骤2:部署Nginx为前台调度服务器(Proxy)
首先关闭:防火墙服务、HTTP服务、SELinux机制
bash
[root@proxy ~]# systemctl stop firewalld
[root@proxy ~]# systemctl stop httpd
[root@proxy ~]# setenforce 0
1)安装yum安装基础依赖包
bash
[root@proxy ~]# yum -y install gcc make openssl-devel pcre-devel
2)源码安装Nginx
bash
[root@proxy ~]# tar -xf nginx-1.17.6.tar.gz
[root@proxy ~]# cd nginx-1.17.6
[root@proxy nginx-1.17.6]# ./configure
[root@proxy nginx-1.17.6]# make && make install
3)安装Mariadb服务
bash
[root@proxy ~]# yum -y install mariadb mariadb-server mariadb-devel
4)安装PHP服务
bash
[root@proxy ~]# yum -y install php php-mysql php-fpm
5)启动Nginx、MariaDB、PHP服务
bash
[root@proxy ~]# /usr/local/nginx/sbin/nginx
[root@proxy ~]# systemctl start mariadb
[root@proxy ~]# systemctl start php-fpm
6)修改Nginx配置文件,实现反向代理服务器
Nginx配置文件中,通过upstream定义后端服务器地址池,默认调度策略为轮询
bash
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
upstream webs {
server 192.168.2.100:80;
server 192.168.2.200:80;
}
server {
listen 80;
server_name localhost;
location / {
root html;
index index.php index.html index.htm;
proxy_pass http://webs;
}
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload //重新加载配置文件
测试:浏览器访问测试页面验证轮询
**问题情况:**填写注册信息后,刷新,还需要再次注册,说明两台web后端服务器使用的是本地Session;第二台web2并不知道用户再第一台web1已经登录,第一台web1的登录信息也没有传递给第二台web2,所以导致用户需要再次注册;
- 分析:由于web1与web2都是在各自的/var/lib/php/session目录中存储session,所以造成客户需要重复登录,为了统一session存储的位置(该存储方式通常被称为session共享),需要安装专门的数据库工具,借助到memcached缓存服务器实现。
三、PHP+Memcached(实现Session共享)
通过修改PHP-FPM配置文件关联memcached服务器,实现session会话共享。当客户端访问两台不同的后端Web服务器时,Session 信息一致。
1)修改PHP配置文件
2)重启服务
3)测试Session共享
- 浏览器访问调度器(因拓扑问题,暂时以proxy为实验对象),刷新页面后,登录账户会被记录再memcached服务器;
- 刷新页面,proxy调度器切换后端服务器后,账户信息还在;
- 两台后端服务器(web1、web2)使用的是同一个账户;
步骤3:实现Session共享(Memcached)(web1、web2)
1)为后端服务器的PHP添加memcache扩展(we1为例)
bash
[root@web1 ~]# yum -y install php-pecl-memcached //安装php与memcached服务关联的软件包
[root@web1 ~]# systemctl restart php-fpm //重启PHP-FPM服务
2)在后端服务器上部署Session共享,修改PHP-FPM配置文件并重启服务
bash
[root@web1 ~]# vim /etc/php-fpm.d/www.conf
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
##原始文件,默认定义Sessoin会话信息本地计算机(默认在/var/lib/php/session)
+++++++++++++++++++++++++++++++++++++++++++++++
224 php_value[session.save_handler] = memcache
225 php_value[session.save_path] = "tcp://192.168.2.5:11211"
##定义Session信息存储在公共的memcached服务器上,通过path参数定义公共的memcached服务器的IP和端口
[root@web1 ~]# systemctl restart php-fpm //重启PHP-FPM服务
- 注意:主机参数中为memcache没有"d"
验证:清空浏览器的历史记录,再访问http://192.168.2.5/index.php仅仅登录一次即可成功;
扩展:通过sed修改PHP-FPM配置文件部署Session共享
sed -i '/save_handler/s/file/memcache/' /etc/php-fpm.d/www.conf
sed -i '/save_path]/s/\/var.*/tcp:\/\/192.168.2.5:11211/' /etc/php-fpm.d/www.conf
四、Memcached概述
Memcached 是一个高性能的分布式内存对象缓存系统,最初由 Brad Fitzpatrick 开发,用于加速动态 Web 应用程序,减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态应用程序的速度和性能。
使用场景:数据库加速、会话管理、页面缓存、计数器
- 分布式缓存:Memcached 支持分布式部署,可以将多台服务器组合成一个缓存集群,提供更高的容量和性能。
- 内存存储:数据存储在内存中,读取速度极快,适合需要快速响应的应用场景。
- 简单的键值对存储:Memcached 使用简单的键值对(key-value)存储方式,支持字符串、整数、浮点数等基本数据类型。
- LRU 缓存淘汰策略:当内存不足时,Memcached 使用最近最少使用(LRU)策略自动淘汰最不常用的数据。
- 多语言支持:提供多种编程语言的客户端库,如 Python、Java、PHP、Ruby 等,方便开发者使用。
- 无持久化:Memcached 不支持数据持久化,数据仅存储在内存中,服务器重启后数据会丢失。
优势:
- 高性能:内存存储提供极快的读写速度,适合需要低延迟的应用场景。
- 简单易用:简单的键值对存储方式和丰富的客户端库,方便开发者使用。
- 分布式支持:支持分布式部署,提供高可用性和可扩展性。
劣势:
- 数据丢失风险:由于数据仅存储在内存中,服务器重启或故障可能导致数据丢失。
- 无持久化:不支持数据持久化,需要额外的机制来保证数据的持久性和可靠性。
工作原理:
- 客户端请求:应用程序通过 Memcached 客户端库发送请求到 Memcached 服务器。
- 哈希算法:客户端库使用一致性哈希算法将键(key)映射到特定的 Memcached 服务器。
- 内存存储:Memcached 服务器将数据存储在内存中,提供快速的读写操作。
- 缓存命中:如果请求的数据在缓存中存在,Memcached 直接返回数据,减少对数据库的访问。
- 缓存未命中:如果请求的数据不在缓存中,应用程序从数据库读取数据,并将其存储到 Memcached 中供后续请求使用。
官网:memcached - a distributed memory object caching system
1)安装memcached(软件包:memcached)
2)启动memcached
3)memcached常用指令(增、删、改、查):
- 指令:set 变量 0 200 3 //定义变量,再输入变量的值(添加或替换)
备注:0表示数据不压缩,200为数据缓存时间/秒 3为需要存储的数据字节数量;
指令:add 变量 0 200 3 //变量不存在则添加
指令:replace 变量 0 200 3 //替换当前已有变量
指令:get 变量 //查询变量
指令:delete 变量 //删除变量
指令:flush_all //清空所有
指令:quit //退出登录
- 注意:对Memcached进行测试时,需要提前安装telnet远程工具才能访问;
- 注意:变量的值区分大小写
例如:memcached配置文件(查看即可,不需要修改)
bash
[root@proxy ~]# vim /usr/lib/systemd/system/memcached.service
ExecStart=/usr/bin/memcached -u $USER -p $PORT -m $CACHESIZE -c $MAXCONN $OPTIONS
[root@proxy ~]# vim /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""
bash
[root@proxy ~]# yum -y install memcached //安装memcached软件包
[root@proxy ~]# systemctl start memcached //启动服务
[root@proxy ~]# netstat -anptul | grep :11211 //查看服务端口信息
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 2154/memcached
tcp6 0 0 :::11211 :::* LISTEN 2154/memcached
udp 0 0 0.0.0.0:11211 0.0.0.0:* 2154/memcached
udp6 0 0 :::11211 :::* 2154/memcached
[root@proxy ~]# yum -y install telnet //安装telnet远程工具
[root@proxy ~]# telnet 127.0.0.1 11211 //远程访问memcached
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
##提示:0表示不压缩,180为数据缓存时间,3为需要存储的数据字节数量。
set name 0 180 3 //定义变量,变量名称为name
ANJ //输入变量的值,值为ANJ
STORED
get name //获取变量的值
VALUE name 0 3 //输出结果
ANJ
END
add myname 0 180 3 //新建变量,myname不存在则添加,存在则ERROR报错
Tom
STORED
replace myname 0 180 3 //替换,如果myname不存在则报错
TAT
STORED
get myname //读取变量
VALUE myname 0 3
TAT
END
delete myname //删除变量
DELETED
flush_all //清空所有
OK
quit //退出登录
**报错:**open() "/usr/local/nginx/html/favicon.ico" failed (2: No such file or directory)
思路:查看error日志/usr/local/nginx/logs/error.log
参考:https://blog.csdn.net/youcijibi/article/details/88868091
**解决办法:**只需要关闭 favicon.ico 的 log:
bash
location = /favicon.ico {
log_not_found off;
access_log off;
}
扩展知识:
-
如果web服务器端使用的是session,那么所有的数据都保存在服务器上,客户端每次请求服务器的时候会发送当前会话的session id,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登录或具有某种权限。由于数据是存储在服务器上面,所以你不能伪造,但是如果你能够获取某个登录用户的 sessionid,用特殊的浏览器伪造该用户的请求也是能够成功的。sessionid是服务器和客户端链接时候随机分配的,一般来说是不会有重复,但如果有大量的并发请求,也不是没有重复的可能性;
-
如果浏览器使用的是cookie,那么所有的数据都保存在浏览器端,比如你登录以后,服务器设置了cookie用户名,那么当你再次请求服务器的时候,浏览器会将用户名一块发送给服务器,这些变量有一定的特殊标记。服务器会解释为cookie变量,所以只要不关闭浏览器,那么cookie变量一直是有效的,所以能够保证长时间不掉线。
小结:
本篇章节为**【第二阶段】OPERATION-DAY4**的学习笔记,这篇笔记可以初步了解到 Session和Cookie、部署memcached,Session共享。除此之外推荐参考相关学习网址:
Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解