我们这次项目主要从RestTemplate 和 Feign 进行选型分析。 一、Spring Cloud Feign分析 Feign是另外一种客户端负载均衡实现。 我在该模块写了Feign Client的示例代码。 【1】spring-cloud-web-demo-api为服务的
我们这次项目主要从RestTemplate 和 Feign 进行选型分析。 一、Spring Cloud Feign分析
我在该模块写了Feign Client的示例代码。 首先在spring-cloud-web-demo-api模块,定义Feign API。spring-cloud-web-demo为spring-cloud-web-demo-service暴露的服务名。
然后通过ClientAutoConfiguration自动装配。(client直接引入api包就可以使用,不需要再EnableFeignClients)
在service模块如以往Spring MVC般实现api模块接口即可。
在Client模块,注入bean后直接调用。
二、RestTemplate分析写了具有客户端负载均衡能力的RestTemplate的请求代码。 类似这样定义:
RestTemplate究竟是如何利用注册中心实现客户端负载均衡的呢? 实现方式: 就是将上面所说的LoadBalancerInterceptor负载均衡拦截器加到标注了@LoadBalanced的RestTemplate实例中。 LoadBalancerInterceptor拦截器会在执行过程中获取并设置适合的目标请求实例,重新构造请求URI。
三、技术选型最终选择使用OpenFeign,下面说说原因。 和RestTemplate比起来,OpenFeign显得更适合Spring Boot微服务。 Open Feign相当于(HTTP)RPC,相比起RestTemplate,它直接显式将API声明以JAVA接口形式标识出来。 并且因为底层用的动态代理,它还可以(无感知地)替换底层实现。比如,github上就有替换底层逻辑的repo – Open Feign+Dubbo的RPC实现。 通过sdk包的形式,方便了调用,不需要像RestTemplate一样,客户端自行拼接上一串请求参数。在代码编写上也清晰。 要使用就必须知道OpenFeign是怎么实现的呢? 四、OpenFeign 初始化分析流程图如下: 看看前面例子里我们引入的OpenFeign的东西 我们就从这两个注解开始分析源码。
【2】接下来重点关注@EnableFeignClients注解是如何扫描FeignClient接口的。
嗯,发现没有,就是FeignClientsRegistrar做处理的。来分析下重点方法registerFeignClients和registerFeignClient
可以看到最后注册beanDefinition时,我们看到注册了FeignClientFactoryBean这一FactoryBean。 我们看看工厂bean FeignClientFactoryBean是如何构造对象的。
在非调试情况下(即我们没设置url参数), 我们来看看targeter.target(this, builder, context, target)做了什么。 Targeter接口是构造被请求的代理bean的类。有两个实现类HystrixTargeter、DefaultTargeter。 HystrixTargeter会比默认的多设置一些回滚措施,用到Feign的Contract属性, 我会先从DefaultTargeter说起。 DefaultTargeter会通过Feign.Builder#target(Target target)生成实例。我们来看看代码。
在解读ReflectiveFeign前介绍几个概念: 有了以上介绍,接下来简单分析ReflectiveFeign的newInstance方法。
初始化完成。 五、OpenFeign 执行分析上图是OpenFeign构造的代理对象被调用时的时序图。 下面介绍执行过程中涉及到源码中的部分组件。
6、LoadBalancerFeignClient Client接口的实现类,是具有负载均衡能力的Client。Client接口为执行HTTP的接口,Client.Default是最终发出HTTP请求的类。 7、FeignLoadBalancer FeignLoadBalancer通过ILoadBalancer选择合适Server,通过Server重组URI,通过RibbonRequest持有的Client执行实际HTTP请求包装成Response。 熔断: 在FeignClientsConfiguration中, 当配置了feign.hystrix.enabled,Feign Builder使用HystrixFeign.builder()。 所以build的时候新建HystrixInvocationHandler和HystrixDelegatingContract实例。
来看看HystrixInvocationHandler的hystrix调用代码
|
2021-06-05
2021-05-27
2021-05-26
2021-06-05
2021-05-16