自从开始工作以来,每天都会遇到各种技术名词,由于非计算机专业科班出身,很多词汇看的一头雾水。这就看一篇博客收集整理一下。久而久之就都会了
自从开始工作以来,每天都会遇到各种技术名词,由于非计算机专业科班出身,很多词汇看的一头雾水。这就看一篇博客收集整理一下。久而久之就都会了
token,session,cookie 相关#
一、我们先解释一下他的含义:
1、Token 的引入:Token 是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token 便应运而生。
2、Token 的定义:Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个 Token 便将此 Token 返回给客户端,以后客户端只需带上这个 Token 前来请求数据即可,无需再次带上用户名和密码。
3、使用 Token 的目的:Token 的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
了解了Token的意义后,我们就更明确的知道为什么要用他了。
二、如何使用Token?
这是本文的重点,在这里我就介绍常用的两种方式。
1、用设备号 / 设备 mac 地址作为 Token(推荐)
客户端:客户端在登录的时候获取设备的设备号/mac地址,并将其作为参数传递到服务端。
服务端:服务端接收到该参数后,便用一个变量来接收同时将其作为Token保存在数据库,并将该Token设置到session中,客户端每次请求的时候都要统一拦截,并将客户端传递的token和服务器端session中的token进行对比,如果相同则放行,不同则拒绝。
分析:此刻客户端和服务器端就统一了一个唯一的标识 Token,而且保证了每一个设备拥有了一个唯一的会话。该方法的缺点是客户端需要带设备号 /mac 地址作为参数传递,而且服务器端还需要保存;优点是客户端不需重新登录,只要登录一次以后一直可以使用,至于超时的问题是有服务器这边来处理,如何处理?若服务器的 Token 超时后,服务器只需将客户端传递的 Token 向数据库中查询,同时并赋值给变量 Token,如此,Token 的超时又重新计时。
2、用 session 值作为 Token
客户端:客户端只需携带用户名和密码登陆即可。
客户端:客户端接收到用户名和密码后并判断,如果正确了就将本地获取sessionID作为Token返回给客户端,客户端以后只需带上请求数据即可。
分析:这种方式使用的好处是方便,不用存储数据,但是缺点就是当 session 过期后,客户端必须重新登录才能进行访问数据。
三、使用过程中出现的问题以及解决方案?
刚才我们轻松介绍了 Token 的两种使用方式,但是在使用过程中我们还出现各种问题,Token 第一种方法中我们隐藏了一个在网络不好或者并发请求时会导致多次重复提交数据的问题。
该问题的解决方案:将session和Token套用,如此便可解决,如何套用呢?请看这段解释:
session 是一个在单个操作人员整个操作过程中,与服务器端保持通信的唯一识别信息,在同一操作人员的多次请求当中,session 始终保证是同一对象,
而不是多个对象,因为可以对其加锁。当同一操作人员多个请求进入时,可以通过 session 限制只能单向通行。本文正是通过使用 session 以及在 session
中加入 token,来验证同一操作人员是否进行了并发重复的请求,在最后一个请求到来时,使用 session 中的 token 验证请求中的 token 是否一致,当不一致
时,被认为是重复提交,将不允许通过。
这就是解决重复提交的方案。
四、session 和 token 和 cookie
什么是 session 认证?
http 协议是一无状态协议,所以如果用户向后台应用提供了用户名和密码来进行认证,下一次请求时,用户还是要带上用户名和密码进行用户认证。为了使后台应用能识别是哪个用户发出的请求,只能在后台服务器存储一份用户登陆信息,这份信息也会在响应前端请求时返回给浏览器(前端),前端将其保存为 cookie,下次请求时前端发送给后端应用,后端应用就可以识别这个请求是来自哪个用户了,这就是传统的 session 认证
session 认证的过程是怎样的?
浏览器第一次访问服务器,服务器会创建一个 session,然后同时为该 session 生成一个唯一的会话的 key, 也就是 sessionid,然后,将 sessionid 及对应的 session 分别作为 key 和 value 保存到缓存中,也可以持久化到数据库中,然后服务器再把 sessionid,以 cookie 的形式发送给客户端。这样浏览器下次再访问时,会直接带着 cookie 中的 sessionid。然后服务器根据 sessionid 找到对应的 session 进行匹配;
还有一种是浏览器禁用了 cookie 或不支持 cookie,这种可以通过 URL 重写的方式发到服务器;
什么是 token 认证?
token 的意思是 “令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。
当用户第一次登录后,服务器生成一个 token 并将此 token 返回给客户端,以后客户端只需带上这个 token 前来请求数据即可,无需再次带上用户名和密码。
token 认证与 session 认证的区别?
token 和 session 其实都是为了身份验证,session 一般翻译为会话,而 token 更多的时候是翻译为令牌;
session 服务器会保存一份,可能保存到缓存,文件,数据库;同样,session 和 token 都是有过期时间一说,都需要去管理过期时间;
其实 token 与 session 的问题是一种时间与空间的博弈问题,session 是空间换时间,而 token 是时间换空间。两者的选择要看具体情况而定。
虽然确实都是 “客户端记录,每次访问携带”,但 token 很容易设计为自包含的,也就是说,后端不需要记录什么东西,每次一个无状态请求,每次解密验证,每次当场得出合法 / 非法的结论。这一切判断依据,除了固化在 CS 两端的一些逻辑之外,整个信息是自包含的。这才是真正的无状态。
而 sessionid ,一般都是一段随机字符串,需要到后端去检索 id 的有效性。万一服务器重启导致内存里的 session 没了呢?万一 redis 服务器挂了呢?
方案 A :我发给你一张身份证,但只是一张写着身份证号码的纸片。你每次来办事,我去后台查一下你的 id 是不是有效。
方案 B :我发给你一张加密的身份证,以后你只要出示这张卡片,我就知道你一定是自己人。
就这么个差别。
两种认证方式都是为了解决 Http 协议状态保持的问题,因为 http 协议是一种无状态协议。
Rest 服务#
rest 应该具备以下条件:
使用客户 / 服务器模型 (简称 C/S 结构,是一种网络架构,它把客户端 (Client) 与服务器 (Server) 区分开来。 每一个客户端软件的实例都可以向一个服务器或应用程序服务器发出请求。)
例如前后端分离,页面和服务不在同一服务器上运行。
层次化的系统
例如一个父系统下有多个子模块,每个模块都是独立的服务。
无状态
服务端并不会保存有关客户的任何状态,也就是说要服务后端服务,就要带 token 过去。
可缓存
例如服务端通过 token 缓存已登录过的用户信息,客户端请求会带一个 token 过来,后台服务通过带过来的 token 在缓存中取出用户信息,提高效率。
统一的接口
例如,一个项目的所有模块都整合到一起,all-in-one,打成一个包,多个服务,整合到一个端口下。
如果一个系统满足了上面所列出的五条约束,那么该系统就被称为是 RESTful 的 (一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。)
Eureka#
一、Eureka 简介
Eureka 是 Netflix 开发的_服务发现框架_,本身是一个基于 REST 的服务,主要用于定位运行在 AWS 域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务发现功能。
1、Eureka 组件
Eureka 包含两个组件:Eureka Server 和 Eureka Client。
1.1 Eureka Server
Eureka Server 提供服务注册服务,各个节点启动后,会在 Eureka Server 中进行注册,这样 Eureka Server 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Server 本身也是一个服务,默认情况下会自动注册到 Eureka 注册中心。
如果搭建单机版的 Eureka Server 注册中心,则需要配置取消 Eureka Server 的自动注册逻辑。毕竟当前服务注册到当前服务代表的注册中心中是一个说不通的逻辑。
Eureka Server 通过 Register、Get、Renew 等接口提供服务的注册、发现和心跳检测等服务。
2.1 Eureka Client
Eureka Client 是一个 java 客户端,用于简化与 Eureka Server 的交互,客户端同时也具备一个内置的、使用轮询 (round-robin) 负载算法的负载均衡器。在应用启动后,将会向 Eureka Server 发送心跳,默认周期为 30 秒,如果 Eureka Server 在多个心跳周期内没有接收到某个节点的心跳,Eureka Server 将会从服务注册表中把这个服务节点移除 (默认 90 秒)。
Eureka Client 分为两个角色,分别是:Application Service (Service Provider) 和 Application Client (Service Consumer)
2.1.1 Application Service
服务提供方,是注册到 Eureka Server 中的服务。
2.1.2 Application Client
服务消费方,通过 Eureka Server 发现服务,并消费。
在这里,Application Service 和 Application Client 不是绝对上的定义,因为 Provider 在提供服务的同时,也可以消费其他 Provider 提供的服务;Consumer 在消费服务的同时,也可以提供对外服务。
SpringMVC Spring boot Spring Cloud#
spring boot 只是一个配置工具,整合工具,辅助工具.
springmvc 是框架,项目中实际运行的代码
Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa 等等。但他们的基础都是 Spring 的 ioc 和 aop,ioc 提供了依赖注入的容器, aop 解决了面向横切面的编程,然后在此两者的基础上实现了其他延伸产品的高级功能。
Spring MVC 提供了一种轻度耦合的方式来开发 web 应用。它是 Spring 的一个模块,是一个 web 框架。通过 Dispatcher Servlet, ModelAndView 和 View Resolver,开发 web 应用变得很容易。解决的问题领域是网站应用程序或者服务开发 ——URL 路由、Session、模板引擎、静态 Web 资源等等。
Spring Boot 实现了自动配置,降低了项目搭建的复杂度。它主要是为了解决使用 Spring 框架需要进行大量的配置太麻烦的问题,所以它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。同时它集成了大量常用的第三方库配置 (例如 Jackson, JDBC, Mongo, Redis, Mail 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用 (out-of-the-box)。
Spring Boot 只是承载者,辅助你简化项目搭建过程的。如果承载的是 WEB 项目,使用 Spring MVC 作为 MVC 框架,那么工作流程和你上面描述的是完全一样的,因为这部分工作是 Spring MVC 做的而不是 Spring Boot。
对使用者来说,换用 Spring Boot 以后,项目初始化方法变了,配置文件变了,另外就是不需要单独安装 Tomcat 这类容器服务器了,maven 打出 jar 包直接跑起来就是个网站,但你最核心的业务逻辑实现与业务流程实现没有任何变化。
总结:Spring 最初利用 “工厂模式”(DI)和 “代理模式”(AOP)解耦应用组件。大家觉得挺好用,于是按照这种模式搞了一个 MVC 框架(一些用 Spring 解耦的组件),用开发 web 应用( SpringMVC )。然后发现每次开发都写很多样板代码,为了简化工作流程,于是开发出了一些 “懒人整合包”(starter),这套就是 Spring Boot。
所以,用最简练的语言概括就是:
Spring 是一个 “引擎”;
Spring MVC 是基于 Spring 的一个 MVC 框架;
Spring Boot 是基于 Spring4 的条件注册的一套快速开发整合包。
SpringCloud 是一套目前完整的微服务框架,它是是一系列框架的有序集合。它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 SpringBoot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 SpringBoot 的开发风格做到一键启动和部署。
什么是 token
Spring 基础知识详解
Eureka 介绍
feign 设计原理
Spring boot 和 Spring Cloud
HTTP 就是这么简单
消息队列介绍
动态代理详细分析
CAS#
cas 是 compare and swap 的简称,从字面上理解就是比较并更新,简单来说:从某一内存上取值 V,和预期值 A 进行比较,如果内存值 V 和预期值 A 的结果相等,那么我们就把新值 B 更新到内存,如果不相等,那么就重复上述操作直到成功为止。CAS 就是一种乐观锁,而 synchronized 就是悲观锁
IO 多路复用#
题外话:我们现在要仔细的说一说 I/O 多路复用机制,因为这个说法实在是太通俗了,通俗到一般人都不懂是什么意思。博主打一个比方:小曲在 S 城开了一家快递店,负责同城快送服务。小曲因为资金限制,雇佣了一批快递员,然后小曲发现资金不够了,只够买一辆车送快递。
经营方式一
客户每送来一份快递,小曲就让一个快递员盯着,然后快递员开车去送快递。慢慢的小曲就发现了这种经营方式存在下述问题,几十个快递员基本上时间都花在了抢车上了,大部分快递员都处在闲置状态,谁抢到了车,谁就能去送快递随着快递的增多,快递员也越来越多,小曲发现快递店里越来越挤,没办法雇佣新的快递员了快递员之间的协调很花时间综合上述缺点,小曲痛定思痛,提出了下面的经营方式经营方式二
小曲只雇佣一个快递员。然后呢,客户送来的快递,小曲按送达地点标注好,然后依次放在一个地方。最后,那个快递员依次的去取快递,一次拿一个,然后开着车去送快递,送好了就回来拿下一个快递。
对比
上述两种经营方式对比,是不是明显觉得第二种,效率更高,更好呢。在上述比喻中:
每个快递员 ——————> 每个线程
每个快递 ——————–> 每个 socket (I/O 流)
快递的送达地点 ————–>socket 的不同状态
客户送快递请求 ————–> 来自客户端的请求
小曲的经营方式 ————–> 服务端运行的代码
一辆车 ———————->CPU 的核数
于是我们有如下结论
1、经营方式一就是传统的并发模型,每个 I/O 流 (快递) 都有一个新的线程 (快递员) 管理。
2、经营方式二就是 I/O 多路复用。只有单个线程 (一个快递员),通过跟踪每个 I/O 流的状态 (每个快递的送达地点),来管理多个 I/O 流。