soul网关源码学习11-http代理解析(上)
前言
soul作为一款高性能网关,可以转发各种类型的接口,如http,dubbo,springcloud,sofa等,那么它是通过怎么样的方式来进行转发呢?如何动态的上下线接口呢?如何保证接口一直能处于服务状态呢?
下面顺着上面几个问题,以http接口为例子,解析代码。
一、启动项目
- 启动admin项目
- 启动bootstrap项目
- 启动http-example项目
二、源码解析
启动完这三个项目之后思考一下,既然是http
接口要接入网关,猜测会有一个把接口注册到网关的动作,这个动作应该是在http
接口这个项目启动的时候做的。通过控制台看一下http-example
项目的日志,o.d.s.client.common.utils.RegisterUtils : http client register success
,直接就可以从RegisterUtils
这个工具类入手。
- 找到这个工具类,看一下是哪里调用的,由于我们用的http服务,所以应该是
SpringMvcClientBeanPostProcessor
这里面调用的。
- 找到
SpringMvcClientBeanPostProcessor
这个类,先不急着看里面有什么东西,先看一下是哪里调用的。
- 找到这个配置类
SoulSpringMvcClientConfiguration
,可以看出这里面加载了两个bean
,下面仔细看一下这两个bean
加载过程做了什么,直接打上两个断点,重启http-example
。
- 断点先到
SpringMvcClientBeanPostProcessor
,直接进入类里面。
- 构造方法做了一下初始化的东西,创建了一个线程池。
- 然后注意一下
SpringMvcClientBeanPostProcessor
这个类,实现了BeanPostProcessor
接口,所以它会在加载bean之后执行postProcessAfterInitialization
方法,打上断点。debug往下走,进来这里。
- 这里注意一下这个full字段,在配置文件里面配置的,我们现在配的是false,所以debug直接往下走。
soul:
http:
adminUrl: http://localhost:9095
port: 8188
contextPath: /http
appName: http
full: false
- 往下走可以看到这里扫描了
Controller
、RestController
、RequestMapping
这几个注解,这里可以看到有很多bean扫描到的这几个类型的注解都是null,所以断点直接打到里面去。 - 继续往下执行,可以看到扫描到了上面的那几个注解的其中一个,然后再进一步扫描
SoulSpringMvcClient
注解,这个注解应该就是表示这个接口要被soul
网关代理了。
- 往下走,走到线程池这里来,这个地址是
admin
的一个接口地址,进去RegisterUtils
的doRegister
方法里面做了什么。
- 通过http请求调了
admin
注册api
的接口。
- 继续往下,通过反射拿到
bean
所有的方法,然后再判断方法有没有SoulSpringMvcClient
注解,有的话由soul网关代理,下面也是同样的操作,通过http请求调用admin
的接口。 - 断点继续往下走,来到
ContextRegisterListener
这里。
- 进入里面,看它的构造方法,对参数做了校验,然后做了初始化的操作。注意看一下这个类实现了
ApplicationListener
接口,所以在onApplicationEvent
方法打上断点。
- 往下走,进到这个
onApplicationEvent
方法里面,注意看一下事件类型ContextRefreshedEvent
,这个表示spring
容器加载完毕之后触发监听的。而且这个监听有可能是会被触发多次的,为了防止触发多次,前面加了个判断。 - 继续往下走,因为我们
full
字段配置了false
,所以直接结束了。
- 整个过程加载完毕,下面把
full
字段配置成true
,看一下有哪些不同的地方。
soul:
http:
adminUrl: http://localhost:9095
port: 8188
contextPath: /http
appName: http
full: true
- 改完之后重启
http-example
,同样的断点,这里只看有区别的地方。执行到这里的时候由于full是true
,所以直接返回bean
,不扫描注解。
- 执行到这里的时候,会去注册所有的接口。
- 看一下
buildJsonParams
方法,全路径匹配。
- 走到这里,整个http服务注册客户端的流程就走完了。
三、总结
整个注册的过程就是围绕着spring的加载流程,再配合反射,扫描注解等,去找到需要代理的接口,然后通过http请求的方式发送数据到admin
,下一讲继续看admin
接收到数据之后做了哪些操作。