Feign是Netflix公司开发的一个声明式的REST调用客户端; Ribbon负载均衡、Hystrix服务熔断是我们Spring Cloud中进行微服务开发非 常基础的组件,在使用的过程中我们也发现它们一般都是同时出现的,而且配置 也都非常相似,每次开发都有很多相同的代码,因此Spring Cloud基于Netflix Feign整合了Ribbon和Hystrix两个组件,让我们的开发工作变得更加简单, 就像Spring Boot是对 Spring+SpringMVC的简化一样,Spring Cloud Feign 对 Ribbon 负载均衡、Hystrix 服务熔断进行简化,在其基础上进行了进一步的 封装,不仅在配置上大大简化了开发工作,同时还提供了一种声明式的Web服 务客户端定义方式;
使用 Feign 实现消费者,我们通过下面步骤进行:
第一步:创建普通 Spring Boot 工程
首先我们来创建一个普通的 Spring Boot 工程,取名为: 05-springcloud-service-feign;
第二步:添加依赖
要 添 加 的 依 赖 主 要 是 spring-cloud-starter-netflix-eureka-client
和spring-cloud-starter-feign
,如下:
<!--Eureka客户端进行服务发现的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<!--SpringCloud feign的起步依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!--Spring Cloud熔断器起步依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
第三步:添加注解
在项目入口类上添加@EnableFeignClients
注解表示开启 Spring Cloud Feign的支持功能;
第四步:声明服务
定义一个 HelloService 接口,通过@FeignClient 注解来指定服务名称,进而绑定服务,然后再通过 SpringMVC 中提供的注解来绑定服务提供者提供的接口,
如下:
/**
* 使用Feign可客户端注解,绑定远程服务的名字
* 远程服务的名字 可以大写 也可以小写
*/
@FeignClient("01-springcloud-service-provider")
public interface HelloService {
// 声明一个方法,这个方法就是远程服务提供者提供的方法
@RequestMapping("service/hello")
public String hello();
}
这相当于绑定了一个名叫 01-springcloud-service-provider (这里
01-springcloud-service-provider 大小写 01-SPRINGCLOUD-SERVICE-PROVIDER
都可以 ) 的服务提供者提供的/service/hello 接口;
我们服务提供者提供的接口如下:
@RequestMapping("/service/hello")
public String hello(){
return "hello,Spring Cloud,Provider1";
}
第五步:使用 Controller 中调用服务
接着来创建一个 Controller 来调用上面的服务,如下:
@RestController
public class FeignController {
@Autowired
private HelloService helloService;
@RequestMapping("/web/hello")
public String hello(){
// 调用声明式接口方法,实现对远程服务的调用
return helloService.hello();
}
}
第六步:属性配置
在 application.properties 中指定服务注册中心、端口号等信息,如下:
server.port=8082
# 配置服务的名称
spring.application.name=05-springcloud-service-feign
# 配置 eureka 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka,http://localhost:8762/eureka
第七步:测试
依次启动注册中心、服务提供者和 feign 实现服务消费者,然后访问如下地址:http://localhost:8082/web/hello
负载均衡:
我们知道,Spring Cloud 提供了 Ribbon 来实现负载均衡,使用 Ribbo 直接注
入一个 RestTemplate 对象即可,RestTemplate 已经做好了负载均衡的配置;
在 Spring Cloud 下,使用 Feign 也是直接可以实现负载均衡的,定义一个注解
有@FeignClient 注解的接口,然后使用@RequestMapping 注解到方法上映
射远程的 REST 服务,此方法也是做好负责均衡配置的。
上面我们写的就是负载均衡的,大家可以自己测试下。
服务熔断:
1、在 application.properties 文件开启 hystrix 功能
feign.hystrix.enabled=true
2、指定熔断回调逻辑
@FeignClient(name="01-springcloud-service-provider", fallback = MyFallback.class)
@Component
public class MyFallback implements HelloService {
@Override
public String hello() {
return "hello远程服务不可用";
}
}
2-1 新增错误回调类
2-2 新建MyFallback类,继承HelloService,重写HelloService的方法,重写的内容即为熔断后回调的
在服务提供着的方法中制造异常
重启 重启 重启 所有的服务提供者,Eureka服务,feign,在服务提供者2的方法中制造异常
测试结果:
服务提供者2发生异常,进入了fallback方法
3、服务熔断获取异常信息:
为@FeignClient 修饰的接口加上 fallback 方法可以实现远程服务发生异常后进
行服务的熔断,但是不能获取到远程服务的异常信息,如果要获取远程服务的异
常信息,怎么办?此时可以使用 fallbackFactory:
@FeignClient(name="01-springcloud-service-provider", fallbackFactory=MyFallbackFactory.class)
@Component
public class MyFallbackFactory implements FallbackFactory<HelloService> {
@Override
public HelloService create(Throwable throwable) {
return new HelloService() {
@Override
public String hello() {
return throwable.getMessage();
}
};
}
}
上图:电脑端点击可放大至高清