Feign实现微服务进行接口之间的调用

2022-08-01 12:17:14

Feign调用微服务与Ribbon+RestTemplate通过服务名来调用微服务区别

  1. Feign通过接口的方法调用Rest服务。通过Feign直接找到服务接口,由于在进行服务调用的时候融合了Ribbon技术,所以也支持负载均衡作用。
  2. Ribbon+RestTemplate:该请求发送给Eureka服务器(http://MICROSERVICECLOUD-DEPT/dept/list) ,然后获得服务信息进而调用服务
    这两种方式都要启动Eureka服务,并将服务提供者注入到Eureka中。

什么是Feign

官网地址
在这里插入图片描述
Feign是一个声明式的Web服务客户端, 使得编写Web服务客户端变得非常容易,
只需要创建一个接口,然后在上面添加注解即可。

Feign能干什么?

在这里插入图片描述

Feign是面向接口+注解的形式去调用Feign

github官网地址

在这里插入图片描述

Feign与Ribbon的关系(Feign集成了Ribbon)

Feign集成了Ribbon。
利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。

Feign的构建

构建步骤
在这里插入图片描述

  1. 服务消费者:microservicecloud-consumer-dept-feign ,能够通过Feign去调用服务提供者。
  2. microservicecloud-consumer-dept-feign的pom.xml文件,feign整合了Ribbon,所以需要导入Ribbon,Ribbon需要Eureka,所以到Eureka的依赖。
    在这里插入图片描述
  3. Feign的接口可能每个服务都需要,写在公共的模块中。建立Feign的Service接口,并在启动类上添加@FeignClient(value=“服务提供者的名称”),在公共模块要添加Feign依赖。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  4. 在服务消费者的Controller类找那个注入Feign的service接口,并使用该接口。
    在这里插入图片描述
  5. 在服务消费者开启Feign的使用 ,在启动类上添加@EnableFeignClients 注解,启用Feign。
    在这里插入图片描述
  6. ok 完成,启动。项目,先启动Eureka,再启动服务。

Spring Boot 和 Spring Cloud Feign调用服务及传递参数踩坑记录

总结:Feign当不使用@RequestParam、@RequestBody注解的时候,会默认发送POST请求,将参数序列化成json对象,放在请求体中。如果强制定义GET请求,将会转化为POST请求,然后请求体中无数据。
Feign使用@RequestParam注解的时候,默认使用get请求,并拼装到url中

参考链接

https://blog.csdn.net/liu_ares/article/details/103599418?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1

在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate。但是,用起来最方便、最优雅的还是要属Feign了。
Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。比如:

@Autowiredprivate AdvertGropRemoteService service;// 远程服务public AdvertGroupVOfoo(Integer groupId){return service.findByGroupId(groupId);// 通过HTTP调用远程服务}

开发者通过service.findByGroupId()就能完成发送HTTP请求和解码HTTP返回结果并封装成对象的过程。

为了让Feign知道在调用方法时应该向哪个地址发请求以及请求需要带哪些参数,我们需要定义一个接口:

@FeignClient(name="ea")//  [A]publicinterfaceAdvertGroupRemoteService{@RequestMapping(value="/group/{groupId}", method= RequestMethod.GET)// [B]
    AdvertGroupVOfindByGroupId(@PathVariable("groupId") Integer adGroupId)// [C]@RequestMapping(value="/group/{groupId}", method= RequestMethod.PUT)voidupdate(@PathVariable("groupId") Integer groupId,@RequestParam("groupName") String groupName)

A:@FeignClient用于通知Feign组件对该接口进行代理(不需要编写接口实现),使用者可直接通过@Autowired注入。

B:@RequestMapping表示在调用该方法时需要向/group/{groupId}发送GET请求。

C:@PathVariable与SpringMVC中对应注解含义相同。

Spring Cloud应用在启动时,Feign会扫描标有@FeignClient注解的接口,生成代理,并注册到Spring容器中。生成代理时Feign会为每个接口方法创建一个RequetTemplate对象,该对象封装了HTTP请求需要的全部信息,请求参数名、请求方法等信息都是在这个过程中确定的,Feign的模板化就体现在这里。

在本例中,我们将Feign与Eureka和Ribbon组合使用,@FeignClient(name = “ea”)意为通知Feign在调用该接口方法时要向Eureka中查询名为ea的服务,从而得到服务URL。

Feign将方法签名中方法参数对象序列化为请求参数放到HTTP请求中的过程,是由编码器(Encoder)完成的。同理,将HTTP响应数据反序列化为java对象是由解码器(Decoder)完成的。

默认情况下,Feign会将标有@RequestParam注解的参数转换成字符串添加到URL中,将没有注解的参数通过Jackson转换成json放到请求体中。注意,如果在@RequetMapping中的method将请求方式指定为GET,那么所有未标注解的参数将会被忽略,例如:

@RequestMapping(value="/group/{groupId}", method= RequestMethod.GET)voidupdate(@PathVariable("groupId") Integer groupId,@RequestParam("groupName") String groupName, DataObject obj);

此时因为声明的是GET请求没有请求体,所以obj参数就会被忽略。

在Spring Cloud环境下,Feign的Encoder只会用来编码没有添加注解的参数。如果你自定义了Encoder, 那么只有在编码obj参数时才会调用你的Encoder。对于Decoder, 默认会委托给SpringMVC中的MappingJackson2HttpMessageConverter类进行解码。只有当状态码不在200 ~ 300之间时ErrorDecoder才会被调用。ErrorDecoder的作用是可以根据HTTP响应信息返回一个异常,该异常可以在调用Feign接口的地方被捕获到。我们目前就通过ErrorDecoder来使Feign接口抛出业务异常以供调用者处理。

  • 作者:侯侯侯先生
  • 原文链接:https://blog.csdn.net/weixin_44142032/article/details/106670071
    更新时间:2022-08-01 12:17:14