Spring Cloud之Feign
Feign的概述
Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端。Spring Cloud引入Feign并且集成了Ribbon实现客户端负载均衡调用。
Feign不但整合了Ribbon和Hystrix的功能,还提供了一种比Ribbon更简单的服务调用方式 ——— 声明式服务调用。
Feign的使用
添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
定义接口
定义FeignClient接口
@Component
@FeignClient(value = "eureka-client1") //指定远程调用的服务名
public interface TestController {
//远程调用test接口
@GetMapping("/test")//用GetMapping标识远程调用的http的方法类型
public String test();
}
启动类添加注解
使用@EnableFeignClients和@EnableDiscoveryClient注解,开启Spring Cloud Feign和服务注册与发现
@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
服务提供者
@RestController
public class TestController {
@GetMapping("/test")
public String test() {
return "hello world";
}
@PostMapping("/getUser")
public User getUser(@RequestBody User user) {
return user;
}
}
服务消费者
server:
port: 8083
spring:
application:
name: Server-Consumer
eureka:
client:
serviceUrl:
defaultZone: http://admin:admin123@localhost:8080/eureka/
在Spring Cloud Ribbon中访问服务需要通过RestTemplate对象来实现,并且参数绑定过程繁琐。Feign对这个步骤进行了进一步的封装,使用Feign调用服务只需要定义一个接口,然后将服务提供者中的部分代码复制改造即可.
//@FeignClient("Server-Produce")注解获取服务,其中服务名称不区分大小写。
@FeignClient("Server-Produce")
public interface ITestService {
@GetMapping("/test")
public String test();
@PostMapping("/getUser")
public User getUser(User user);
}
执行测试
@RestController
public class TestController {
@Autowired
private ITestService testService;
@GetMapping("/test")
public String test(){
return testService.test();
}
@GetMapping("/getUser")
public User getUser(){
User user = new User();
user.setUsername("小白");
return testService.getUser(user);
}
}
Feign的配置
配置Hystrix
# 开启Hystrix
feign:
hystrix:
enabled: true
创建TestService 类实现ITestService接口,重写方法,这些方法就是处理服务降级的方法
@Service
public class TestService implements ITestService{
@Override
public String test() {
return "服务暂时不可用,请稍后重试";
}
@Override
public User getUser(User user) {
return null;
}
}
fallback 属性来指定对应的服务降级实现类:
@FeignClient(value = "Server-Produce",fallback = TestService.class)
public interface ITestService {
@GetMapping("/test")
public String test();
@PostMapping("/getUser")
public User getUser(User user);
}
请求压缩
Feign支持对请求与响应进行GZIP压缩,以减少通信过程中的性能损耗
# 开启Hystrix
feign:
hystrix:
enabled: true
# 开启压缩
compression:
request:
enabled: true
# 指定压缩的请求数据类型
mime-types: text/xml,application/xml,application/json
# 指定请求压缩的大小下限,超过这个大小的请求才会对其进行压缩
min-request-size: 2048
response:
enabled: true
日志配置
Feign提供了日志打印的功能,Feign的日志级别分为四种:
NONE: 不记录任何信息。
BASIC: 仅记录请求方法、URL以及响应状态码和执行时间。
HEADERS: 除了记录BASIC级别的信息之外,还会记录请求和响应的头信息。
FULL: 记录所有请求与响应的明细,包括头信息、请求体、元数据等。
请求压缩
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestFeign {
@Autowired
//接口代理对象,由Feign生成代理对象
TestController testController;
@Test
public void testRibbon(){
//发起远程调用
String string = testController.test();
System.out.println(string);
}
}
[main] INFO c.netflix.discovery.DiscoveryClient - Starting heartbeat executor: renew interval is: 30
[main] INFO c.n.discovery.InstanceInfoReplicator - InstanceInfoReplicator onDemand update allowed rate per min is 4
[main] INFO c.netflix.discovery.DiscoveryClient - Discovery Client initialized at timestamp 1608039839407 with initial instances count: 3
[main] INFO c.n.config.ChainedDynamicProperty - Flipping property: eureka-client1.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
[main] INFO c.n.l.DynamicServerListLoadBalancer - DynamicServerListLoadBalancer for client eureka-client1 initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=eureka-client1,current list of Servers=[127.0.0.1:8081],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:127.0.0.1:8081; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@2fca282c
{"name":"lisi","age":"20"}
Feign工作原理
1、启动类添加@EnableFeignClients注解,Spring会扫描标记了@FeignClient注解的接口,并生成此接口的代理对象
2、@FeignClient(value = "eureka-client1")指定eureka的服务名称,Feign会从注册中心获取eureka服务列表,并通过负载均衡算法进行服务调用。
3、在接口方法 中使用注解@GetMapping("/test"),指定调用的url,Feign将根据url进行远程调用。