0
点赞
收藏
分享

微信扫一扫

spring cloud 之 feign

微笑沉默 2021-09-21 阅读 44

一、fegin简介

fegin 是 Netflix 开发的声明式、模板化的HTTP客户端,其令该来自Retrofit、JAXRS-2.0以及WebSocket。feign可帮助我们更加便捷,优雅的调用HTTP API。
在spring cloud中,使用feign非常简单,创建一个接口,并在接口上添加一些注解,代码就完成了。feign支持多种注解,例如feign自带的注解或者JAX-RS注解等 。
spring cloud对feign进行了增强,使feign支持了Spring MVC注解,并整合了Ribbon和Eureka
,从而让Feign的使用更加便捷。

二、使用

添加依赖

        <!-- 包含了Ribbon 和 hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

编写 接口
path 是请求控制器的路径
name 是访问服务的 application.name

// name=eureka里注册的服务
@FeignClient(path = "test", name = "client-hyq-life-server")
public interface TestApi {


    @RequestMapping(value = "/idnex", method = RequestMethod.GET)
    String idnex();

}

编写实现

@RestController
@RequestMapping("test")
public class TestController implements TestApi {

    @Autowired
    private TestServer testServer;

    @Override
    public String idnex(){
        return testServer.idnex();
    }

}

编写调用

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private TestApi testApi;

    @GetMapping("/index")
    public String index(){
        return testApi.idnex();
    }

}

如果两个服务是分离的都需要给启动类加

@EnableFeignClients
@SpringBootApplication
public class BffAppServerApplication {

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

}

三、Feign对压缩的支持

feign:
  # 不使用 openfeign 自带的熔断
  hystrix:
    enabled: false
  compression:
    #配置请求 GZIP 压缩
    request:
      enabled: true
      #配置压缩支持的 MIME TYPE
      mime-types: text/xml,application/xml,application/json
      #配置压缩数据大小的最小阀值,只有超过了这个大小的请求才会对其进行压缩。,默认 2048
      min-request-size: 300
    #配置响应 GZIP 压缩
    response:
      enabled: true

四、feign 对OkHttp的支持

依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>

拦截日志,这里建议做的有意义一些。

/**
 * @author big uncle
 * @date 2020/6/17 9:02
 * ok http 拦截日志
 **/
@Slf4j
public class OkHttpLogInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        log.debug("OkHttpUrl : " + chain.request().url());
        return chain.proceed(chain.request());
    }

}

配置

/**
 * @author big uncle
 * @date 2020/6/17 8:58
 **/
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignOkHttpConfig {

    @Bean
    public okhttp3.OkHttpClient okHttpClient(){
        return new okhttp3.OkHttpClient.Builder()
                // 读取超时设置
                .readTimeout(60, TimeUnit.SECONDS)
                // 连接超时设置
                .connectTimeout(60, TimeUnit.SECONDS)
                //
                .writeTimeout(120, TimeUnit.SECONDS)
                .connectionPool(new ConnectionPool())
                .addInterceptor(okHttpLogInterceptor())
                // .addInterceptor();
                .build();
    }

    @Bean
    public OkHttpLogInterceptor okHttpLogInterceptor(){
        return new OkHttpLogInterceptor();
    }

}

配置出现问题,发现配置的时间一直不生效,我读取时间设置30秒,在拦截里面看只有1秒,所以很多时候提示超时。
最后有个大神跟我说了,fegin 一直都是用的是 default 配置,让我在yml配置 connectTimeout,readTimeout

feign:
  compression:
    # 请求压缩
    request:
      enabled: true
      mime-types: "text/xml,application/xml,application/json"
      # 用于设置请求的最小阈值
      min-request-size: 1024
    # 响应压缩
    response:
      enabled: true
  hystrix:
    enabled: false
  okhttp:
    enabled: true
  client:
    config:
      default:
        connectTimeout: 30000
        readTimeout: 40000

经过发现的确可以做到,在代码里的配置优先级居然没有配置文件高,我个人觉得是有问题的,忽然又想到那配置的池是否也是无用的,待观察。

五、日志

这里为了看每个请求的路径,参数,耗时我们可以进行如下操作,loggerLevel:

feign:
  compression:
    # 请求压缩
    request:
      enabled: true
      mime-types: "text/xml,application/xml,application/json"
      # 用于设置请求的最小阈值
      min-request-size: 1024
    # 响应压缩
    response:
      enabled: true
  hystrix:
    enabled: false
  okhttp:
    enabled: true
  client:
    config:
      default:
        connectTimeout: 30000
        readTimeout: 40000
        # BASIC FULL HEADERS NONE
        loggerLevel: BASIC

BASIC 打印如下

2020-06-18 09:45:51.670 DEBUG 26772 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] ---> POST http://server-data-platform/menu/getSonDataMenuList HTTP/1.1
2020-06-18 09:45:52.637 DEBUG 26772 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] <--- HTTP/1.1 200  (966ms)
2020-06-18 09:45:52.767 DEBUG 26772 --- [nio-8888-exec-2] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] ---> POST http://server-data-platform/electricityStation/getElectricityStationList HTTP/1.1
2020-06-18 09:45:52.805 DEBUG 26772 --- [nio-8888-exec-2] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] <--- HTTP/1.1 200  (38ms)

FULL 打印如下

2020-06-18 09:54:05.190 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] ---> POST http://server-data-platform/menu/getSonDataMenuList HTTP/1.1
2020-06-18 09:54:05.191 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] Content-Length: 1733
2020-06-18 09:54:05.191 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] Content-Type: application/json
2020-06-18 09:54:05.191 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] 
2020-06-18 09:54:05.191 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] {"data":{"id":null,"parentId":null,"menuName":null,"menuPath":"/electricityStation/list","menuOrder":null,"icon":null,"remarks":null,"menuData":null,"menuButton":null},"token":"5a717dca1142d685c8aa54b45d0388c8","user":{"id":1,"account":"15771720565","name":"冯谦润","phone":"15771720565","onlineState":null,"remarks":"fdsafdsa","rolesId":1,"avatar":null,"token":"5a717dca1142d685c8aa54b45d0388c8","roles":{"id":1,"roleName":"超级管理员","remarks":"2222","menus":null},"menus":[{"id":1,"parentId":0,"menuName":"大屏展示","menuPath":"/dashboard","menuOrder":1000,"icon":"el-icon-monitor","remarks":null,"menuData":false,"menuButton":false,"child":[]},{"id":2,"parentId":0,"menuName":"数据分析","menuPath":"/dataAnalysis","menuOrder":2000,"icon":"el-icon-data-line","remarks":null,"menuData":false,"menuButton":false,"child":[]},{"id":3,"parentId":0,"menuName":"系统管理","menuPath":"/setting","menuOrder":3000,"icon":"el-icon-setting","remarks":null,"menuData":false,"menuButton":false,"child":[{"id":5,"parentId":3,"menuName":"角色管理","menuPath":"/setting/roles","menuOrder":3200,"icon":null,"remarks":null,"menuData":false,"menuButton":false,"child":[]},{"id":6,"parentId":3,"menuName":"菜单管理","menuPath":"/setting/menus","menuOrder":3300,"icon":null,"remarks":null,"menuData":false,"menuButton":false,"child":[]}]},{"id":16,"parentId":0,"menuName":"电站管理","menuPath":"/electricityStation","menuOrder":4000,"icon":"el-icon-lightning","remarks":null,"menuData":false,"menuButton":false,"child":[{"id":17,"parentId":16,"menuName":"电站信息","menuPath":"/electricityStation/list","menuOrder":4100,"icon":null,"remarks":"列出所有电站","menuData":false,"menuButton":false,"child":[]}]}]}}
2020-06-18 09:54:05.191 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] ---> END HTTP (1733-byte body)
2020-06-18 09:54:06.014 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] <--- HTTP/1.1 200  (822ms)
2020-06-18 09:54:06.015 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] connection: keep-alive
2020-06-18 09:54:06.015 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] content-type: application/json
2020-06-18 09:54:06.015 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] date: Thu, 18 Jun 2020 01:54:05 GMT
2020-06-18 09:54:06.015 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] keep-alive: timeout=60
2020-06-18 09:54:06.015 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] transfer-encoding: chunked
2020-06-18 09:54:06.015 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] 
2020-06-18 09:54:06.017 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] {"code":200,"msg":null,"data":[{"id":24,"parentId":17,"menuName":"电站数据","menuPath":"/electricityStation/data","menuOrder":4110,"icon":null,"remarks":null,"menuData":true,"menuButton":false,"child":[{"id":25,"parentId":24,"menuName":"平顶山","menuPath":"/electricityStation/data/pds","menuOrder":4111,"icon":null,"remarks":null,"menuData":true,"menuButton":false,"child":[]}]}]}
2020-06-18 09:54:06.017 DEBUG 29140 --- [nio-8888-exec-1] com.giant.cloud.api.MenuApi              : [MenuApi#getSonDataMenuList] <--- END HTTP (388-byte body)
2020-06-18 09:54:06.453 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] ---> POST http://server-data-platform/electricityStation/getElectricityStationList HTTP/1.1
2020-06-18 09:54:06.453 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] Content-Length: 1756
2020-06-18 09:54:06.453 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] Content-Type: application/json
2020-06-18 09:54:06.453 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] 
2020-06-18 09:54:06.453 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] {"data":{"data":{"id":null,"parentId":null,"menuName":null,"menuPath":null,"menuOrder":null,"icon":null,"remarks":null,"menuData":null,"menuButton":null,"menuId":"25"},"current":1,"size":20},"token":"5a717dca1142d685c8aa54b45d0388c8","user":{"id":1,"account":"15771720565","name":"冯谦润","phone":"15771720565","onlineState":null,"remarks":"fdsafdsa","rolesId":1,"avatar":null,"token":"5a717dca1142d685c8aa54b45d0388c8","roles":{"id":1,"roleName":"超级管理员","remarks":"2222","menus":null},"menus":[{"id":1,"parentId":0,"menuName":"大屏展示","menuPath":"/dashboard","menuOrder":1000,"icon":"el-icon-monitor","remarks":null,"menuData":false,"menuButton":false,"child":[]},{"id":2,"parentId":0,"menuName":"数据分析","menuPath":"/dataAnalysis","menuOrder":2000,"icon":"el-icon-data-line","remarks":null,"menuData":false,"menuButton":false,"child":[]},{"id":3,"parentId":0,"menuName":"系统管理","menuPath":"/setting","menuOrder":3000,"icon":"el-icon-setting","remarks":null,"menuData":false,"menuButton":false,"child":[{"id":5,"parentId":3,"menuName":"角色管理","menuPath":"/setting/roles","menuOrder":3200,"icon":null,"remarks":null,"menuData":false,"menuButton":false,"child":[]},{"id":6,"parentId":3,"menuName":"菜单管理","menuPath":"/setting/menus","menuOrder":3300,"icon":null,"remarks":null,"menuData":false,"menuButton":false,"child":[]}]},{"id":16,"parentId":0,"menuName":"电站管理","menuPath":"/electricityStation","menuOrder":4000,"icon":"el-icon-lightning","remarks":null,"menuData":false,"menuButton":false,"child":[{"id":17,"parentId":16,"menuName":"电站信息","menuPath":"/electricityStation/list","menuOrder":4100,"icon":null,"remarks":"列出所有电站","menuData":false,"menuButton":false,"child":[]}]}]}}
2020-06-18 09:54:06.454 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] ---> END HTTP (1756-byte body)
2020-06-18 09:54:06.483 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] <--- HTTP/1.1 200  (29ms)
2020-06-18 09:54:06.484 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] connection: keep-alive
2020-06-18 09:54:06.484 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] content-type: application/json
2020-06-18 09:54:06.484 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] date: Thu, 18 Jun 2020 01:54:05 GMT
2020-06-18 09:54:06.484 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] keep-alive: timeout=60
2020-06-18 09:54:06.484 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] transfer-encoding: chunked
2020-06-18 09:54:06.484 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] 
2020-06-18 09:54:06.484 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] {"code":200,"msg":null,"data":{"current":1,"size":20,"total":1,"records":[{"createTime":"2020-06-15T03:46:17.000+00:00","updateTime":"2020-06-15T03:46:17.000+00:00","deleteFlag":false,"id":1,"menuId":25,"name":"平顶山新能源项目1期","buildingDegree":30,"cityName":"平顶山","cityId":"410400","lng":"113.308","lat":"33.7352","remarks":"测试数据"}]}}
2020-06-18 09:54:06.484 DEBUG 29140 --- [nio-8888-exec-3] c.giant.cloud.api.ElectricityStationApi  : [ElectricityStationApi#getElectricityStationList] <--- END HTTP (362-byte body)

我就试到这里了,正常来说 FULL 已经足够了。

六、Feign的全局异常处理

@Configuration
public class FeignClientErrorDecoder implements ErrorDecoder {

    private static final Log log = LogFactory.getLog(FeignClientErrorDecoder.class);

    @Override
    public Exception decode(String methodKey, Response response) {
        try {
            String body = IoUtil.read(response.body().asInputStream(), "utf-8");
            Map<String,String> errMap = JSONObject.parseObject(body, HashMap.class);
            return new InternalException(errMap.get("message"));
        }catch(Exception e){
            return new InternalException(e.getMessage());
        }
    }
}
举报

相关推荐

0 条评论