主要内容:

Session 和 Cookie、部署 memcached,Session共享

提前准备需要的环境:

1)由于最小化安装缺少许多工具包:

[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安装基础依赖包:

[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

[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

[root@proxy ~]# yum -y install mariadb-server    //安装数据库服务端
[root@proxy ~]# yum -y install mariadb     //安装数据库客户端
[root@proxy ~]# yum -y install mariadb-devel   //安装数据库依赖包(支持lnmp)

③ 安装PHP、安装PHP扩展

[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

[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 并发送给客户端:

Set-Cookie: session_id=1234567890; Expires=Wed, 21 Oct 2023 07:28:00 GMT; Secure; HttpOnly

 客户端在后续请求中发送 Session ID:

Cookie: session_id=1234567890

服务器根据 Session ID 查找会话数据:

# 服务器端存储的会话数据示例(伪代码):

{
    "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机制

[root@web1 ~]# systemctl stop firewalld
[root@web1 ~]# systemctl stop httpd
[root@web1 ~]# setenforce 0

1)安装yum安装基础依赖包

[root@web1 ~]# yum -y install gcc make openssl-devel pcre-devel

2)源码安装Nginx

[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服务

[root@web1 ~]# yum -y install mariadb mariadb-server mariadb-devel

4)安装PHP服务

[root@web1 ~]# yum -y install php php-mysql php-fpm

5)启动Nginx、MariaDB、PHP服务

[root@web1 ~]# /usr/local/nginx/sbin/nginx
[root@web1 ~]# systemctl start mariadb
[root@web1 ~]# systemctl start php-fpm

6)修改Nginx配置文件(修改默认首页与动静分离)

[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

[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信息

浏览器访问后端服务器http://192.168.2.100/index.php测试页面并填写账户信息

[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机制

[root@proxy ~]# systemctl stop firewalld
[root@proxy ~]# systemctl stop httpd
[root@proxy ~]# setenforce 0

1)安装yum安装基础依赖包

[root@proxy ~]# yum -y install gcc make openssl-devel pcre-devel

2)源码安装Nginx

[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服务

[root@proxy ~]# yum -y install mariadb mariadb-server mariadb-devel

4)安装PHP服务

[root@proxy ~]# yum -y install php php-mysql php-fpm

5)启动Nginx、MariaDB、PHP服务

[root@proxy ~]# /usr/local/nginx/sbin/nginx
[root@proxy ~]# systemctl start mariadb
[root@proxy ~]# systemctl start php-fpm

6)修改Nginx配置文件,实现反向代理服务器

Nginx配置文件中,通过upstream定义后端服务器地址池,默认调度策略为轮询

[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为例)

[root@web1 ~]# yum -y install php-pecl-memcached  //安装php与memcached服务关联的软件包
[root@web1 ~]# systemctl restart php-fpm   //重启PHP-FPM服务

2)在后端服务器上部署Session共享,修改PHP-FPM配置文件并重启服务

[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 不支持数据持久化,数据仅存储在内存中,服务器重启后数据会丢失。

优势:

  1. 高性能:内存存储提供极快的读写速度,适合需要低延迟的应用场景。
  2. 简单易用:简单的键值对存储方式和丰富的客户端库,方便开发者使用。
  3. 分布式支持:支持分布式部署,提供高可用性和可扩展性。

劣势:

  1. 数据丢失风险:由于数据仅存储在内存中,服务器重启或故障可能导致数据丢失。
  2. 无持久化:不支持数据持久化,需要额外的机制来保证数据的持久性和可靠性。

工作原理:

  1. 客户端请求:应用程序通过 Memcached 客户端库发送请求到 Memcached 服务器。
  2. 哈希算法:客户端库使用一致性哈希算法将键(key)映射到特定的 Memcached 服务器。
  3. 内存存储:Memcached 服务器将数据存储在内存中,提供快速的读写操作。
  4. 缓存命中:如果请求的数据在缓存中存在,Memcached 直接返回数据,减少对数据库的访问。
  5. 缓存未命中:如果请求的数据不在缓存中,应用程序从数据库读取数据,并将其存储到 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配置文件(查看即可,不需要修改)

[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=""
[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:

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

扩展知识:

1. 如果web服务器端使用的是session,那么所有的数据都保存在服务器上,客户端每次请求服务器的时候会发送当前会话的session id,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登录或具有某种权限。由于数据是存储在服务器上面,所以你不能伪造,但是如果你能够获取某个登录用户的 sessionid,用特殊的浏览器伪造该用户的请求也是能够成功的。sessionid是服务器和客户端链接时候随机分配的,一般来说是不会有重复,但如果有大量的并发请求,也不是没有重复的可能性;

2. 如果浏览器使用的是cookie,那么所有的数据都保存在浏览器端,比如你登录以后,服务器设置了cookie用户名,那么当你再次请求服务器的时候,浏览器会将用户名一块发送给服务器,这些变量有一定的特殊标记。服务器会解释为cookie变量,所以只要不关闭浏览器,那么cookie变量一直是有效的,所以能够保证长时间不掉线。

小结:

本篇章节为【第二阶段】OPERATION-DAY4 的学习笔记,这篇笔记可以初步了解到 Session和Cookie、部署memcached,Session共享。除此之外推荐参考相关学习网址:


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐