1、什么是Session/Cookie?
用户使用网站的服务,基本上需要浏览器与Web服务器的多次交互。HTTP协议本身是无状态的,当用户的第一次访问请求结束后,后端服务器就无法知道下一次来访问的还是不是上次访问的用户。我们需要基于HTTP协议支持会话状态的机制,这样的机制可以使Web服务器从多次单独的HTTP请求中知道哪些请求是来自哪个会话的。
Session与Cookie的作用都是为了保持访问用户与后端服务器的交互状态。
1.1、理解Cookie
1.2、理解Session
Cookie可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果Cookie很多,这无形地增加了客户端与服务端的数据传输量,而Session的出现正是为了解决这个问题。
同一个客户端每次和服务端交互时,不需要每次都传回所有的Cookie值,而是只要传回一个会话标识(SessionId),这个ID是客户端第一次访问服务器的时候生成的,而且每个客户端是唯一的。这样每个客户端就有一个唯一的ID,客户端只要传回这个ID就行了,这个ID通常是NAME为PHPSESIONID的一个Cookie。在Web服务器上,各个会话独立存储保存不同会话的信息。如果遇到禁用Cookie的情况,一般的做法就是把这个会话标识放到URL的参数中。
2、集群遇到的问题
从用户端来解释,就是当一个用户第一次访问被负载均衡代理到后端服务器A并登录后,服务器A上保留了用户的登录信息;当用户再次发送请求时,根据负载均衡策略可能被代理到后端不同的服务器,例如服务器B,由于这台服务器B没有用户的登录信息,所以导致用户需要重新登录。这对用户来说是不可忍受的。所以,在实施负载均衡的时候,我们必须考虑Session的问题。
3、解决集群Session共享问题
在负载均衡中,针对Session的处理,我们一般有以下几种方法:
(1)、Session 保持
(2)、Session 复制
(3)、Session 共享
3.1、会话保持(Session Sticky)
Session保持(会话保持)是我们见到最多的名词之一,通过会话保持,负载均衡进行请求分发的时候保证每个客户端固定的访问到后端的同一台应用服务器。会话保持方案在所有的负载均衡都有对应的实现。而且这是在负载均衡这一层就可以解决Session问题。
对于Nginx可以选用Session保持的方法实行负载均衡,nginx的upstream目前支持5种方式的分配方式,其中有两种比较通用的Session解决方法,ip_hash和url_hash。注意:后者不是官方模块,需要额外安装。
upstream bakend { server192.168.0.11:80; server192.168.0.12:80; ip_hash; }
3.2、会话复制(Session Replication)
此方案不用再要求负载均衡器保证同一个会话的多次请求必须到同一个Web服务器上了。我们在Web服务器之间增加了会话数据的同步,通过同步就保证了不同Web服务器之间Session数据的一致。
3.3、会话共享
Session数据不保存到本机而且存放到一个集中存储的地方,修改Session也是发生在集中存储的地方。Web服务器使用Session从集中存储的地方读取。这样保证了不同Web服务器读取到的Session数据都是一样的。存储Session的具体方式可以是数据库、分布式存储系统等。
PHP通过两行配置就可以把Session存放在Memcached或者Redis中,当然你要提前配置好他们。
使用memcache存储Session session.save_handler = memcache session.save_path = "tcp://192.168.56.11:11211"
使用redis存储Session session.save_handler = redis session.save_path ="tcp://localhost:6379"