接口调用方式

1:HTTPclient

Apache common 下,

2:OKhttp

安卓端最火,轻量
简洁高效 支持多重协议

3:Reset template webClient

Spring提供访问rest服务端

feign

声明式,模块化的HTTP客户端
像调用接口的方式dubbo调用,不需要httpclient 那样解析,在调用无需关注远程交互

feign的设计机构

image.png

feign调用方式

  1. @FeignClient(value = "mall-order",path = "/order")
  2. public interface OrderFeignService {
  3. @RequestMapping("/findOrderByUserId/{userId}")
  4. public R findOrderByUserId(@PathVariable("userId") Integer userId);
  5. }
  6. @Autowired
  7. OrderFeignService orderFeignService;
  8. //feign调用
  9. R result = orderFeignService.findOrderByUserId(id);

fign的单独使用

引入依赖

  1. <dependency>
  2. <groupId>com.netflix.feign</groupId>
  3. <artifactId>feign-core</artifactId>
  4. <version>8.18.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.netflix.feign</groupId>
  8. <artifactId>feign-jackson</artifactId>
  9. <version>8.18.0</version>
  10. </dependency>
  1. public interface RemoteService {
  2. @Headers({"Content-Type: application/json","Accept: application/json"})
  3. @RequestLine("GET /order/findOrderByUserId/{userId}")
  4. public R findOrderByUserId(@Param("userId") Integer userId);
  1. public class FeignDemo {
  2. public static void main(String[] args) {
  3. //基于json
  4. // encoder指定对象编码方式,decoder指定对象解码方式
  5. RemoteService service = Feign.builder()
  6. .encoder(new JacksonEncoder())
  7. .decoder(new JacksonDecoder())
  8. .options(new Request.Options(1000, 3500))
  9. .retryer(new Retryer.Default(5000, 5000, 3))
  10. .target(RemoteService.class, "http://localhost:8020/");
  11. System.out.println(service.findOrderByUserId(1));
  12. }

fegin与SpringCloudAlibaba整合

依赖

  1. <!-- openfeign 远程调用 -->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-openfeign</artifactId>
  5. </dependency>
  1. @FeignClient(value = "mall-order",path = "/order")
  2. public interface OrderFeignService {
  3. @RequestMapping("/findOrderByUserId/{userId}")
  4. public R findOrderByUserId(@PathVariable("userId") Integer userId);
  5. }

启动类上加注解@EnableFeignClients

  1. @SpringBootApplication
  2. @EnableFeignClients
  3. public class MallUserFeignDemoApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(MallUserFeignDemoApplication.class, args);
  6. }
  7. }

调用

  1. @RestController
  2. @RequestMapping("/user")
  3. public class UserController {
  4. @Autowired
  5. OrderFeignService orderFeignService;
  6. @RequestMapping(value = "/findOrderByUserId/{id}")
  7. public R findOrderByUserId(@PathVariable("id") Integer id) {
  8. //feign调用
  9. R result = orderFeignService.findOrderByUserId(id);
  10. return result;
  11. }
  12. }

Spring Cloud Feign 的自定义配置和使用

1:日志配置

需要定义个配置类指定日志级别

  1. // 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置
  2. //@Configuration,不注释就是全局的,注释后,可以在配置中单独指定
  3. public class FeignConfig {
  4. /**
  5. * 日志级别
  6. * @return
  7. */
  8. @Bean
  9. public Logger.Level feignLoggerLevel() {
  10. return Logger.Level.FULL;
  11. }
  12. }

四种日志级别

  1. none:性能最佳适用生产,不记录日志,也是默认的
  2. basic:生产环境追踪用,记录请求方法,URL,响应,耗时
  3. headers:baseic的基础上加上header
  4. Full:就是全部的了,包括body,元数据

    2: 局部日志,只针调用的微服务有效

    在@FeignClient注解这顶只用即可
    image.png

    3:在yml配置执行client的日志级别

    1. logging:
    2. level:
    3. com.tuling.mall.feigndemo.feign: debug
    4. feign:
    5. client:
    6. config:
    7. mall-order: #对应微服务
    8. loggerLevel: FULL #设置对应微服务的日志级别
    可以在对应的配置文件找对应的可能的还要其他的东西
    org.springframework.cloud.openfeign.FeignClientProperties.FeignClientConfiguration

契约配置

Spring cloud 对feign做了扩展,可以支持MVC的注解调用,
可以使用Spring的注解了默认的类是: Spring Cloud 中默认的是 SpringMvcContract。

修改契约配置,支持feign原生注解

  1. /**
  2. * 修改契约配置,支持Feign原生的注解
  3. * @return
  4. */
  5. @Bean
  6. public Contract feignContract() {
  7. return new Contract.Default();
  8. }

注意:修改契约配置后,OrderFeignService 不再支持springmvc的注解,需要使用Feign原生的注解
使用feign原生注解

  1. @FeignClient(value = "mall-order",path = "/order")
  2. public interface OrderFeignService {
  3. @RequestLine("GET /findOrderByUserId/{userId}")
  4. public R findOrderByUserId(@Param("userId") Integer userId);
  5. }

通过配置指定对应的契约
  1. feign:
  2. client:
  3. config:
  4. mall-order: #对应微服务
  5. loggerLevel: FULL
  6. contract: feign.Contract.Default #指定Feign原生注解契约配置

拦截器,很重要、

比如添加header ,做实名认证,接口鉴权

  1. @Configuration // 全局配置
  2. public class FeignConfig {
  3. @Bean
  4. public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
  5. //自定义自己的拦截逻辑,比如添加header
  6. return new BasicAuthRequestInterceptor("fox", "123456");
  7. }
  8. }

RequestInterceptor

  1. public interface RequestInterceptor {
  2. /**
  3. * Called for every request. Add data using methods on the supplied {@link RequestTemplate}.
  4. */
  5. void apply(RequestTemplate template);
  6. }

这样,每次feign发起HTTP之前都会调用,
可以统一添加Header

代码示例

  1. public class FeignAuthRequestInterceptor implements RequestInterceptor {
  2. @Override
  3. public void apply(RequestTemplate template) {
  4. // 业务逻辑
  5. String access_token = UUID.randomUUID().toString();
  6. template.header("Authorization",access_token);
  7. }
  8. }
  9. @Configuration // 全局配置
  10. public class FeignConfig {
  11. @Bean
  12. public Logger.Level feignLoggerLevel() {
  13. return Logger.Level.FULL;
  14. }
  15. /**
  16. * 自定义拦截器
  17. * @return
  18. */
  19. @Bean
  20. public FeignAuthRequestInterceptor feignAuthRequestInterceptor(){
  21. return new FeignAuthRequestInterceptor();
  22. }
  23. }

也可以在yml中配置拦截器

  1. feign:
  2. client:
  3. config:
  4. mall-order: #对应微服务
  5. requestInterceptors[0]: #配置拦截器
  6. com.tuling.mall.feigndemo.interceptor.FeignAuthRequestInterceptor

4:超时时间配置

通过options配置

  1. @Configuration
  2. public class FeignConfig {
  3. @Bean
  4. public Request.Options options() {
  5. // 默认毫秒,连接超时时间,请求处理的超时时间
  6. return new Request.Options(5000, 10000);
  7. }
  8. }

配置文件方式配置

  1. feign:
  2. client:
  3. config:
  4. mall-order: #对应微服务
  5. # 连接超时时间,默认2s
  6. connectTimeout: 5000
  7. # 请求处理超时时间,默认5s
  8. readTimeout: 10000

fegin底层是ribbon,但是时间一feign为准

5:客户端组件配置,就是底层http具体是走那种方式

feign原生使用JDK的URL connection 发送HTTP,可以替换的
发起调用的执行逻辑 Feign.Client#execute 可以扩展
image.png

替换Apache HttpClient
  1. <!-- Apache HttpClient -->
  2. <dependency>
  3. <groupId>org.apache.httpcomponents</groupId>
  4. <artifactId>httpclient</artifactId>
  5. <version>4.5.7</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>io.github.openfeign</groupId>
  9. <artifactId>feign-httpclient</artifactId>
  10. <version>10.1.0</version>
  11. </dependency>

修改配置就可以启用HTTPclient

  1. feign:
  2. #feign 使用 Apache HttpClient 可以忽略,默认开启
  3. httpclient:
  4. enabled: true

修改配置就能用
是因为org.springframework.cloud.openfeign.FeignAutoConfiguration预留了ApacheHttpClient的位置
image.png

okhttpClient 也可以
image.png

  1. <dependency>
  2. <groupId>io.github.openfeign</groupId>
  3. <artifactId>feign-okhttp</artifactId>
  4. </dependency>
  1. feign:
  2. #feign 使用 okhttp
  3. httpclient:
  4. enabled: false
  5. okhttp:
  6. enabled: true

引入依赖,打开配置就可以用了
feign.okhttp.OkHttpClient#execute

6: GZIP压缩配置

节约资源,提高接口性能的

  1. feign:
  2. # 配置 GZIP 来压缩数据
  3. compression:
  4. request:
  5. enabled: true
  6. # 配置压缩的类型
  7. mime-types: text/xml,application/xml,application/json
  8. # 最小压缩值
  9. min-request-size: 2048
  10. response:
  11. enabled: true

okhttp3是无效的
源码FeignAcceptGzipEncodingAutoConfiguration
核心代码就是 @ConditionalOnMissingBean(type=”okhttp3.OkHttpClient”),表示 Spring BeanFactory 中不包含指定的 bean 时条件匹配,也就是没有启用 okhttp3 时才会进行压缩配置。
image.png

7:编解码器的配置

feign 提供了自定义的编解码器 ,比如Gson,JackSon可以自定义
扩展feign.codec.Encoder ¥ feign.codec.Decoder接口

  1. public interface Encoder {
  2. void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;
  3. }
  4. public interface Decoder {
  5. Object decode(Response response, Type type) throws IOException, DecodeException, FeignException;
  6. }
  1. @Bean
  2. public Decoder decoder() {
  3. return new JacksonDecoder();
  4. }
  5. @Bean
  6. public Encoder encoder() {
  7. return new JacksonEncoder();
  8. }

yml配置文件配置方式

  1. feign:
  2. client:
  3. config:
  4. mall-order: #对应微服务
  5. # 配置编解码器
  6. encoder: feign.jackson.JacksonEncoder
  7. decoder: feign.jackson.JacksonDecoder

fegin 与 openFegin的区别

消息转化器
MessageConverter

拦截器实现认证

FeginAutoConfiguration 条件注解
自动配置,是要引入就可以切换了

如何找怎么配置
从FeginAutoConfiguration 找到FeginClientProperties.java文件
切入点,如何找到

GZIP压缩配置

方法


编解码器配置