技术干货程序员

Sentinel之从启动来分析加载过程

2018-12-08  本文已影响118人  橘子_好多灰

之前介绍过dashboard模块也引入的sentinel的核心模块sentinel-core,所以这里通过启动dashboard来分析sentinel在系统初次加载过程中做了什么?

本文基于:1.3.0-GA版本

一、启动dashboard项目

dashboard项目通过CommonFilter过滤器实现对资源的保护的。

image.png

启动项目后,访问首页,默认localhost:8080
在过滤器CommonFilter就会拦截请求的资源,如图。

image.png

这个时候就进入到sentinel的核心模块了。

二、进入ContextUtil

首先执行ContextUtil静态快内容,如图:


image.png

1、首先获取默认的Context名称:sentinel_default_context;Context是一次调用的上下文内容,主要包括:name,entranceNode(调用树资源入口),curEntry(当前实体)等信息,关于这个Context上下文、EntranceNode等后续再介绍。
2、构建一个EntranceNode节点node。
3、构建一个跟节点ROOT,并增加一个字节点node;见第三步Constants
4、把资源信息放到一个 contextNameNodeMap,后面进入资源名称相同直接可以从map中获取。

三、进入Constants

Constants是一个常量类,这里我们主要注意的是断点处,如图:

image.png

1、在构建一个DefaultNode,用的是new EntranceNode(ResourceWrapper,ClusterNode)方法,
2、EntranceNode是DefaultNode的子类,
3、ResourceWrapper是一个资源包装器,这里用的通用的StringResourceWrapper包装器,
4、构建一个ClusterNode用的是Env类的nodeBuilder的静态变量,通过DefaultNodeBuilder获取。

四、进入Env

image.png

注意到静态块内容,Env类在初始化会加载。来到InitExecutor类

五、进入InitExecutor

这个就是Sentinel的加载的核心了。

image.png

在doInit中:
1、有一个initialized原子变量,保证初始化内容只会执行一次
2、接着ServiceLoader<InitFunc> loader = ServiceLoader.load(InitFunc.class); 这行代码就是通过JDK自带的SDK自带的SPI机制获取InitFunc的实现类了,对SPI机制不熟悉的可以自查资料了解下;
这里默认自带了4种初始化内容

image.png

3、接下来第一个循环就是要初始的Init进行排序,
4、第二个循环就排序的顺序加载初始化

image.png

这里我们先进入到CommandCenterInitFunc中;

六、进入CommandCenterInitFunc

image.png

1、同样是通过SPI加载ComandCenter的实现类,这里用的是SimpleHttpCommandCenter,因为dashboard引入的sentinel-transport-simple-http模块,若是引入netty-http模块则是NettyHttpCommandCenter
2、然后执行beforeStart()和start()方法

七、进入SimpleHttpCommandCenter

先执行beforeStart方法

image.png

1、通过CommandHandlerProvider的namedHandlers方法获取所有的CommandHandler,见第八步
2、并把获取的ComandHandler注册到handlerMap中

接下来执行start方法
1、获取机器的核数
2、创建一个bizExecutor线程池
3、创建一个serverInitTask线程任务
4、放入到executor线程池(单个线程)中执行,在个线程中会把HttpEventTask任务放到bizExecutor线程池中的线程处理

八、进入CommandHandlerProvider

这里同样通过SPI机制获取实现了CommandHandler的类

image.png

可以发现实现ComandHandler有这么多。


image.png

1、在for循环中把获取注释的CommandMapping注解的类,并放入Map<String, CommandHandler>这个map中,方便下次直接获取。

回到SimpleHttpCommandCenter类的beforeStart方法中。

总结

1、sentinel在首次资源访问的的过程中SPI机制加载初始化的内容,后续资源进来了不用在加载一遍。
2、SPI机制sentinel用的很多,但是这个JDK在的SPI加载有个缺点,就是全量加载,很多没有用的功能也加载进来了;可以参考Dubbo的ExtensionLoader进行懒加载。
3、可以说sentinel首次加载的过程就是InitFunc加载的过程。
4、这里初始化只分析了CommandCenterInitFunc;至于其它几个:FileDataSourceInitsentinel默认没有用到,
ParamFlowStatisticSlotCallbackInit热点参数的,还在实践中,
HeartbeatSenderInitFunc这个就是用来发送心跳的。


以上内容,若有不当之处,谢谢指正

上一篇下一篇

猜你喜欢

热点阅读