- HTTP的基本性质
- HTTP是简单的
- HTTP是可扩展的
- HTTP是无状态的,有会话的
- Cookie
- 是服务器发送到浏览器,并保存在浏览器端的一小块数据。
- 浏览器下次访问该服务器时,会自动携带块该数据,将其发送给服务器。
- Session
- 是JavaEE的标准,用于在服务端记录客户端信息。
- 数据存放在服务端更加安全,但是也会增加服务端的内存压力。
COOKIE
cookie大概的流程图就是这样,我们用一个小例子来了解一下。
我们在controller里写一个设置cookie的方法。创建一个cookie对象,key-value的形式。设置它的生效范围和生存时间,默认情况下,关闭浏览器后cookie是自动失效的,设置60*10就是10分钟后失效。
1 | //cookie示例 |
访问这个路径,在浏览器中打开检查看一看。可以看到在response header里有一个set-cookie。那么浏览器就会按照我们设置的最大时间保存这个cookie,并在访问我们指定的路径时带上这个cookie。
当浏览器带上这个cookie来访问的时候,我们使用@CookieValue注解来获取cookie里某一个key-value的值。可以看到页面显示了获取到的cookie,同时在请求头里也看到了cookie,说明浏览器发送这次请求的时候带上了cookie。
1 | "/alpha",method = RequestMethod.GET) (path = |
SESSION
由于cookie存在浏览器本地,不安全,所以有session方案,session也是和cookie一起用的。原理图如下。
session比较简单,我们只需要声明,spring容器就会自动注入,不需要我们创建。session可以存任意数据,cookie就只能存字符串。
1 | //session |
分布式部署下的session
由于现在网站流量都比较大,很少单服务器部署,那么使用session就会有一些问题。所以session使用比较少。
比如我们将项目部署在多台服务器上,这里涉及到nginx反向代理服务器,它会做一个负载均衡,有不同策略。浏览器访问nginx,如果按照哪台服务器比较空闲就将请求分配给哪台服务器的策略,那么当我创建session时可能是在服务器1,再次访问可能访问的服务器2,那么就无法正确的得到session。
这个问题解决有多种方案。
- 黏性session:固定ip分给同一个服务器处理,很难保证负载均衡
- 同步session:当某一个服务器创建session,会将session同步给其它服务器。同步影响服务器性能,服务器产生耦合,不利于部署。
- 将session单独交给一个服务器处理。这个服务器挂了,所有服务器都无法使用。
主流方法,能用cookie就用cookie,敏感数据就存到数据库。传统的数据库将数据存到硬盘,访问量大的时候也会出现性能瓶颈。所以使用redis缓存数据库是更好的解决方案。