跳至主要內容

OpenFeign 远程调用基本原理和使用

悟空约 890 字大约 3 分钟...

OpenFeign 远程调用基本原理和使用

之前已经把 Eureka、Ribbon 集成到我的小商城系统了,今天把 OpenFeign 远程调用组件集成了。

比较有趣的一点是 Feign 和 OpenFeign 这两个小家伙,这里做个总结:

Feign 最早是由 Netflix 公司进行维护的,后来 Netflix 不再对其进行维护,最终 Feign 由社区进行维护,更名为 OpenFeign。

Feign是 Springcloud组件中的一个轻量级 Restful的 HTTP 服务客户端,Feign 内置了 Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign 的使用方式是:使用 Feign 的注解定义接口,调用这个接口,就可以调用服务注册中心的服务.

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-feign</artifactId>
    </dependency>

OpenFeign 是 Springcloud 在 Feign的基础上支持了 SpringMVC 的注解,如 @RequestMapping 等等。OpenFeign 的 @FeignClient 可以解析 SpringMVC 的 @RequestMapping 注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

源码地址:https://github.com/openfeign/feignopen in new window

代码示例

OpenFeign 的使用也很简单,这里还是用我的开源 SpringCloud 项目 PassJava 作为示例。

开源地址: https://github.com/Jackson0714/PassJava-Platformopen in new window

喜欢的小伙伴来点个 Star 吧,冲 2K Star。

Member 服务远程调用 Study 服务的方法 memberStudyTime(),如下图所示。

第一步:Member 服务需要定义一个 OpenFeign 接口:

@FeignClient("passjava-study")
public interface StudyTimeFeignService {
    @RequestMapping("study/studytime/member/list/test/{id}")
    public R getMemberStudyTimeListTest(@PathVariable("id") Long id);
}

我们可以看到这个 interface 上添加了注解@FeignClient,而且括号里面指定了服务名:passjava-study。显示声明这个接口用来远程调用 passjava-study服务。

第二步:Member 启动类上添加 @EnableFeignClients注解开启远程调用服务,且需要开启服务发现。如下所示:

@EnableFeignClients(basePackages = "com.jackson0714.passjava.member.feign")
@EnableDiscoveryClient

第三步:Study 服务定义一个方法,其方法路径和 Member 服务中的接口 URL 地址一致即可。

URL 地址:"study/studytime/member/list/test/{id}"

@RestController
@RequestMapping("study/studytime")
public class StudyTimeController {
    @RequestMapping("/member/list/test/{id}")
    public R memberStudyTimeTest(@PathVariable("id") Long id) {
       ... 
    }
}

第四步:Member 服务的 POM 文件中引入 OpenFeign 组件。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

第五步:引入 studyTimeFeignService,Member 服务远程调用 Study 服务即可。

Autowired
private StudyTimeFeignService studyTimeFeignService;

studyTimeFeignService.getMemberStudyTimeListTest(id);

通过上面的示例,我们知道,加了 @FeignClient 注解的接口后,我们就可以调用它定义的接口,然后就可以调用到远程服务了。

这里你是否有疑问:为什么接口都没有实现,就可以调用了?

OpenFeign 使用起来倒是简单,但是里面的原理可没有那么简单,OpenFeign 帮我们做了很多事情,接下来我们来看下 OpenFeign 的架构原理。

QA

1、遇到报错:Unregistering application *** with eureka with status DOWN

在出错项目的pom依赖中添加如下依赖:

https://blog.csdn.net/weixin_45763431/article/details/114013665open in new window

2、404 not found

FeignClient 对应的 API 方法,上面的 URL 路径需要和 controller 定义的 API 路径一致。

3、405

Service A

2022-07-04 11:11:50.979 ERROR 33552 --- [nio-9642-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.FeignException$MethodNotAllowed: [405] during [GET] to [http://lic-example-service/member/v1/list] [FeignMemberService#getUserinfoList(Member)]: [{"timestamp":"2022-07-04T03:11:50.315+00:00","status":405,"error":"Method Not Allowed","message":"","path":"/member/v1/list"}]] with root cause

Service B

2022-07-04 11:11:50 [http-nio-9640-exec-3] WARN  org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver -Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]

解决方案:

Get 请求传对象,需要加 @SpringQueryMap

@GetMapping("/member/v1/list")
R<List<Member>> getUserinfoList(@SpringQueryMap Member member);
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.3.0