尚硅谷SpringCloud第2季--openFeign

openFeign服务接口调用

openFeign主要用在客服端进行接口调用
在这里插入图片描述

openFeign集成了Ribbon
在这里插入图片描述

尚硅谷SpringCloud第2季--openFeign_第1张图片

openFeign初步使用

依赖

        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-openfeignartifactId>
        dependency>

主启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class OrderFeignMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderFeignMain80.class,args);
    }
}
 

业务类
尚硅谷SpringCloud第2季--openFeign_第2张图片

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id);
}
 

调用

@RestController
public class OrderFeignController {

    @Resource
    private PaymentFeignService paymentFeignService;

    @GetMapping(value = "/consumer/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
       return paymentFeignService.getPaymentById(id);
    }
}
 

尚硅谷SpringCloud第2季--openFeign_第3张图片

openFeign超时控制

当前版本修改超时时间有3中方案:

(1) feign client

feign:
  client:
    config:
      default:
        #default为全局配置,如果要单独配置每个服务,改为服务名
        # 请求连接的超时时间
        connectTimeout: 1000,#默认为10s
        # 请求处理的超时时间,#默认为60s
        readTimeout: 1000
        #这是默认的配置,单次请求最大时长是1s,默认重试5次
#所以如果使用默认配置,超时时间最长也就6s左右,如果要更长时间,则需要自定义了
        retryer: feign.Retryer.Default

(2)hystrix

#默认为true可不配置
#hystrix.command.default.execution.timeout.enabled=true
#默认为1s
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000
(3)rubbin
Feign 的负载均衡底层用的就是 Ribbon
  在application.properties中添加如下配置,超过5秒没连接上报连接超时,如果超过5秒没有响应,报请求超时

ribbon:
# 请求处理的超时时间
  ReadTimeout:  1000    #单位为秒
  # 请求连接的超时时间 默认的时间为 1 秒
  ConnectTimeout: 1000

rubbin默认等待1秒钟,超时报错

那么问题来了,我把这三个配置项都配置上去了,而且把值改大,服务仍然秒超时。

二、解决方案
查阅了各种资料后,发现 FeignClient的默认超时时间为10s,不会开启重试机制。

看见重点了吗,“不会开启重试机制”,没有重试,超时时间再长也没用,所以还得手动加上。

#这是默认的配置,单次请求最大时长是1s,默认重试5次
#所以如果使用默认配置,超时时间最长也就6s左右,如果要更长时间,则需要自定义了
feign.client.config.default.retryer=feign.Retryer.Default

尚硅谷SpringCloud第2季--openFeign_第4张图片

  • 配置openFeign客户端
    Feign 的负载均衡底层用的就是 Ribbon
      在application.properties中添加如下配置,超过5秒没连接上报连接超时,如果超过5秒没有响应,报请求超时
    apolication.yml
ribbon:
# 请求处理的超时时间
  ReadTimeout:  1000    #单位为秒
  # 请求连接的超时时间 默认的时间为 1 秒
  ConnectTimeout: 1000
#这是默认的配置,单次请求最大时长是1s,默认重试5次
#所以如果使用默认配置,超时时间最长也就6s左右,如果要更长时间,则需要自定义了
feign.client.config.default.retryer=feign.Retryer.Default

openFeign日志打印功能

在这里插入图片描述

  • 日志级别
    尚硅谷SpringCloud第2季--openFeign_第5张图片
  • 配置日志bean
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}
 
 
  • application.yml中需要开启日志的Feign客户端
    在这里插入图片描述
logging:
  level:
    com.atguigu.springcloud.service.PaymentFeignService: debug

Feign的重试、超时自定义

通过配置文件

application.yml

feign:
  client:
    config:
      default:
        #default为全局配置,如果要单独配置每个服务,改为服务名
        # 请求连接的超时时间,#默认为10s
        connectTimeout: 1000
        # 请求处理的超时时间,#默认为60s
        readTimeout: 1000
        #默认重试5次
        retryer: feign.Retryer.Default

通过配置类配置

@Configuration
public class FeignClientConfiguration {

  //自定义重试次数
  @Bean
  public Retryer feignRetryer() {
    // period=100 发起当前请求的时间间隔,单位毫秒
    // maxPeriod=1000 发起当前请求的最大时间间隔,单位毫秒
    // maxAttempts=5 最多请求次数,包括第一次
    Retryer retryer = new Retryer.Default(100, 1000, 5);
    return retryer;
  }

  //自定义请求超时时间
  @Bean
  public Request.Options  feignRequest() {
    // connectTimeoutMillis=1000 链接超时时间
    // readTimeoutMillis=1000 响应超时时间,如果超过10秒没有接过发起下一次请求
    Request.Options options = new Request.Options(1000, 5000);
    return options;
  }
  }

带参数

@FeignClient(name = "Ekafka-DW", url = "${ecollector.server.url}",
        configuration = FeignClientConfiguration.class)
public interface EServerClient {
    
    @RequestMapping(method = RequestMethod.GET, value = "/test2/tenants/{tenant_id}/clusters/{cluster_id}/cgs/{group}")
    List<String> getTest2(@PathVariable("tenant_id") String tenantId,
                                             @PathVariable("cluster_id") String clusterId,
                                             @PathVariable("group") String group);
    
}

配置文件

一般使用的配置文件
FeignClientConfiguration.class

@Configuration
public class FeignClientConfiguration {

  //自定义重试次数
  @Bean
  public Retryer feignRetryer() {
    // period=100 发起当前请求的时间间隔,单位毫秒
    // maxPeriod=1000 发起当前请求的最大时间间隔,单位毫秒
    // maxAttempts=5 最多请求次数,包括第一次
    Retryer retryer = new Retryer.Default(100, 1000, 3);
    return retryer;
  }

  //自定义请求超时时间
  @Bean
  public Request.Options  feignRequest() {
    // connectTimeoutMillis=1000 链接超时时间
    // readTimeoutMillis=1000 响应超时时间,如果超过10秒没有接过发起下一次请求
    Request.Options options = new Request.Options(1000, 5000);
    return options;
  }

  //日志配置
  @Bean
  Logger.Level feignLoggerLevel() {
    return Logger.Level.FULL;
  }

  //请求https时忽略证书
  @Bean
  public Client feignClient() {
    Client trustSSLSockets = new Client.Default(getSSLSocketFactory(), new NoopHostnameVerifier());
    return trustSSLSockets;
  }

  private SSLSocketFactory getSSLSocketFactory() {
    try {
      TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
          //Do your validations
          return true;
        }
      };

      SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
      return sslContext.getSocketFactory();
    } catch (Exception exception) {
      throw new RuntimeException(exception);
    }
  }
}

支持feign自己的请求风格

feign自己的请求风格:

@FeignClient(name = "test", url = "localhost:8080",
             configuration = FeignClientConfiguration.class)
public interface EServerClient {

  @RequestLine("GET /test1")
  String getTest1();
  
  @RequestLine("GET /test2/{id}")
    String getTest2(@PathVariable("id") long id);

}

在配置类中声明

@Configuration
public class FeignClientConfiguration {
//支持feign自己的请求风格,不支持SpringMVC的风格
  @Bean
  public Contract useFeignAnnotations() {
    return new Contract.Default();
   }
  }

你可能感兴趣的:(微服务)