HTTP是一种无状态的请求,但是在实际应用中,往往需要保存浏览器请求的一些数据,这时候我们可以使用cookie或session来实现。
笔者在做一个Spring Boot社区项目时,需要做一个“显示登录信息”的功能,即显示当前用户的用户名、消息数、头像等信息。由于在网站中,HTTP是无状态的,无法保存当前用户的信息,因此需要使用cookie或session保存一些数据。
本文介绍cookie和session的特点,以及session在分布式部署中的处理。
版权声明:本文为博主原创文章,禁止转载
作者博客:codesong.cn
created: 2019-11-24
为什么要用cookie/session?
HTTP请求是一种简单的、可扩展、无状态有会话的请求。“无状态”也就是说客户端向服务器发送一次请求后,不保存当前状态,同一客户端再次发送相同请求时,服务器无法知道当前请求是哪个用户发出的。
浏览器和服务器是多对一的关系,为了判断请求是由哪个客户端发起的,可以使用cookie或session。
cookie及其特点
- cookie是服务器发送到浏览器,并保存在浏览器端的一小块数据。
- 浏览器下次访问该服务器时,会自动携带该块数据,将其发送到服务器。
使用cookie能够建立有状态的会话:浏览器首次向服务器发送请求时,服务器创建一个cookie对象以记住浏览器,并在响应时发送给浏览器,浏览器接收后将cookie保存在本地。当浏览器在此访问服务器时,会在请求首部字段中加入cookie带回给服务器,服务器因此识别浏览器。
cookie有以下特点:
- cookie保存在客户端中,用户可以直接查看,存在安全隐患。
- cookie多次向服务器发送请求,对服务器内存压力大
session的出现能够解决cookie的以上问题。
session及其特点
- session是JavaEE的标准,保存在服务端来记录客户端的信息
- 数据存放在服务端更加安全,但是也会增加服务端的压力
服务器接收到浏览器的请求后,创建一个session对象。在响应的时候,服务器返回一个含有session信息(sessionId)的cookie给浏览器,浏览器会将cookie对象存在本地,下次访问服务器时将cookie对象发送给服务器。服务器接再次接收到请求,会通过sessionId识别出浏览器。
session的主要特点为:
- session数据保存在服务端,更加安全,但是对服务器内存压力更大
分布式环境与session
在实际应用中常会采用分布式服务器,在分布式部署中,session会出现一些问题,相应地有一些解决方法。
nginx是负载均衡的服务器,浏览器直接访问的是nginx这个代理,nginx会根据服务其状态将请求分发给服务器。
显然,同一浏览器的请求并不能保证每次都被相同的服务器处理,这样session就失去了其作用。
解决分布式部署中session出现的这种问题,常见有三种方案:
- 粘性session(Sticky Session, 同一浏览器访问同一服务器)
- 同步session(Session Replication, 将session同步到所有服务器)
- 共享session(Session Server, 有一台服务器专门记录session)
三种方案特点如下:
粘性session:
同一个浏览器的请求分配给同一个服务器,很难保证服务器负载均衡。
同步session
将每个浏览器的session同步到所有服务器,会对服务器性能产生影响。
服务器之间会产生耦合,不利于分布式部署。
共享session
共享session中有一台服务器专门用来记录session,其他服务器都向此服务器提交、申请session。分布式部署是为了解决单体的瓶颈,但万一此服务器出现问题,就会出现很大的影响。
为解决以上三种方案带来的问题,可以采用以下思路:
能用cookie就用cookie,浏览器不方便存cookie时候,将cookie存储在数据库集群中。
缺点:关系型数据库在硬盘里,不如从内存中读数据性能好。(可以考虑Redis)