欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Cloud Feign 使用方法与性能优化

程序员文章站 2022-05-13 23:38:55
1. feign自定义Configuration和root 容器有效隔离。 用@Configuration注解 不能在主@ComponentScan (or @SpringBootApplication)范围内,从其包名上分离 注意避免包扫描重叠,最好的方法是明确的指定包名 2. Spring Cl ......

1. feign自定义configuration和root 容器有效隔离。

  • 用@configuration注解
  • 不能在主@componentscan (or @springbootapplication)范围内,从其包名上分离
  • 注意避免包扫描重叠,最好的方法是明确的指定包名

2. spring cloud netflix 提供了默认的bean类型:

  • decoder feigndecoder: responseentitydecoder (which wraps a springdecoder)
  • encoder feignencoder: springencoder
  • logger feignlogger: slf4jlogger
  • contract feigncontract: springmvccontract
  • feign.builder feignbuilder: hystrixfeign.builder

3. spring cloud netflix没有提供默认值,但仍然可以在feign上下文配置中创建:

  • logger.level
  • retryer
  • errordecoder
  • request.options
  • collection

4. 自定义feign的消息编码解码器:

不要在如下代码中getobject方法内new 对象,外部会频繁调用getobject方法。

1
2
3
4
5
6

objectfactory<httpmessageconverters> messageconvertersobjectfactory = new objectfactory<httpmessageconverters>() {
@override
public httpmessageconverters getobject() throws beansexception {
return httpmessageconverters;
}
};

5. 注意测试环境和生产环境,注意正确使用feign日志级别。

6. apachehttpclient或者其他client的正确配置:

  • apachehttpclient自定义配置放在spring root context,不要在feigncontext,否则不会起作用。
  • apachehttpclient 连接池配置合理地连接和其他参数

7. feign配置

1
2
3
4
5
6
7
8
9
10
11
12
13

#hystrix支持,如果为true,hystrix库必须在classpath中
feign.hystrix.enabled=false

#请求和响应gzip压缩支持
feign.compression.request.enabled=true
feign.compression.response.enabled=true
#支持压缩的mime types
feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048

# 日志支持
logging.level.project.user.userclient: debug

8. logger.level支持

必须为每一个feign client配置来告诉feign如何输出日志,可选:

  • none, no logging (default).
  • basic, log only the request method and url and the response status code and execution time.
  • headers, log the basic information along with request and response headers.
  • full, log the headers, body, and metadata for both requests and responses.

9. feignclient.fallback 正确的使用方法

配置的fallback class也必须在feignclient configuration中实例化,否则会报
java.lang.illegalstateexception: no fallback instance of type class异常。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

@feignclient(name = "hello", fallback = hystrixclientfallback.class)
public interface hystrixclient {
@requestmapping(method = requestmethod.get, value = "/hello")
hello ifailsometimes();
}

public class hystrixclientfallback implements hystrixclient {
@override
public hello ifailsometimes() {
return new hello("fallback");
}
}

@configuration
public class fooconfiguration {
@bean
@scope("prototype")
public feign.builder feignbuilder() {
return feign.builder();
}

@bean
public hystrixclientfallback fb(){
return new hystrixclientfallback();
}

}

10. 使用feign client 和@requestmapping时,注意事项

当前工程中有和feign client中一样的endpoint时,feign client的类上不能用@requestmapping注解否则,当前工程该endpoint http请求且使用accpet时会报404.

下面的例子:

有一个 controller

1
2
3
4
5
6
7
8
9
10
11
12
13

@restcontroller
@requestmapping("/v1/card")
public class indexapi {

@postmapping("balance")
@responsebody
public info index() {
info.builder builder = new info.builder();
builder.withdetail("x", 2);
builder.withdetail("y", 2);
return builder.build();
}
}

有一个feign client

1
2
3
4
5
6
7
8
9
10
11
12
13

@feignclient(
name = "card",
url = "http://localhost:7913",
fallback = cardfeignclientfallback.class,
configuration = feignclientconfiguration.class
)
@requestmapping(value = "/v1/card")
public interface cardfeignclient {

@requestmapping(value = "/balance", method = requestmethod.post, produces = mediatype.application_json_value)
info info();

}

if @requestmapping is used on class, when invoke http /v1/card/balance, like this :

如果 @requestmapping注解被用在feignclient类上,当像如下代码请求/v1/card/balance时,注意有accept header:

1
2
3
4

content-type: application/json
accept: application/json

post http://localhost:7913/v1/card/balance

那么会返回 404。

如果不包含accept header时请求,则是ok:

1
2

content-type:application/json
post http://localhost:7913/v1/card/balance

或者像下面不在feign client上使用@requestmapping注解,请求也是ok,无论是否包含accept:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

@feignclient(
name = "card",
url = "http://localhost:7913",
fallback = cardfeignclientfallback.class,
configuration = feignclientconfiguration.class
)

public interface cardfeignclient {

@requestmapping(value = "/v1/card/balance", method = requestmethod.post, produces = mediatype.application_json_value)
info info();

}