龙空技术网

Feign 实战-> 源码

java联网架构师 250

前言:

现时姐妹们对“aspnetmvc泛解析”大体比较着重,看官们都需要剖析一些“aspnetmvc泛解析”的相关资讯。那么小编同时在网上汇集了一些关于“aspnetmvc泛解析””的相关文章,希望朋友们能喜欢,你们快快来学习一下吧!

一、Feign简介

Feign是Netflix开发的⼀个轻量级RESTful的HTTP服务客户端(⽤它来发起请求,远程调⽤的),是以Java接⼝注解的⽅式调⽤Http请求,⽽不⽤像Java中通过封装HTTP请求报⽂的⽅式直接调⽤,Feign被⼴泛应⽤在Spring Cloud 的解决⽅案中。 类似于Dubbo,服务消费者拿到服务提供者的接⼝,然后像调⽤本地接⼝⽅法⼀样去调⽤,实际发出的是远程的请求。

常规的RestTemplate请求存在拼接url restTmplate.getForObJect比较模版化,硬编码等不便之处。

Feign可帮助我们更加便捷,优雅的调⽤HTTP API:不需要我们去拼接url然后呢调⽤ restTemplate的api,在SpringCloud中,使⽤Feign⾮常简单,创建⼀个接⼝(在消费者--服务调⽤⽅这⼀端),并在接⼝上添加⼀些注解,代码就完成了SpringCloud对Feign进⾏了增强,使Feign⽀持了SpringMVC注解(OpenFeign)

本质:封装了Http调⽤流程,更符合⾯向接⼝化的编程习惯,类似于Dubbo的服务调⽤ Dubbo的调⽤⽅式其实就是很好的⾯向接⼝编程

二、 Feign配置应⽤

Feign = RestTemplate+Ribbon+Hystrix

消费者引⼊Feign依赖

<dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
消费者启动类使⽤注解@EnableFeignClients添加Feign⽀持 @EnableFeignClients,注意:此时去掉Hystrix熔断的⽀持注解@EnableCircuitBreaker即可包括引⼊的依赖,因为Feign会⾃动引⼊创建Feign接⼝
// name:调⽤的服务名称,和服务提供者yml⽂件中spring.application.name保持⼀致@FeignClient(name="lagou-service-resume")public interface ResumeFeignClient {//调⽤的请求路径@RequestMapping(value = "/resume/openstate/{userId}",method=RequestMethod.GET)    public Integer findResumeOpenState(@PathVariable(value = "userId")Long userId);}

注意:

@FeignClient注解的name属性⽤于指定要调⽤的服务提供者名称,和服务提供者yml⽂件中 spring.application.name保持⼀致接⼝中的接⼝⽅法,就好⽐是远程服务提供者Controller中的Hander⽅法(只不过如同本地调⽤了),那么在进⾏参数绑定的时,可以使⽤@PathVariable、@RequestParam、@RequestHeader等,这也是OpenFeign对SpringMVC注解的⽀持,但是需要注意value必须设置,否则会抛出异常使⽤接⼝中⽅法完成远程调⽤

@Autowiredprivate ResumeFeignClient resumeFeignClient;@Testpublic void testFeignClient(){    Integer resumeOpenState =    resumeFeignClient.findResumeOpenState(1545132l);    System.out.println("=======>>>resumeOpenState:" + resumeOpenState);}
三、Feign对负载均衡的⽀持

Feign 本身已经集成了Ribbon依赖和⾃动配置,因此我们不需要额外引⼊依赖,可以通过 ribbon.xx 来进 ⾏全局配置,也可以通过服务名.ribbon.xx 来对指定服务进⾏细节配置配置(参考之前,此处略) Feign默认的请求处理超时时⻓1s,有时候我们的业务确实执⾏的需要⼀定时间,那么这个时候,我们就需要调整请求处理超时时⻓,Feign⾃⼰有超时设置,如果配置Ribbon的超时,则会以Ribbon的为准

Ribbon设置

#针对的被调⽤⽅微服务名称,不加就是全局⽣效lagou-service-resume:    ribbon:        #请求连接超时时间        #ConnectTimeout: 2000        #请求处理超时时间        #ReadTimeout: 5000        #对所有操作都进⾏重试        OkToRetryOnAllOperations: true        ####根据如上配置,当访问到故障请求的时候,它会再尝试访问⼀次当前实例(次数由        MaxAutoRetries配置),        ####如果不⾏,就换⼀个实例进⾏访问,如果还不⾏,再换⼀次实例访问(更换次数由        MaxAutoRetriesNextServer配置),        ####如果依然不⾏,返回失败信息。        MaxAutoRetries: 0 #对当前选中实例重试次数,不包括第⼀次调⽤        MaxAutoRetriesNextServer: 0 #切换实例的重试次数        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #负载        策略调整
四、Feign对熔断器的⽀持在Feign客户端⼯程配置⽂件(application.yml)中开启Feign对熔断器的⽀持
# 开启Feign的熔断功能feign:  hystrix:   enabled: true

注意:

开启Hystrix之后,Feign中的⽅法都会被进⾏⼀个管理了,⼀旦出现问题就进⼊对应的回退逻辑处理针对超时这⼀点,当前有两个超时时间设置(Feign/hystrix),熔断的时候是根据这两个时间的最 ⼩值来进⾏的,即处理时⻓超过最短的那个超时时间了就熔断进⼊回退降级逻辑⾃定义FallBack处理类(需要实现FeignClient接⼝)在@FeignClient注解中关联2)中⾃定义的处理类

@FeignClient(value = "lagou-service-resume",fallback =ResumeFallback.class,path = "/resume") // 使⽤fallback的时候,类上的@RequestMapping的url前缀限定,改成配置在@FeignClient的path属性中//@RequestMapping("/resume")public interface ResumeServiceFeignClient {复制代码
五、Feign对请求压缩和响应压缩的⽀持

Feign ⽀持对请求和响应进⾏GZIP压缩,以减少通信过程中的性能损耗。通过下⾯的参数 即可开启请求与响应的压缩功能:

六、Feign的⽇志级别配置

Feign是http请求客户端,类似于咱们的浏览器,它在请求和接收响应的时候,可以打印出⽐较详细的⼀些⽇志信息(响应头,状态码等等),默认情况下Feign的⽇志没有开启。

开启Feign⽇志功能及级别

// Feign的⽇志级别(Feign请求过程信息)// NONE:默认的,不显示任何⽇志----性能最好// BASIC:仅记录请求⽅法、URL、响应状态码以及执⾏时间----⽣产问题追踪// HEADERS:在BASIC级别的基础上,记录请求和响应的header// FULL:记录请求和响应的header、body和元数据----适⽤于开发及测试环境定位问题@Configurationpublic class FeignConfig {    @Bean    Logger.Level feignLevel() {        return Logger.Level.FULL;    }}
配置log⽇志级别为debug
logging:  level:   # Feign⽇志只会对⽇志级别为debug的做出响应   com.lagou.edu.controller.service.ResumeServiceFeignClient: debug
七、Feign核⼼源码剖析

思考⼀个问题:只定义了接⼝,添加上@FeignClient,真的没有实现的话,能完成远程请求么?不能,考虑是做了代理了。

断点标注 @FeginClient 接口

从@EnableFeignClients 正向切⼊import FeignClientsRegistrar进入 org.springframework.cloud.openfeign.FeignClientsRegistrar#registerBeanDefinitions,重写BeanDefinitions,完成Bean 注入接下来,我们主要追踪下另外⼀⾏主要的代码registerFeignClients(metadata, registry);定义了扫描器,主要扫描@FeginClient注册客户端,给每⼀个客户端⽣成代理对象所以,下⼀步,关注FeignClientFactoryBean这个⼯⼚Bean的getObject⽅法,根据经验,这个⽅法会返回我们的代理对象getObject 里面完成了 核心方法,包括了负载均衡的封装,最后发起请求最终请求的发起使⽤的是HttpURLConnection

简单总结下:

为标注@FeginClient的接口生成代理,封装成Bean,利用FactoryBean#getObject,去包装了Ribbon,最终发起http请求。

标签: #aspnetmvc泛解析