Spring Cloud OAuth2 资源服务器CheckToken 源码解析

Spring Cloud OAuth2 资源服务器CheckToken 源码解析,第1张

当用户携带token 请求资源服务器的资源时, OAuth2AuthenticationProcessingFilter 拦截token,进行token 和userdetails 过程,把无状态的token 转化成用户信息。

最重要的 userTokenConverterextractAuthentication(map);

基于Spring Cloud、oAuth20开发基于Vue前后分离的开发平台,支持账号、短信、SSO等多种登录,提供配套视频开发教程。
>阅读《Spring微服务实战》笔记

项目地址: >大家好,本文我将继续来剖析SpringCloud中负载均衡组件Ribbon的源码。本来我是打算接着OpenFeign动态代理生成文章直接讲Feign是如何整合Ribbon的,但是文章写了一半发现,如果不把Ribbon好好讲清楚,那么有些Ribbon的细节理解起来就很困难,所以我还是打算单独写一篇文章来剖析Ribbon的源码,这样在讲Feign整合Ribbon的时候,我就不再赘述这些细节了。好了,话不多说,直接进入主题。

这是个很简单的东西,就是服务实例数据的封装,里面封装了服务实例的ip和端口之类的,一个服务有很多台机器,那就有很多个Server对象。

ServerList是个接口,泛型是Server,提供了两个方法,都是获取服务实例列表的,这两个方法其实在很多实现类中实现是一样的,没什么区别。这个接口很重要,因为这个接口就是Ribbon获取服务数据的来源接口,Ribbon进行负载均衡的服务列表就是通过这个接口来的,那么可以想一想是不是只要实现这个接口就可以给Ribbon提供服务数据了?事实的确如此,在SpringCloud中,eureka、nacos等注册中心都实现了这个接口,都将注册中心的服务实例数据提供给Ribbon,供Ribbon来进行负载均衡。

通过名字也可以知道,是用来更新服务注册表的数据,他有唯一的实现,就是PollingServerListUpdater,这个类有一个核心的方法,就是start,我们来看一下start的实现。

通过这段方法我们可以看出,首先通过isActivecompareAndSet(false, true)来保证这个方法只会被调用一下,然后封装了一个Runnable,这个Runnable干了一件核心的事,就是调用传入的updateAction的doUpdate方法,然后将Runnable扔到了带定时调度功能的线程池,经过initialDelayMs(默认1s)时间后,会调用一次,之后都是每隔refreshIntervalMs(默认30s)调用一次Runnable的run方法,也就是调用updateAction的doUpdate方法。

所以这个类的核心作用就是每隔30s会调用一次传入的updateAction的doUpdate方法的实现,记住这个结论。

IRule是负责负载均衡的算法的,也就是真正实现负载均衡获取一个服务实例就是这个接口的实现。比如说实现类RandomRule,就是从一堆服务实例中随机选取一个服务实例。

就是一个配置接口,有个默认的实现DefaultClientConfigImpl,通过这个可以获取到一些配置Ribbon的一些配置。

这个接口的作用,对外主要提供了获取服务实例列表和选择服务实例的功能。虽然对外主要提供获取服务的功能,但是在实现的时候,主要是用来协调上面提到的各个核心组件的,使得他们能够协调工作,从而实现对外提供获取服务实例的功能。

这个接口的实现有好几个实现类,但是我讲两个比较重要的。

BaseLoadBalancer

核心属性

allServerList:缓存了所有的服务实例数据

upServerList:缓存了能够使用的服务实例数据。

rule:负载均衡算法组件,默认是RoundRobinRule

核心方法

setRule:这个方法是设置负载均衡算法的,并将当前这个ILoadBalancer对象设置给IRule,从这可以得出一个结论,IRule进行负载均衡的服务实例列表是通过ILoadBalancer获取的,也就是 IRule 和 ILoadBalancer相互引用。setRule(rule)一般是在构造对象的时候会调用。

chooseServer:就是选择一个服务实例,是委派给IRule的choose方法来实现服务实例的选择。

BaseLoadBalancer这个实现类总体来说,已经实现了ILoadBalancer的功能的,所以这个已经基本满足使用了。

说完BaseLoadBalancer这个实现类,接下来说一下DynamicServerListLoadBalancer实现类。DynamicServerListLoadBalancer继承自BaseLoadBalancer,DynamicServerListLoadBalancer主要是对BaseLoadBalancer功能进行扩展。

DynamicServerListLoadBalancer

成员变量

serverListImpl:上面说过,通过这个接口获取服务列表

filter:起到过滤的作用,一般不care

updateAction:是个匿名内部类,实现了doUpdate方法,会调用updateListOfServers方法

serverListUpdater:上面说到过,默认就是唯一的实现类PollingServerListUpdater,也就是每个30s就会调用传入的updateAction的doUpdate方法。

这不是巧了么,serverListUpdater的start方法需要一个updateAction,刚刚好成员变量有个updateAction的匿名内部类的实现,所以serverListUpdater的start方法传入的updateAction的实现其实就是这个匿名内部类。

那么哪里调用了serverListUpdater的start方法传入了updateAction呢?是在构造的时候调用的,具体的调用链路是调用 restOfInit -> enableAndInitLearnNewServersFeature(),这里就不贴源码了

所以,其实DynamicServerListLoadBalancer在构造完成之后,默认每隔30s中,就会调用updateAction的匿名内部类的doUpdate方法,从而会调用updateListOfServers。所以我们来看一看 updateListOfServers 方法干了什么。

这个方法实现很简单,就是通过调用 ServerList 的getUpdatedListOfServers获取到一批服务实例数据,然后过滤一下,最后调用updateAllServerList方法,进入updateAllServerList方法。

其实很简单,就是调用每个服务实例的setAlive方法,将isAliveFlag设置成true,然后调用setServersList。setServersList这个方法的主要作用是将服务实例更新到内部的缓存中,也就是上面提到的allServerList和upServerList,这里就不贴源码了。

其实分析完updateListOfServers方法之后,再结合上面源码的分析,我们可以清楚的得出一个结论,那就是默认每隔30s都会重新通过ServerList组件获取到服务实例数据,然后更新到BaseLoadBalancer缓存中,IRule的负载均衡所需的服务实例数据,就是这个内部缓存。

从DynamicServerListLoadBalancer的命名也可以看出,他相对于父类BaseLoadBalancer而言,提供了动态更新内部服务实例列表的功能。

为了便于大家记忆,我画一张图来描述这些组件的关系以及是如何运作的。

说完一些核心的组件,以及他们跟ILoadBalancer的关系之后,接下来就来分析一下,ILoadBalancer是在ribbon中是如何使用的。

ILoadBalancer是一个可以获取到服务实例数据的组件,那么服务实例跟什么有关,那么肯定是跟请求有关,所以在Ribbon中有这么一个抽象类,AbstractLoadBalancerAwareClient,这个是用来执行请求的,我们来看一下这个类的构造。

通过上面可以看出,在构造的时候需要传入一个ILoadBalancer。

AbstractLoadBalancerAwareClient中有一个方法executeWithLoadBalancer,这个是用来执行传入的请求,以负载均衡的方式。

这个方法构建了一个LoadBalancerCommand,随后调用了submit方法,传入了一个匿名内部类,这个匿名内部类中有这么一行代码很重要。

这行代码是根据给定的一个Server重构了URI,这是什么意思呢?举个例子,在OpenFeign那一篇文章我说过,会根据服务名拼接出类似 >

微服务,是一个小型的服务,也是一种设计理念,将一个大型繁杂的系统拆分为多个小型的服务,进行独立部署,这些服务在独立进程中运行,通过特定的协议进行通信

优点:

缺点:

在服务通信性能上RPC更强,但是Rest更为灵活

SpringCloud是基于SpringBoot实现的微服务框架,为开发人员提供了很多快速构建分布式系统中常见模式的工具,包括配置管理、服务发现、断路器、智能路由、微代理,控制总线等。

Spring Cloud专注于为典型的用例提供良好的开箱即用体验,并为其他用例提供扩展性机制。

参考地址:

Eureka是Netflix开发的基于Rest的服务发现框架,SpringCloud基于此进行二次封装,实现服务的管理。

创建一个Eureka服务:>

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10642538.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-10
下一篇 2023-05-10

发表评论

登录后才能评论

评论列表(0条)

保存