1 介绍

  Feign 是一个声明式的 REST 客户端,它能让 REST 调用更加简单。Feign 提供了 Http 请求的模板,通过编写简单的忌口和插入注解,就可以定义好 Http 请求的参数、格式、地址等信息。

  之前使用的是 RestTemplate 访问 Rest 服务,RestTemplate 提供了多种便捷访问远程 Http 服务的方法,能够大大提高客户端的编写效率。

  而 Feign 会完全代理 Http 请求,我们只需要湘调用方法一样调用它就可以完成服务请求及相关处理。Feign 可以与 Eureka 和 Ribbon 组合使用以支持负载均衡。

2 集成 Feign

  声明式的 REST 客户端,即注解式的接口调用,类似于 Mapper 接口一样。在服务消费者模块添加如下信息。

2.1 pom.xml
<dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-openfeign</artifactId>
     </dependency>
2.2 Service

  创建 UserInfo Service 接口

@FeignClient(value = "springcloud-provider", path = "/users")
public interface UserInfoService {

    @RequestMapping(value = "/{username}")
    UserInfo getByName(@PathVariable(value = "username") String username);

}

使用 @PathVariable 时,value 需要显式声明,否则报错。

2.3 Controller
@RestController
@RequestMapping(value = "users")
public class UserInfoController {

    @Autowired
    UserInfoService userInfoService;

    /**
     * 通过用户名获取用户
     * @param username
     * @return
     */
    @GetMapping(value = "/feign/{username}")
    public UserInfo getByFeign(@PathVariable String username) {
        UserInfo userInfo = userInfoService.getByName(username);
        return userInfo;
    }
}
2.4 启动类
@SpringBootApplication
@EnableEurekaClient // 表明自己是个 eureka 客户端,会自动注册到 eureka 服务端中
@EnableFeignClients(basePackages = {"com.pky.springcloud"}) // 指定扫描 Feign 相关注解。
public class ConsumerApplication {

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

如果 Feign 接口定义跟启动类不在一个包名下,则需要指定扫描的包名 @EnableFeignClients(basePackages = “指定扫描路径”)

2.5 启动测试

  浏览器输入对应地址。

feign调用负载均衡怎么配置 feign的负载均衡_拦截器

多次请求之后观察 9001、9002 控制台,轮询输出对应信息,达到了负载均衡的效果。

2.6 自定义认证

  Feign 有提供一个接口 RequestInterceptor,即请求拦截器。在请求之前做认证操作,然后往请求头中设置认证之后的信息。通过实现 RequestInterceptor 接口来自定义认证方式。

/**
 * Feign 认证拦截器
 */
@Configuration
public class FeignBasicAuthRequestInterceptor implements RequestInterceptor {
    public FeignBasicAuthRequestInterceptor() {

    }

    @Override
    public void apply(RequestTemplate requestTemplate) {
        // 业务逻辑
        requestTemplate.header("token", "FeignToken");
    }
}

  创建 Feign 配置类:

/**
 * Feign 配置类
 */
@Configuration
public class FeignConfig {

    /**
     * 认证拦截器
     * @return
     */
    @Bean
    public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor(){
        return new FeignBasicAuthRequestInterceptor();
    }

    /**
     * 日志级别
     * @return
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

  还需要在 Feign 接口中引用该配置:

@FeignClient(value = "springcloud-provider", path = "/users", configuration = FeignConfig.class)
public interface UserInfoService {

    @RequestMapping(value = "/{username}")
    UserInfo getByName(@PathVariable(value = "username") String username);

}

  服务提供者模块中的 Controller 接口:

@RestController
@RequestMapping(value = "users")
public class UserInfoController {

    @Autowired
    UserInfoService userInfoService;

    /**
     * 通过用户名获取用户
     * @param username
     * @return
     */
    @GetMapping(value = "/{username}")
    public UserInfo getByName(@PathVariable String username, HttpServletRequest request) {
        String token = request.getHeader("token");
        UserInfo userInfo = userInfoService.getByUsername(username);
        return userInfo;
    }

}

  以上完成自定义认证。

2.7 日志

  若接口调用失败、参数没收到等问题,就需要配置 Feign 的日志。

* Feign 配置类
 */
@Configuration
public class FeignConfig {

    /**
     * 认证拦截器
     * @return
     */
    @Bean
    public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor(){
        return new FeignBasicAuthRequestInterceptor();
    }

    /**
     * 日志级别
     * @return
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

日志类别:

  • NONE: 不输出日志
  • BASIC:只输出请求方法的 URL 和响应的状态码以及接口执行的时间
  • HEADERS:将 BASIC 信息和请求头信息输出
  • FULL: 输出完整的请求信息

  在 application.yml 中配置日志信息

# 日志
logging:
  level:
    com:
      pky:
        springcloud: DEBUG

level 后面为指定包路径。

  调用接口时,控制台会打印相应信息:

feign调用负载均衡怎么配置 feign的负载均衡_spring_02