技术需求点:
在SpringCloud部署的微服务系统中,消费者通过Feign组件调用提供者的微服务。
一.Feign简介
在前文SpringCloud+SpringBoot搭建服务注册与调用平台中,我们使用了Ribbon客户端实现了微服务之间的调用,Ribbon本身集成了负载均衡的功能,但是Ribbon有一个使用不便的地方:每次使用需要手动拼接请求的url,还要对返回的结果进行格式化处理。为了解决这个不便,SpringCloud提供了一个声明式的调用组件:Feign,它可以帮助我们便捷的调用注册在注册中心的微服务。
Feign是一种声明式调用组件,提供了一种基于接口的编程方式,我们只要声明接口并配置注解,SpringCloud会根据配置以Rest风格的方式从其它微服务系统中调用方法并获取数据。
主要有以下几个优点:
(1)可插拔的注解支持,包括Feign注解和JAX-RS注解;
(2)支持可插拔的HTTP编码器和解码器;
(3)支持Hystrix和它的Fallback;
(4)支持Ribbon的负载均衡,如果某个微服务id下有两个端口提供2个同样的服务,会采用轮询机制调用;
(5)支持HTTP请求和相应的压缩。
https://segmentfault.com/a/1190000019685780?utm_source=tag-newest
二.工程搭建
在之前的文章中,我们已经搭建好了基于Springcloud + SpringBoot的工程结构:springcloud-eureka-server、springcloud-eureka-provider、springcloud-eureka-consumer等角色,这次只需要在springcloud-eureka-provider中将Ribbon组件调用的方式改成Feign即可。
1.pom文件中添加Feign依赖
org.springframework.cloud
spring-cloud-starter-openfeign
我之前使用的版本:Spring Boot版本:1.5.3.RELEASE,Spring Cloud版本:Dalston.SR5。
添加feign的pom依赖之后,发现找不到用于负载均衡的LoadBalancedRetryFactory的包,上网查资料发现是SprongBoot和SpringCloud的版本问题,不是所有SpringBoot和SpringCloud的包都是兼容的,两者的版本必须匹配使用,官网上两者匹配的版本如下:
image.png
因此,我们项目中SpringBoot版本改为用:2.0.3.RELEASE,SpringCloud的版本改为用:Finchley.RELEASE,改动代码如下:
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.目录结构
image.png
3.创建UserFeignService接口
Feign只需要写一个接口,在接口配置好需要调用的微服务id,并声明接口即可。如代码所示,使用注解@FeignClient,"eureka-provider"是提供者的serviceid,在整个微服务系统中是唯一的,表明该接口将调用eureka-provider的服务。方法名称和返回类型直接copy被调用服务的方法即可。
//开启feign客户端,eureka-provider-user微服务的serviceid(唯一)
@FeignClient("eureka-provider")
public interface UserFeignService {
@RequestMapping("/user")
public List getUsers();
}
@RequestMapping要写完整路径。我们这里路径比较简单,直接是"/user",如果原服务的路径是下面这种,就需要写成"/provider/user"
image.png
4.修改启动类
启动类上添加@EnableFeignClients开启Feign客户端。
@EnableFeignClients//开启Feign客户端
@EnableEurekaClient//开启Eureka客户端
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class,args);
}
}
三.测试结果
依次启动springcloud-eureka-server(集群)、springcloud-eureka-provider、springcloud-eureka-consumer服务,启动成功后,查看控制台http://192.168.33.100:8761
image.png
输入http://127.0.0.1:9091/consumer,看到下列返回说明调用成功!
image.png
四.扩展
Feign还有另外一种继承与实现的使用方式,大概做法是抽离出一个公共API项目,写一个接口让消费者继承,实现方法在提供者中实现,调用该公共接口的方法即可。
这种做法的好处是创建了独立的api项目,可以很方便的实现接口定义和依赖共享,不用再复制粘贴接口,但弊端是增加了服务提供者和消费者之间的耦合,如果服务提供者修改了一个接口定义,消费者也得跟着变,进而带来一些坑。
有兴趣的同学可以参考:https://www.jianshu.com/p/ff79509b0962
作者:superxcp
链接:https://www.jianshu.com/p/df5aa32f42a0
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。