Feign
- 什么是Feign
Feign 与Ribbon 一样,Feign也是有Netflix 提供的,Feign是一个声明式、模块化的Web Service 客户端,它简化了开发者编写Web服务客户端的操作,开发者可以通过简单的接口和注解来调用HTTP API,Spring Cloud Feign,它整合了Ribbon 和Hystrix ,具有可插拔、基于注解、负载均衡、服务熔断等一系列便捷功能。
相比较于Ribbon +RestTemplate 的方式,Feign 大大简化了代码的开发,Feign 支持多种注解,包括Feign 注解、JAX-RS注解、Spring MVC注解等,Spring Cloud 对Feign 进行了优化,整合了Ribbon 和Eureka ,从而让Feign 的使用更加方便。
-
Ribbon 和Feign 的区别
1、 Fiegn 是一个声明式的Web Service 客户端。
2、支持Feign 注解、Spring MVC注解、JAX-RS注解。
3、Feign 基于Ribbon 实现,使用起来更加简单。
4、Feign 集成了Hystrix ,具备服务熔断的功能。
开启Feign 的功能
1、创建新的Module ,命名为 feign ,pom.xml 添加以下依赖
<dependencies>
<!-- 都是作为服务注册到Eureka Server ,所以需要添加这个依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<!-- Feign 的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</dependencies>
2、 新建application.yml文件
内容如下:
server:
port: 8050
spring:
application:
name: feign
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
3、创建启动类,并添加上Feign相关的注解
启动类名称取名为FeignApplication
代码如下:
package com.southwind;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class FeignApplication {
public static void main(String[] args){
SpringApplication.run(FeignApplication.class,args);
}
}
4、因为还需要继续操作第一篇文章建的学生实体类,所以需要把原来的实体类代码复制过来
Student 类:
package com.southwind.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor //无参构造
@AllArgsConstructor //有参构造
public class Student {
private long id;
private String name;
private int age;
}
目录结构如下:
4、 新建一个名叫 FeignProviderClient 的接口 放在com.southwind.feign 包里
FeignProviderClient 代码如下:
```java
package com.southwind.feign;
import com.southwind.entity.Student;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Collection;
//这里就体现了Feign 的声明式调用,都是接口,
//value = provider是因为提供者在注册中心的名字叫做 provider
@FeignClient(value = "provider")
public interface FeignProviderClient {
/* 需要调用提供者的controller 里面的方法,直接就行(有
* 点相当于它自己就会把provider 替换成IP地址,然后把Mapping 里面的值给拼接
* 到后面,实现模块间的调用。)
*/
@GetMapping("/student/findAll")
public Collection<Student> findAll();
@GetMapping("/student/index")
public String index();
}
5、创建controller ,命名为FeignHandler.java ,存放在com.southwind.controller 文件夹里
package com.southwind.controller;
import com.southwind.entity.Student;
import com.southwind.feign.FeignProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collection;
@RestController
@RequestMapping("/feign")
public class FeignHandler {
@Autowired
private FeignProviderClient feignProviderClient;
@GetMapping("/findAll")
public Collection<Student> findAll(){
return feignProviderClient.findAll();
}
@GetMapping("/index")
public String index(){
return feignProviderClient.index();
}
}
6、启动注册中心eruekaserver,然后与上一篇文章一样,一个工程启动两个不同端口的提供者服务,启动eurekaclient,然后启动feign 工程
7、在浏览器输入:localhost:8050/feign/index
Feign 声明式调用 也可以实现了负载均衡,并且比用zuul 网关的方法,简化了代码,更方便。
使用Feign 实现服务的熔断
什么是熔断。
当微服务处理秒杀场景,或者类似场景,导致访问服务器并发量特别大的时候,有可能一个服务崩了,导致调用它的服务因为长时间等不到该服务的响应继而也发生崩溃,以此类推,导致“雪崩效应”。这时候熔断器发挥了作用,他像电路的熔断器一样,一旦电流超过了最大电流,熔断器就断电,防止漏电和触电事件的发生。当某一个服务一直调用不无响应时,熔断器启动,暂时停止访问该服务,并且返回一个熔断处理的结果,告知用户稍后再试。等待宕机的服务重新恢复正常。待服务可以正常访问后,熔断器自动关闭。
1、在原来feign 工程的yml文件,添加feign熔断开启的代码。
server:
port: 8050
spring:
application:
name: feign
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
feign:
hystrix:
enabled: true
feign.hystrix.enabled:true 是否开启熔断器
2、创建FeignProviderClient 的实现类FeignError, 定义容错处理逻辑,通过@Component 注解将FeignError实例注入IoC容器中。
FeignError 代码:
package com.southwind.feign.impl;
import com.southwind.entity.Student;
import com.southwind.feign.FeignProviderClient;
import org.springframework.stereotype.Component;
import java.util.Collection;
@Component
public class FeignError implements FeignProviderClient {
@Override
public Collection<Student> findAll() {
return null;
}
//当熔断开启时,停止对该服务的访问,然后调用此方法告知用户系统繁忙
@Override
public String index() {
return "服务器维护中.....";
}
}
3、在FeignProviderClient 定义处通过 @FeignClient 的fallback 属性设映射,降级处理。
在FeignProviderClient 中,增加降级处理(红色框框部分)
这时候,一旦Feign 访问服务提供者,服务提供者不是正常状态导致feign 访问不成功的话,他自己就会找到feignError 里面的fallback 方法进行处理。这样,就不会出现网页状态码,如500,404等,而是会出现你写的fallback ,即熔断处理的方法里面。
4、测试
先把服务提供者停掉,这时候使用 feign 调用提供者 ,会报500,即服务器没有响应。
这时候重新启动feign(开启feign 熔断后,还没有生效,现在重启feign 使熔断生效)
重新在浏览器访问:localhost:8050/feign/index
成功启动了熔断器。因为提供者调不通,所以直接调用自己熔断方法。