Feign声明式客户端接口

声明式客户端接口

只需要定义一个抽象的接口,就可以通过接口调用远程服务,不需要写具体调用代码.
例如调用后台商品服务,接口可以这样定义


@FeignClient(name="item-service")
public interface ItemFeignClient {
    @GetMapping("/{orderId}")
    JsonResult<List<Item>> getItems(@PathVarible String orderId);
}
  • 通过注解,配置以下三点:
    1. 服务id - 确定调用哪个远程服务
    2. 路径 - 调用一个服务的哪个路径
    3. 参数 - 向这个路径提交什么参数数据
      微服务应用中国,ribbon和hystrix总是同时出现,feign整合了两者,并提供了声明式消费者客户端
  • 用feign代替了 hystrix+ribbon
    Feign声明式客户端接口_第1张图片

入门案例

1.新建项目并导入坐标

Feign声明式客户端接口_第2张图片

2. 添加公共配置类坐标

3. yml配置

spring:
  application:
    name: feign
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

4. 主程序添加注解

@EnableDiscoveryClient (开启eureka)和 @EnableFeignClients(开启 feign)

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Sp09FeignApplication {

	public static void main(String[] args) {
		SpringApplication.run(Sp09FeignApplication.class, args);
	}

}

feign声明式客户端

feign 利用了我们熟悉的 spring mvc 注解来对接口方法进行设置,降低了我们的学习成本。
通过这些设置,feign可以拼接后台服务的访问路径和提交的参数
例如:

@GetMapping("/{userId}/score") 
JsonResult addScore(@PathVariable Integer userId, @RequestParam Integer score);

当这样调用该方法

service.addScore(7, 100);

那么feign会向服务器发送请求

http://用户微服务/7/score?score=100
  • 注意:如果score参数名和变量名不同,需要添加参数名设置
@GetMapping("/{userId}/score") 
JsonResult addScore(@PathVariable Integer userId, @RequestParam("score") Integer s);

FeignService

@FeignClient("item-service")
public interface ItemFeignService {
	@GetMapping("/{orderId}")
	JsonResult<List<Item>> getItems(@PathVariable String orderId);

	@PostMapping("/decreaseNumber")
	JsonResult decreaseNumber(@RequestBody List<Item> items);
}

FeignController

@RestController
public class FeignController {
	@Autowired
	private ItemFeignService itemService;
	@Autowired
	private UserFeignService userService;
	@Autowired
	private OrderFeignService orderService;
	
	@GetMapping("/item-service/{orderId}")
	public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
		return itemService.getItems(orderId);
	}

	@PostMapping("/item-service/decreaseNumber")
	public JsonResult decreaseNumber(@RequestBody List<Item> items) {
		return itemService.decreaseNumber(items);
	}
}

调用流程

Feign声明式客户端接口_第3张图片

feign+ribbon负载均衡和重试

  • 无需额外配置, feign默认已经启用了ribbon负载均衡和重试机制.可以通过配置对参数进行调整

重试的默认配置参数:

ConnectTimeout=1000
ReadTimeout=1000
MaxAutoRetries=0
MaxAutoRetriesNextServer=1

application.yml配置ribbon超时和重试

  • ribbon.xxx 全局配置
  • item-service.ribbon.xxx 对特定服务器实例的配置
spring:
  application:
    name: feign
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
#全局配置     
ribbon:
  ConnectTimeout: 1000
  ReadTimeout: 1000
#局部配置
item-service:
  ribbon:
    MaxAutoRetries: 1
    MaxAutoRetriesNextServer: 2
    ConnectTimeout: 1000
    ReadTimeout: 500

feign+hystrix降级

feign启用hystrix

feign默认没有启用hystrix,添加配置,启用hystrix

  • feign.hystrix.enabled=true

application.yml添加配置

feign:
  hystrix:
    enabled: true

启用hystrix,访问服务
默认1秒会快速失败,没有降级方法时,会显示空白页
Feign声明式客户端接口_第4张图片

可以添加配置,暂时减少降级超时时间,以便对降级的测试

ribbon超时时间至少应小于ystrix的超时时间

......

feign:
  hystrix:
    enabled: true
    
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 500

feign+hystrix降级

feign远程接口中指定降级类

远程调用事变,会执行降级类中的代码

添加降级代码

添加一个单独的降级类,需要实现声明式客户端接口

@Component
public class ItemFeignClientFB implements ItemFeignClient {
    实现降级方法,返回降级响应
}

在接口上,还需要指定降级类

@FeignClient(name="item-service",fallback=降级类)
interface ItemFeignClient {
    
}

FeignService

...
@FeignClient(name="item-service", fallback = ItemFeignServiceFB.class)
public interface ItemFeignService {
...

降级类

降级类需要实现远程接口


@Component
public class ItemFeignServiceFB implements ItemFeignService {

	@Override
	public JsonResult<List<Item>> getItems(String orderId) {
		return JsonResult.err("无法获取订单商品列表");
	}

	@Override
	public JsonResult decreaseNumber(List<Item> items) {
		return JsonResult.err("无法修改商品库存");
	}

}

feign+hystrix监控和熔断测试

Feign声明式客户端接口_第5张图片

修改上述项目pom.xml添加hystrix起步依赖

  • feign没有包含完整的hystrix依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

主程序添加@EnableCircuitBreaker

@EnableCircuitBreaker
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Sp09FeignApplication {

	public static void main(String[] args) {
		SpringApplication.run(Sp09FeignApplication.class, args);
	}

}

配置actuator,暴露 hystrix.stream 监控端点

actuator依赖

查看pom.xml,确认已经添加了 actuator 依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

application.yml暴露 hystrix.stream 端点

management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream

启动服务,查看监控端点

http://localhost:端口/actuator

hystrix dashboard

启动 hystrix dashboard 服务,填入 feign 监控路径,开启监控
访问 http://localhost:4001/hystrix

  • 填入 feign 监控路径:
    http://localhost:3001/actuator/hystrix.stream

  • 访问微服务,以产生监控数据
    Feign声明式客户端接口_第6张图片

你可能感兴趣的:(SpringCloud)