让你用最轻松的方式,不说学会,至少能懂什么叫springcloud及其组件: SpringCloud版本Hoxton SR5 --- 第一讲:认识
接下来,就好好剖析剖析Session:
先说一些小结论,再慢慢分析:其实在我看来Session不仅仅是服务器(tomcat)生成的Session ID,我认为所有的可以建立: 浏览器端/App 与 服务器 之间的一对一的交互,都可以被称为Session。比如:app与服务器之间就是用token,其实就改了个名字,还是模仿的Session原理。
所以在我看来,Seesion是一种抽象的概念,没有具体实现,他是一种思想。
在实际项目,基本就分两种架构:
1. 单体服务器部署项目
2. 多台服务器的微服务架构(微服务解决方案不只springcloud,double也是可以的)
当我们用浏览器第一次访问服务器(tomcat)之前,首先浏览器端是没有session ID的,当浏览器访问到tomcat的时候,这时候tomcat要回复浏览器数据的过程其实就是:服务器端的tomcat自己生成了一个session ID,并返回给了浏览器端,这时候浏览器端把session ID保存到Cookie中,这时候浏览器端就有了session ID,以后再不关闭浏览器的前提下,每次访问这个tomcat服务器,都会把这个session ID自动带上来访问我们的tocmat,而我们后端程序员就是依靠这个session ID进行用户确认的。
传统情况下, 我们是这样使用的:当用户访问我们的网站后,tomcat服务器自动生成一个SeesionID,然后返回给浏览器,后面在不关闭浏览器的情况下,每次访问我们这个网站,都会带上tomcat返回给浏览器的SeesionID,当用户登录成功后,我们把这个SeesionID 和 用户信息,以键值对的数据结构保存在redis中,然后每次访问的时候,我们都获取浏览器传给服务器的SeesionID去redis查,没找到提示登录,找到了程序继续。
那么这个一个过程,其实就是对SessionID的应用。还有些人,会禁用浏览器端的Cookie,这时候浏览器端就不能保存SessionID了,比如你禁用Cookie后,淘宝就不能登录了,淘宝就不能正常使用了。再比如你用手机App使用淘宝,App没有Cookie这一说法,是不是就不能登录淘宝使用了呢 ?
所以我上面说,Session宏观上来说是一种抽象的概念。
浏览器端禁用了Seesion也可以用其他方法,其实就是要将SessionId就是保存在用户端。比如浏览器http请求的headers里面保存SessionID,每次访问tomat服务器,把header中的SessionID传到tomcat服务器中。程序员通过header的SessionID也可以确认访问者的身份、再比如App里没有seesion、header、cookie,可以保存到文件中呀,然后通过访问http的网站后面跟一段SessionID数据、或者在请求参数中,带上SessionID,tomcat服务器端拦截所有请求,先分析参数,通过的继续访问,没通过的提示登录。
所以可以先总结一下:
Seesion在微观上,就是浏览器访问tomcat,然后tomcat自己会生成一个SessionID返回给浏览器端保存起来,再访问其他tomcat又会生成一个sessionID继续保存在浏览器端。
宏观上,就是用户端访问服务器端,登录成功后,服务器端通过程序员设置一个ID,返回给用户端保存起来,然后用户再访问服务器,就带上这个ID,以此来确认用户的身份。
而对Session的应用很多网站都是微观上的使用,比如淘宝,你禁用了cookie就不能登录了。
1. 单体服务(一台tomcat服务器)
对于我国的互联网技术发展过程,以前主流的都是一台服务器,然后tomcat服务器生成session,登录成功后将session与个人信息以map的数据结构保存起来,后面每次访问都去查询出个人信息,再执行后面的程序,但是一台服务器肯定不能够满足日益发展的互联网大国。
2. 初具形态的微服务架构 (3台服务器)
这时候有了一项技术,就是tomcat支持多台tomcat之间的session共享。只需要在tomcat的配置中修改一下,然后几台服务器就会session共享,再使用nginx做转发。这种方式有个缺点:tomcat服务器越多,那tomcat需要将所有tomcat的session都保持一致,非常浪费资源和时间,面对访问量日益增加不得不使用其他方式。
3. 解决服务器数量限制的微服务架构
使用nginx的ip-hash,什么意思呢 ?就是说,一个nginx做转发连接多台tomcat服务器,nginx有个功能,就是说将访问ip与tomcat绑定,比如成都某区的电信ip为125.70.56开头 。这个地区用户访问nginx,然后nginx就指定ip为125.70.56开头的用户访问A tomcat,其他ip访问B tomcat,用这种方法来固定session访问。缺点:第一,这个配置工作大大增加了运维的工作量 。第二:如果这个区域访问人数突然增多这个tomcat也会宕机。
4. 用redis保存session 微观上使用session (适用于大型项目 与 第5个方案差不多,还是有点区别)
比如用10台服务器做登录的项目,不管访问到哪台服务器登录成功后,我们都将该请求的sessionid和用户信息保存到redis中,然后访问其他服务器功能的时候,我们浏览器端拿到这个sessionid给服务器,服务器去redis中查询出用户信息,就完成了session的校验。
5. 宏观上的使用Session(可以用于:springcloud 或者 double架构的大型微服务分布式架构)
随着电子产品的发展。App成为了互联网主流,上面也说了,App这种客户端没有cookie、session这一说法,他只能把数据保存到文件中。所以把session通过http的方式,自动上传到服务器就不现实了。App中把这种类似Session的东西,叫做token。使用原理其实也都差不多,比如app登录成功之后,服务器返回一个类似uuid东西,然后app保存到本地文件中,再访问服务器的时候,就把token传上来,通常token里面是有当前手机的唯一标识和一些用户信息的,这样服务器端直接解析确认用户就好了,还可以判断用户是否换手机登录以保证用户的安全,还可以获取用户平时登录的ip地址来做安全校验,不过这都是一些衍生品。
上面说app,下面就说说浏览器端,当做一个大型的项目的时候,比如淘宝,你在浏览器端登录淘宝之后,你再去访问天猫,你会发现不用登录。再比如说,你登录了百度文库,你再去访问百度地图、百度音乐、百度贴吧也都不用再登录这就叫单点登录(SSO),而实现这个功能,其实依然可以用第4中方式,为什么这里说宏观上使用session呢 ?因为在微观上session是tomcat自己生成的,而我们可以按照我们的规则生成我们想要的sessionID (暂时称为UUID,便于区分),完全脱离tomcat的session,比如我们自己生成的UUID中可以带有很多信息。然后再保存到redis,返回给浏览器端保存起来(这里还有一个问题就是:返回给浏览器端基本都是保存在cookie中,为了其他域名的地址,可以访问到这个cookie,所以浏览器在返回这个数据的时候,要设置cookie的访问域),然后访问其他跨域的网站时,就会把我们返回给浏览器的UUID,再传入服务器,服务器端查询redis做验证就好了。
这也是技术发展到今天,最好的一种方式。
另外在使用springcloud的时候,很可能使用zuul组件。当zuul路由多个微服务的时候,浏览器端是将session交给了zuul,所以我们需要在zuul的过滤器中获取到session,然后再由zuul传给调用的微服务 ,比如将session放在header里面,再调用微服务。