fegin
我们讲一下fegin这个技术栈的全域理解
首先,还是要讲这个背景
假如两个springboot,分别是a和b
都已经注册到nacos上
我们不考虑使用dubbo这个rpc去进行处理
两个springboot如何去进行交互,就是接口互相调用
1.使用resttemplate,这个工具类,调用http请求。
但是这个太复杂了。
于是有了这个fegin这个技术栈。封装了让springboot可以调用http请求的需要处理的技术点
这里,我讲一个点,绕不开的。
就是,底层代码,已经写好了
我们作为开发者,要去理解的事,
这个技术栈提供了哪些机制,去处理这些问题。
这些机制涉及哪些领域。去哪里配置
这个是我们学习这个技术栈,学习的内容
1.fegin的对于springboot引入这个技术栈,要做的配置是什么
2.fegin底层是实现原理是什么,需要配置哪些领域
3.具体在代码中如何使用fegin
Feign的核心价值就是让开发者像调用本地方法一样调用远程服务,从而屏蔽底层的HTTP通信复杂性。下面我来系统地梳理你提出的三个问题,形成一个对Feign技术栈的全域理解。
1. Feign的引入与基础配置
要在项目中使用Feign,有三个必不可少的步骤:
加依赖:在Spring Boot项目的
pom.xml中引入Spring Cloud OpenFeign的起步依赖。<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>启功能:在Spring Boot的启动类上添加
@EnableFeignClients注解,激活Feign的自动配置和扫描功能。@SpringBootApplication@EnableFeignClients// 开启Feign客户端功能publicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);}}写客户端:创建一个Java接口,并用
@FeignClient注解标记,在注解中指定你要调用的目标服务名(例如,在Nacos中注册的服务名)。// “userservice” 是目标服务在Nacos中的服务名@FeignClient("userservice")publicinterfaceUserClient{// 这个方法的声明,精准地“翻译”了要调用的远端API@GetMapping("/user/{id}")// 请求方式 + 路径UserfindById(@PathVariable("id")Longid);// 请求参数 + 返回值}
完成以上三步后,你就可以在其他组件(如@Service或@Controller)中,像使用普通Spring Bean一样注入并使用UserClient了。
2. Feign的底层实现原理与核心机制
Feign之所以能“凭空”调用接口,魔法就在于动态代理和声明式注解解析。它的工作流程可以分为以下几个核心阶段:
启动阶段:动态代理工厂的创建
- 当应用启动时,
@EnableFeignClients注解会触发一个包扫描器(FeignClientsRegistrar)。 - 扫描器会找出所有被
@FeignClient标记的接口,并为每一个接口动态地生成一个代理对象,然后把这个代理对象注册到Spring容器中。这就解释了为什么接口没有实现类也能被@Autowired注入。
- 当应用启动时,
调用阶段:代理对象的工作流程
- 当你在代码中调用
userClient.findById(1L)时,实际调用的是那个由Feign生成的代理对象。 - 注解解析(Contract):代理对象会解析该方法上的Spring MVC注解(如
@GetMapping、@PathVariable),将这些注解“翻译”成一个标准的HTTP请求对象,此时请求的路径是/user/1,目标服务名是userservice。 - 负载均衡:Feign无缝集成了Ribbon或Spring Cloud LoadBalancer。它将服务名
userservice交给负载均衡器,负载均衡器会从服务发现中心(如Nacos)获取userservice的一个健康实例的IP和端口(例如10.0.0.5:8080)。 - 编码与发起请求(Encoder & Client):Feign使用
Encoder组件将方法参数(如id=1L)编码成请求参数或请求体。然后,通过内部的Client组件(默认是URLConnection,可优化为HttpClient或OKHttp)将构建好的HTTP请求发送到http://10.0.0.5:8080/user/1。 - 解码与返回(Decoder):收到远端服务的HTTP响应后,Feign使用
Decoder组件将返回的JSON字符串(或其他格式)解码成方法定义的User对象,最终返回给调用方。
- 当你在代码中调用
3. Feign的可配置领域与调优
要深入使用Feign,需要掌握以下几个关键的配置领域,你可以在application.yml文件中或通过Java配置类进行定制:
| 配置领域 | 作用与机制 | 配置方式示例 (application.yml) |
|---|---|---|
| 日志级别 | 用于调试,可查看请求和响应的详细信息。NONE,BASIC,HEADERS,FULL四个级别,推荐开发环境用FULL。 | logging.level.com.example.feign.UserClient: DEBUG或针对服务的Feign配置: feign.client.config.userservice.loggerLevel: full |
| 连接池 | 默认使用URLConnection无连接池,在高并发下性能较差。强烈建议替换为支持连接池的Apache HttpClient或OKHttp以提升性能。 | 先引入feign-httpclient依赖,再配置:feign.httpclient.enabled: truefeign.httpclient.max-connections: 200 |
| 超时控制 | 防止调用远端时线程被长时间阻塞。分为connectTimeout(建立连接的超时)和readTimeout(收到数据前的超时)。 | feign.client.config.default.connectTimeout: 5000feign.client.config.default.readTimeout: 5000 |
| 请求拦截器 | 一个强大的扩展点。可以为所有Feign请求添加通用的请求头,如认证Token、Trace ID等。 | 需要实现RequestInterceptor接口,并注册为一个@Bean。 |
| 熔断降级 | (可选) 集成Sentinel或Resilience4j后,可以为Feign接口指定一个Fallback类,当服务调用失败或超时时,执行降级逻辑,返回默认结果,提高系统韧性。 | 需要开启熔断支持,并创建@Component类实现UserClient接口作为Fallback。 |
最后,关于你提到的Nacos注册中心,Feign可以无缝配合。你只需要在application.yml中正确配置Nacos服务发现地址即可。在你的@FeignClient(name = "userservice")中,Feign会拿着userservice这个名字去Nacos中查询该服务的所有可用实例列表,再交给其内置的负载均衡器进行选择。这个过程中,你无需编写任何代码去主动集成Nacos。
