Spring Cloud-OpenFeign服务调用

简介

Spring Cloud OpenFeign是声明式的服务调用工具,它整合了Ribbon和Hystrix,拥有负载均衡和服务容错功能,本文将对其用法进行详细介绍。

Feign是声明式的服务调用工具,我们只需创建一个接口并用注解的方式来配置它,就可以实现对某个服务接口的调用,简化了直接使用RestTemplate来调用服务接口的开发量。Feign具备可插拔的注解支持,同时支持Feign注解、JAX-RS注解及SpringMVC注解。当使用Feign时,Spring Cloud集成了Ribbon和Eureka以提供负载均衡的服务调用及基于Hystrix的服务容错保护功能。

版本信息:
Spring Cloud:Hoxton.RELEASE
Spring Boot:2.2.2.RELEASE

创建feign-service模块

这里我们创建一个feign-service模块来演示feign的常用功能。

pom.xml添加相关依赖

<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>

application.yml添加配置

server:
  port: 8701

spring:
  application:
    name: feign-service

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8001/eureka/
#在Feign中开启Hystrix
feign:
  hystrix:
    enabled: true
logging:
  level:
    com.whw.springcloud.feignservice: debug

启动类添加@EnableFeignClients注解来启动Feign客户端功能

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class FeignServiceApplication {

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

}

添加UserService接口完成对user-service服务的接口绑定

我们通过@FeignClient注解实现了一个Feign客户端,其中的value为user-service,表示这是对user-service服务的接口调用客户端。我们只需将user-service中的UserController中的方法改为接口,保留原来的SpringMVC注解即可。

UserService类:

@FeignClient(value = "user-service", fallback = UserFallbackService.class)
public interface UserService {

    @PostMapping("/user/insert")
    Result insert(@RequestBody User user);

    @GetMapping("/user/{id}")
    Result<User> getUser(@PathVariable Long id);

    @GetMapping("/user/listUsersByIds")
    Result<List<User>> listUsersByIds(@RequestParam List<Long> ids);

    @GetMapping("/user/getByUsername")
    Result<User> getByUsername(@RequestParam String username);

    @PostMapping("/user/update")
    Result update(@RequestBody User user);

    @PostMapping("/user/delete/{id}")
    Result delete(@PathVariable Long id);

}

添加UserFeignController调用UserService实现服务调用

UserFeignController类:

@RestController
@RequestMapping("/user/feign")
public class UserFeignController {

    @Autowired
    private UserService userService;

    @PostMapping("/insert")
    public Result insert(@RequestBody User user) {
        return userService.insert(user);
    }

    @GetMapping("/{id}")
    public Result<User> getUser(@PathVariable Long id) {
        return userService.getUser(id);
    }

    @GetMapping("/listUsersByIds")
    public Result<List<User>> listUsersByIds(@RequestParam List<Long> ids) {
        return userService.listUsersByIds(ids);
    }

    @GetMapping("/getByUsername")
    public Result<User> getByUsername(@RequestParam String username) {
        return userService.getByUsername(username);
    }

    @PostMapping("/update")
    public Result update(@RequestBody User user) {
        return userService.update(user);
    }

    @PostMapping("/delete/{id}")
    public Result delete(@PathVariable Long id) {
        return userService.delete(id);
    }
}

启动服务:
eureka-service
user-service-8201
user-service-8202
feign-service

服务注册信息如下图所示:

springcloud-feign-01.pngspringcloud-feign-01.png

负载均衡测试

多次调用接口:http://localhost/user/feign/100
可以发现8201和8202的user-service日志相互交替打印。

Feign中的服务降级

Feign中的服务降级使用起来非常方便,只需要为Feign客户端定义的接口添加一个服务降级处理的实现类即可。

添加服务降级处理类UserFallbackService

@Component
public class UserFallbackService implements UserService {

    @Override
    public Result insert(User user) {
        return new Result("调用失败,服务被降级", 500);
    }

    @Override
    public Result<User> getUser(Long id) {
        return new Result("调用失败,服务被降级", 500);
    }

    @Override
    public Result<List<User>> listUsersByIds(List<Long> ids) {
        return new Result("调用失败,服务被降级", 500);
    }

    @Override
    public Result<User> getByUsername(String username) {
        return new Result("调用失败,服务被降级", 500);
    }

    @Override
    public Result update(User user) {
        return new Result("调用失败,服务被降级", 500);
    }

    @Override
    public Result delete(Long id) {
        return new Result("调用失败,服务被降级", 500);
    }
}

设置服务降级处理类UserFallbackService

修改@FeignClient注解中的参数,设置fallback为UserFallbackService.class即可。

如下所示:

@FeignClient(value = "user-service", fallback = UserFallbackService.class)
public interface UserService {
}

修改application.yml,开启Hystrix功能

#在Feign中开启Hystrix
feign:
  hystrix:
    enabled: true

服务降级功能演示

关闭两个user-service,重启feign-service;

调用地址:http://localhost/user/feign/100

接口响应:{"message":"调用失败,服务被降级","code":500,"data":null}

可以发现返回了服务降级的信息。

Feign日志打印

Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中的Http请求的细节。

日志级别

  • NONE:默认的,不显示任何日志;
  • BASIC:仅记录请求方法、URL、响应状态码及执行时间;
  • HEADERS:除了BASIC中定义的信息外,还有请求和响应头的信息;
  • FULL:除了HEADERS中定义的信息外,还有请求和响应的正文及元数据;

通过配置打印详细日志

我们通过java配置来使Feign打印最详细的http请求日志信息。

@Configuration
public class FeignConfig {

    @Bean
    Logger.Level level() {
        return Logger.Level.FULL;
    }

}

在application.yml设置配置需要开启日志的Feign客户端
配置UserService的日志级别为debug级别

logging:
  level:
    com.whw.springcloud.feignservice: debug

debug重启feign-service
调用接口:http://localhost/user/feign/100
可以查看日志:

2022...UserService : [UserService#getUser] ---> GET http://user-service/user/100 HTTP/1.1
2022...UserService : [UserService#getUser] ---> END HTTP (0-byte body)
2022...UserService : [UserService#getUser] <--- HTTP/1.1 200 (2ms)
2022...UserService : [UserService#getUser] connection: keep-alive
2022...UserService : [UserService#getUser] content-type: application/json
2022...UserService : [UserService#getUser] date: Sat, 10 Dec 2022 20:43:31 GMT
2022...UserService : [UserService#getUser] keep-alive: timeout=60
2022...UserService : [UserService#getUser] transfer-encoding: chunked
2022...UserService : [UserService#getUser] 
2022...UserService : [UserService#getUser] {"message":"操作成功","code":200,"data":null}
2022...UserService : [UserService#getUser] <--- END HTTP (49-byte body)

Feign常用配置

feign:
  hystrix:
    enabled: true #在Feign中开启Hystrix
  compression:
    request:
      enabled: false #是否对请求进行GZIP压缩
      mime-types: text/xml,application/xml,application/json #指定压缩的请求数据类型
      min-request-size: 2048 #超过该大小的请求会被压缩
    response:
      enabled: false #是否对响应进行GZIP压缩
logging:
  level: #修改日志级别
    com.jourwon.springcloud.service: debug

Gitee项目源码地址:
https://gitee.com/whwtree/springcloud-learning.git

(完)

最后修改于:2022年12月11日 05:03

添加新评论