一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。
上次我们深入讲解了 Ribbon 的架构原理,这次我们再来看下 Feign 远程调用的架构原理。
上次我们已经梳理了 OpenFeign 解析 MVC 注解的原理,接着我们就来顺着这个核心流程来讲解 OpenFeign 发送请求的原理。
本文以开源 SpringCloud 项目 PassJava 作为示例。
开源地址: github.com/Jackson0714…
喜欢的小伙伴来点个 Star 吧,冲 2K Star。
OpenFeign 发送请求的原理
先上流程图:
还是在 ReflectiveFeign 类中,有一个 invoke 方法,会执行以下代码:
dispatch.get(method).invoke(args);
这个 dispatch 我们之前已经讲解过了,它指向了一个 HashMap,里面包含了 FeignClient 每个接口的 MethodHandler 类。
这行代码的意思就是根据 method 找到 MethodHandler,调用它的 invoke 方法,且传的参数就是我们接口中的定义的参数。
那我们再跟进去看下这个 MethodHandler invoke 方法里面做了什么事情。源码如下所示:
public Object invoke(Object[] argv) throws Throwable {
RequestTemplate template = buildTemplateFromArgs.create(argv);
...
}
我们可以看到这个方法里面生成了 RequestTemplate,它的值类似如下:
GET /study/list/test/1 HTTP/1.1
RequestTemplate 转换成 Request,它的值类似如下:
GET http://passjava-study/study/list/test/1 HTTP/1.1
这不路径不就是我们要 study 服务的方法,这样就可以直接调用到 study 服了呀!
OpenFeign 帮我们组装好了发起远程调用的一切,我们只管调用就好了。
接着 MethodHandler 会执行以下方法,发起 HTTP 请求。
client.execute(request, options);
从上面的我们要调用的服务就是 passjava-study,但是这个服务的具体 IP 地址我们是不知道的,那 OpenFeign 是如何获取到 passjava-study 服务的 IP 地址的呢?
回想下最开始我们提出的核心问题:OpenFeign 是如何进行负载均衡的?
我们是否可以联想到上一讲的 Ribbon 负载均衡,它不就是用来做 IP 地址选择的么?
那我们就来看下 OpenFeign 又是如何和 Ribbon 进行整合的。
我是悟空,期待与你一起打怪升级变强,我们下期见。
作者简介:悟空,8年一线互联网开发和架构经验,用故事讲解分布式、架构设计、Java 核心技术。《JVM性能优化实战》专栏作者,开源了《Spring Cloud 实战 PassJava》项目,公众号:悟空聊架构。本文已收录至 www.passjava.cn