zoukankan      html  css  js  c++  java
  • feign 声明式客户端接口

    feign 声明式客户端接口

    解决问题: feign集成了远程调用, ribbon, hystrix, 实现业务之间的远程调用及负载均衡的

    微服务应用中,ribbon 和 hystrix 总是同时出现,feign 整合了两者,并提供了声明式消费者客户端

    用 feign 代替 hystrix+ribbon

    快速开始

    1. 创建springboot项目导入依赖

    依赖: Spring Boot Actuator(监控工具), Eureka Discovery Client(Eureka客户端), OpenFeign(feign), Spring Web(Web)

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <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>
    

    2. yml配置

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

    3. 主程序添加注解

    @EnableDiscoveryClient(高版本可省略) 和 @EnableFeignClients

    @EnableFeignClients // 开启Feign
    @EnableDiscoveryClient // 注册中心(Eureka)客户端开启注解, 高版本可省略此注解
    @SpringBootApplication
    public class Sp09FeignApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(Sp09FeignApplication.class, args);
    	}
    
    }
    

    4. 定义客户端通信接口

    在feign包下定义接口, 用于和其他的服务器通信

    1. 接口上需要使用@FeignClient*(name = "item-service")注解, name参数是服务器的ID, 即配置文件中的服务名,
    2. 接口中的方法使用SpringMVC的注解, 例如@RequestMapping,,@GetMapping, @PostMapping

    例如:

    @FeignClient(name = "item-service") // name(别名value) 的属性为服务yml中配置的应用名
    public interface ItemFeignClient {
    
        @GetMapping("/{orderId}") // SpringMVC的注解
        JsonResult<List<Item>> getItems(@PathVariable String orderId);
    
        @PostMapping("/decreaseNumber") // SpringMVC的注解
        JsonResult decrease(@RequestBody List<Item> items);
    
    }
    

    假如调用接口中的getItem方法, 例如getItem(7) 实际上就是发送了远程Http请求, 如下

    http://IP:PORT/7 其中IP和PORT是由Eureka注册中心所绑定的, 会根据应用名item-service找到对应的ip和port

    5. 编写Controlller

    @RestController
    @Slf4j
    public class FeignController {
        
        @Autowired
        private ItemFeignClient itemFeignClient; // 注入接口对象, 对象由底层实现
        
        @GetMapping("/item-service/{orderId}")
        public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
            log.info("调用商品服务, 获得订单的商品列表");
            return itemFeignClient.getItems(orderId); // 调用feign的接口, 远程通信
        }
    
        @PostMapping("/item-service/decreaseNumber")
        public JsonResult deccreaseNumber(@RequestBody List<Item> items) {
            log.info("调用商品服务, 减少商品库存");
            return itemFeignClient.decrease(items); // 调用feign的接口, 远程通信
        }
        
    }
    

    注意, 接口中的注解尽量和Controller保持一致, 例如@PathVariable注解不能省略, 否则可能会出现链接失败异常

    自行测试访问feign中的controller, 是否能够调用item-service的controller

    案例执行流程图

    案例总结

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

    例如:

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

    当这样调用该方法:

    service.addScore(7, 100);
    1
    

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

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

    feign + ribbon 负载均衡和重试

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

    yml配置

    如下yml配置:

    # 所有服务都有效
    ribbon:
      ConnectTimeout: 1000  # 链接超时时间
      ReadTimeout: 1000   # 读取超时时间
     
    # 只对 item-service 有效
    item-service:
      ribbon:
        MaxAutoRetries: 1  # 单台服务器最大自动重试次数
        MaxAutoRetriesNextServer: 2  # 自动更换服务器次数
        ConnectTimeout: 1000  # 链接超时时间
        ReadTimeout: 500  # 读取超时时间
    

    参数默认值

    MaxAutoRetries: 0
    MaxAutoRetriesNextServer: 1
    ReadTimeout: 1000
    

    feign + hystrix 降级

    特殊需求,要启用Hystrix,首先做基本基础配置:

    1. 添加 Hystrix 完整依赖
    2. 添加注解 @EnableCircuitBreaker
    3. yml 配置启用 hystrix: feign.hystrix.enabled=true

    大体结构如下

    // 声明式客户端接口添加注解属性
    @FeignClient(name="item-service", fallback=降级类.class)
    public interface ItemFeignClient {
        
    }
    ​
    ​
    //定义降级类,实现声明式客户端接口
    public class 降级类 implements ItemFeignClient {
            
    }
    

    1. feign 启用 hystrix

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

    • feign.hystrix.enabled=true

    yml中配置

    feign:
      hystrix:
        enabled: true
    

    降级超时时间配置

    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 1000  # 按需求自行配置, 单位为毫秒(一般大于重试时间, 5-10秒即可)
    

    2. feign 远程接口中指定降级类

    我们上面使用了@FeignClient(name="item-service")注解来制定了远程的服务器, 现在我们需要添加一个fallback 参数来指定降级类

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

    3. 实现降级类

    ItemFeignServiceFB

    降级类需要实现远程调用的接口, 然后重写接口中的方法

    当接口中的方法, 远程调用(出现异常、等待超时、不能连接)时, 会执行降级类中的重写方法

    @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 监控和熔断测试

    步骤:

    1. 添加 actuator 依赖
    2. 暴露监控端点 m.e.w.e.i=hystrix.stream

    1. 依赖

    快速开始案例中已经加过此依赖就不需要再加了

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

    2. 主程序注解

    @EnableCircuitBreaker主程序需要假如此注解

    @EnableCircuitBreaker // hystrix
    @EnableFeignClients // feign
    @EnableDiscoveryClient // eureka注册中心客户端, 高版本可省略
    @SpringBootApplication
    public class Sp09FeignApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(Sp09FeignApplication.class, args);
    	}
    
    }
    

    3.配置 actuator,暴露监控端点

    management:
      endpoints:
        web:
          exposure:
            include: hystrix.stream  # 只暴露 hystrix.stream 端点
    

    4. 启动服务,查看监控端点

    查看所有监控链接: http://localhost:3001/actuator

    查看hystrix监控: http://localhost:3001/actuator/hystrix.stream

    如果hystrix一直出现ping, 可尝试发送一次请求, 会不会出现一大坨信息, 如果还是没有一大坨信息, 可能时降级没有配置好,

    5. 仪表盘监控以及并发测试

    关于仪表盘监控, 请参考这里: [仪表盘监控]

    关于并发测试: [并发测试]

  • 相关阅读:
    UITableview cell 的多选
    抽屉开关控制器
    NSDate 获取明天、后天的日期
    UITextField里面的 placeholder颜色和字体
    判断返回数据是否为 null
    UIButton 长按点击 背景改变效果
    UIButton 去除按下效果(阴影)
    iOS-RunLoop,为手机省电,节省CPU资源,程序离不开的机制
    iOS-真机调试
    iOS-设置启动图片
  • 原文地址:https://www.cnblogs.com/zpKang/p/13584468.html
Copyright © 2011-2022 走看看