一、简介
在之前,我们学习了Ribbon
和Hystrix
。微服务的负载均衡器以及服务熔断措施,大大稳定了微服务应用。
在使用Spring Cloud Ribbon
的时候,是配合RestTemplate
与@LoadBalanced
使用的,RestTemplate
封装了http
请求,提供了一套模板化调用方法。这时我们会发现,在实际开发中,对于更多的应用以及接口的调用,要写大量的RestTemplate
模板化内容。
这时SpringCloud
为了方便开发,实现了Feign
这一组件,它简化了Ribbon
,我们只需要创建接口并使用注解配置,即可完成对服务提供方的接口绑定。它具备可插拔的注解支持,包括Feign
注解、JAX-RS
注解。它也支持可插拔的编码器和解码器。Spring Cloud Feign
还扩展了对Spring MVC
注解的支持,同时还整合了Hystrix
来提供服务熔断。
二、Spring Cloud Feign 入门
接着,我们从头开始使用Feign
来充当服务消费方的角色。
1.初始化项目
首先我们创建一个Maven Project,springcloud-study-Feign
然后创建三个Module
,分别是
eureka-server
:注册中心server-provider
:服务提供方server-consumer
:服务消费方
2.添加依赖
这里为了方便,我们将所有依赖都加在父类的pom
文件里,因为eureka
,ribbon
依赖之前都讲过,这里只展示出Feign
的依赖。
1 | <!-- 依赖 Feign --> |
3.配置Eureka 注册中心
创建一个启动类,添加Eureka Server
注解
1 |
|
配置application.properties
1 | eureka-server = |
4.配置服务提供方
创建一个启动类,添加Eureka Client
注解
1 |
|
配置application.properties
1 | server-provider = |
编写Controller
类
1 |
|
5.配置服务消费方(Feign)
这时我们的重头戏就来了,首先是老套路,编写主程序类和配置。
1 |
|
1 | server-consumer = |
配置完这两项之后,我们需要写一个Sevice
接口,用来消费服务,注意,这里的接口,就相当于之前使用Ribbon时编写的RestTemplate
发送请求。
1 | "${provider.service.name}") (name = |
使用Feign实现服务消费接口
- 创建一个接口
- 添加
@FeignClient
注解,具有一些属性name
:服务提供方的应用名称,这里我动态的配置fallback
:使用服务熔断后,可以配置这个,来进行服务熔断后的请求类,我们之后再细说
- 使用
SpringMVC
注解,配置提供方的请求路径,并且入参和返回值要相同
编写Controller
,注入Service
接口,并调用服务。
1 |
|
6.测试
这里先开启eureka-server
然后开启两个服务提供方,9090
和9091
最后开启服务消费方
正确启动后访问我们的消费方接口
)
可以看到,正确负载均衡访问服务提供方,证明我们的Feign
使用成功。
三、Spring Cloud Feign 改造
在上面的例子中,我们写了至少三次的api方法,即,服务提供方一次,服务调用方一次,Feign接口一次,如果接口越来越多,大量的复制粘贴是不可取的,这时,我们就需要改造一下我们的工程。
将接口抽象出来,以供提供方与消费方引用实现。
1.新建api工程
新建一个api工程,将所有的service-api
类存放在这里,以便公共调用实现
创建BookService
接口
1 | public interface BookService { |
2.重构服务提供方
首先需要在pom
中添加api
工程的引用
1 | <dependencies> |
其次就是修改Controller
了
1 | "/book") ( |
在之前的基础上,添加一个BookService
的实现即可,这样我们只需重新接口中的方法即可,不用大量的复制粘贴。
==注意,这里就不用再写一遍@GetMapping
了==,因为接口的映射会自动带过来
3.重构服务消费方
也需要先添加api
工程引用
然后重构BookFeignService
接口
1 | "${provider.service.name}") (name = |
这里只需集成BookService
接口即可,并删除其中之前的方法
然后重构Controller
1 |
|
对于Controller来说也非常简单,实现BookService
接口即可,会把@GetMapping
注解带过来,==就不用再写一遍@GetMapping了==,因为接口的映射会自动带过来
此时,我们的Feign
工程就改造完毕了,利用继承的特性,更好的实现接口定义与依赖共享
四、Spring Cloud Feign 与 Hystrix
之前说过Feign
是将Ribbon
与Hystrix
整合起来,让用户更方便的实现负载均衡和服务熔断,通过刚刚的代码,可以看到Feign
与Ribbon
客户端有很大区别,HystrixCommand
被封装了起来,那么便不能使用@HystrixCommand
注解方式来使用熔断,它提供了一种更好的方式来进行熔断。
我们通过改造我们上面的代码,来进行实现
开启熔断配置
首先要在配置文件中开启配置,因为在SpringCloud Dalston
版本后,Feign
的Hystrix
默认是关闭的
server-consumer/application.properties
1 | # 开启Fegin的Hystrix熔断 |
新建FallBack类实现
1 |
|
这里实现我们刚刚重构过会的BookFeignService
接口,这样就可以直接重写方法了,而不是复制粘贴一遍。
==注意要开启@Component
注解,加载到容器中==
配置FeignClient
最后一步,需要在刚刚的@FeignClient
中添加fallback
属性
1 | "${provider.service.name}",fallback = BookServiceFallBack.class) (name = |
这里使用了fallback
属性。
还有一种方式是使用fallbackFactory
,即工厂,那么实现了就需要继承自FallBackFactory
类,并在泛型上使用BookFeginService
接口。
测试
这里我们想测试熔断,只需将服务提供方关闭即可
可以看到,正确执行我们设置熔断后fallback
方法