目录
在wemedia微服务中添加@EnableFeignClients注解,并指定需要扫描的包
在wemedia微服务中注入article微服务中Feign接口的实现类,调用对应实现方法
Feign介绍
Feign是一个声明式的Web Service客户端。它让微服务之间的调用变得更简单。Feign具有可插拔式的注解支持,包括Feign 注解和JAX-RS注解。Feign还支持可插拔的编码器和解码器。Spring Cloud增加了对Spring MVC注解的支持,并且也支持Spring WebFlux。
在开发中,我们常用httpClient去远程调用其他系统的接口,需要我们指定调用的url(参考苍穹外卖中的调用支付等第三方接口),Feign 是一个声明式的 Web Service 客户端,它实现了一套远程调用的方法,调用的方式也更为优雅。
前提:1.被调用的模块注册到eureka中,能正常运行
2.feign接口文件夹要和启动类在同一个目录下, 否则需指定包名,@EnableFeignClients(basePackages="com.**.***")
Feign的执行流程
Feign在调用其他服务时,会根据注解中的url进行请求转发。它的工作原理是:
- 根据
@FeignClient
的value值找到服务,如果配置了服务注册中心,还会根据服务名获取服务实例列表。- 构造请求参数,根据方法上的注解(如@PathVariable、@RequestParam、@RequestBody等)确定请求参数。
- 根据注解(@GetMapping、@PostMapping、@DeleteMapping等)确定请求方法和路径。
- 发起请求调用其他服务,获取结果。
- 封装结果,返回给调用方。
项目中使用Feign介绍
黑马头条作为一个典型的微服务项目,涉及到多个微服务,如上图中③媒体微服务,可以对用户发布的文章进行审核 ;②文章微服务,**在用户发布的文章经过媒体微服务审核后,利用文章微服务将其存储到文章相关表格中。**②和③对应的微服务之间并没有建立直接的联系,此时使用feign远程调用,在③中方便调用②中提供的服务。结构如下:
大致思路如下:
- 在feign-api(①)微服务中定义feign的接口,并通过@FeignClient(...)注解指定要调用的服务名称。
- 在article(②)微服务中创建feign接口的实现类,并实现具体业务逻辑,向文章相关表格中插入对应数据。
- 在wemedia(③)微服务中注入②中创建的接口的实现类,直接调用②中实现的方法。(面向接口编程)。
实现步骤
添加Feign依赖
bash
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
注册feign远程调用接口,并指定需要调用的微服务
java
@FeignClient(value = "leadnews-article")
public interface IArticleClient {
@PostMapping("/api/v1/article/save")
public ResponseResult saveArticle(@RequestBody ArticleDto dto);
}
通过@FeignClient(...)注解指定要调用的微服务【leadnews-article(②)】,通过@PostMapping(...)注解指定其访问路径。
在leadnews-artilce微服务中创建接口实现类
java
@RestController
@Slf4j
public class ArticleClient implements IArticleClient {
@Autowired
private ApArticleService apArticleService;
/**
* 修改或保存文章信息
* @param dto
* @return
*/
@PostMapping("/api/v1/article/save")
@Override
public ResponseResult saveArticle(@RequestBody ArticleDto dto) {
log.info("修改或保存文章信息:{}", dto);
return apArticleService.saveArticle(dto);
}
}
在wemedia微服务中添加@EnableFeignClients注解,并指定需要扫描的包
上图中指定扫描的包为basePackages = "com.heima.apis",由于Feign接口所在的包的微服务并不是调用者所在的微服务并不会扫描对应的包,需要指定。
在wemedia微服务中注入article微服务中Feign接口的实现类,调用对应实现方法
java
@Autowired
private IArticleClient iArticleClient;
@Autowired
/**
* 审核成功,保存app端的相关文章数据
* @param wmNews
*/
private ResponseResult saveAppArticle(WmNews wmNews) {
// ......
ResponseResult responseResult = iArticleClient.saveArticle(dto);
return responseResult;
}
远程调用服务降级
服务降级:当服务调用失败或超时,我们需要有降级策略,避免影响整体系统。我们可以为Feign接口增加fallback
指定降级实现类。
服务降级是服务自我保护的一种方式,或者保护下游服务的一种方式,用于确保服务不会受请求突增影响变得不可用,确保服务不会崩溃
服务降级虽然会导致请求失败,但是不会导致阻塞。
实现步骤
编写服务降级策略
java
/**
* feign失败配置
*/
@Component
public class IArticleClientFallback implements IArticleClient {
@Override
public ResponseResult saveArticle(ArticleDto dto) {
return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"保存数据失败");
}
}
接口实现类所在的微服务中扫描服务降级所在的包,并通过@FeignClient(...)注解中的fallback属性指定服务降级的类。
java
@Configuration
@ComponentScan("com.heima.apis.article.fallback")
public class InitConfig {
}
@FeignClient(value = "leadnews-article",fallback = IArticleClientFallback.class)
public interface IArticleClient {
@PostMapping("/api/v1/article/save")
public ResponseResult saveArticle(@RequestBody ArticleDto dto);
}
在调用者所在的微服务wemedia中添加具体超时设置
java
feign:
# 开启feign对hystrix熔断降级的支持
hystrix:
enabled: true
# 修改调用超时时间
client:
config:
default:
connectTimeout: 2000
readTimeout: 2000
其中connectTimeout指定连接超时,默认10s;readTimeout指定读取超时,默认60s。