๋ฐ์ํ
feign
- Feign์ ์คํ์์ค ์น ์๋น์ค ํด๋ผ์ด์ธํธ์
๋๋ค. (like RestTemlate..)
- HTTP ํต์ ์ ์ํด ์ฌ์ฉํ๋ค๊ณ ์๊ฐํ์๋ฉด ์ฝ์ต๋๋ค.
- ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ค๋ฅธ Feign์ ์ฅ์ ์ api ํธ์ถ ์ค์ ์ ๊ฐ์ํํ์ฌ interface ์ ์ธ๋ง์ผ๋ก API ํธ์ถ์ ํ ์ ์์ต๋๋ค(์ ์ธ์ ์น ์๋น์ค ํด๋ผ์ด์ธํธ)
- Feign์ Netflix๊ฐ ์ฒ์ ๋ง๋ค์์ง๋ง, ์ดํ Netflix๊ฐ feign์ ์ฌ์ฉํ์ง ์๊ธฐ๋ก ๊ฒฐ์ ํ๊ฒ ๋๋ฉด์ ํ์ฌ๋ OpenFeign์ผ๋ก ๊ด๋ฆฌ๋๊ณ ์์ต๋๋ค.
๋ฌธ์ ์ ์์
- ํ๊ฒฝ : spring-cloud-openfeign 2.2.9
- Spring Boot ํ๊ฒฝ์์ application.yml ํ์ผ์ feign ๊ด๋ จ ์ค์ ์ ์์ฑํด feign์ ์ค์ ๊ฐ๋ค์ ์ธํ ํ ์ ์์ต๋๋ค. (๋ค๋ฅธ ๋ฐฉ๋ฒ๋ ์์)
- ํ์ฌ ์ฌ์ง์ค์ธ ํ์ฌ ๊ฐ์ด๋๋ฅผ ์ดํด๋ณด๋ฉฐ feign ๊ด๋ จ ์ค์ ์ ํ๋์ค, ๊ถ๊ธ์ฆ์ด ์๊ฒจ๋ฌ์ต๋๋ค.
feign: client: config: default: connectTimeout: 5000 readTimeout: 15000 loggerLevel: FULL httpclient: connection-timeout: 5000 # feign.client.config.default.connectTimeout๊ณผ feign.httpclient.connection-timeout์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น...
feign.client.config.default.connectTimeout
๊ณผfeign.httpclient.connection-timeout
์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น...- ๊ตฌ๊ธ๋ง์ ํด๋ณด์์ง๋ง ๋ช ํํ ๋ค๋ฅธ ์ ์ ์ค๋ช ํ ๊ธ์ ์ฐพ์๋ณผ ์ ์์์ต๋๋ค ใ
feign.httpclient
The OkHttpClient and ApacheHttpClient and ApacheHC5 feign clients can be used by setting
`feign.okhttp.enabled`
or `feign.httpclient.enabled`
or `feign.httpclient.hc5.enabled` to `true`,
respectively, and having them on the classpath.
OkHttpClient ๋ฐ ApacheHttpClient ๋ฐ ApacheHC5 feign ํด๋ผ์ด์ธํธ๋ ๊ฐ๊ฐ feign.okhttp.enabled ๋๋ feign.httpclient.enabled ๋๋ feign.httpclient.hc5.enabled๋ฅผ true๋ก ์ค์ ํ๊ณ ํด๋์ค ํจ์ค์ ์์ผ๋ฉด ์ฌ์ฉํ ์ ์์ต๋๋ค.
- spring-cloud-openfeign ๊ณต์๋ฌธ์๋ฅผ ํตํด, httpclient → ApacheHttpClient ๊ด๋ จ ์์ฑ์ด๋ผ๊ณ ์ถ์ธกํ ์ ์์์ต๋๋ค.
- ๊ทธ๋ฆฌ๊ณ apache http client๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด feign.httpclient.enabled ์ฒ๋ฆฌ๋ ์์กด์ฑ ์ถ๊ฐ๊ฐ ํ์ํ๋ค๋ ๊ฒ๋ ๊ฐ์ด ํ์ธ ํ ์ ์์์ต๋๋ค.
- ์ฐธ๊ณ : feign๊ฐ ์ง์ํ๋ http client๋ default, apache http client, ok http client ๋ฑ์ด ์์.
์ฌ๊ธฐ์ ๋ฌธ์ !
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 15000
loggerLevel: FULL
httpclient:
connection-timeout: 5000 # feign.client.config.default.connectTimeout๊ณผ feign.httpclient.connection-timeout์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น...
- ์๊น ์ฐธ๊ณ ํ๋ค๋, ํ์ฌ ๊ฐ์ด๋์๋ enabled ์ค์ ์ ๋ํ ์ด์ผ๊ธฐ์ ์์กด์ฑ ์ถ๊ฐ์ ๋ํ ์ด์ผ๊ธฐ๋ ์ฐพ์ ๋ณผ ์ ์์๋๋ฐ์! ๊ทธ๋์ ์ ๋ ๋ค์ ํผ๋์ ๋น ์ง๊ฒ ๋์์ต๋๋ค...
- ๊ณผ์ฐ.. ์ด๋ค ๊ธ์ด ๋ง๋๊ฒ์ธ๊ฐ...
- ๊ทธ๋์ ์ง์ ์์ค๋ฅผ ๊น๋ณด๊ธฐ๋ก ํ์ต๋๋ค!
- ์ด์ : ํ์ฌ ์ ๊ฐ ์ฌ์ฉํ๋ feign ๋ฒ์ ์ด ๋ฎ์ ๋ฒ์ ์ด๋ผ.. ์ต์ ๋ฒ์ ๊ณผ์ ์ค์ ์ฐจ์ด๊ฐ ์์ ์ ์๋ค๊ณ ์๊ฐํด ๊ตฌ๊ธ๋งํ ํ์ด์ง๋ค์ ๋ฏฟ์ง ๋ชปํ๊ฒ ๋์์ต๋๋ค ใ ใ (feign์ด ๋ฒ์ ์ ์ด ๋๋ฉด์ ๋ฐ๋ ๋ถ๋ถ์ด ์๊ทผ ๋ง๋๋ผ๊ตฌ์ ๐คฃ)
FeignAutoConfiguration.java
- ์๋ง์ ๋๋ฒ๊น ๊ณผ ๊ตฌ๊ธ๋ง์ ํตํด feign์ด client ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์ฝ๋๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค.
- ์๋ ์ฝ๋๊ฐ ๋ฐ๋ก ๊ทธ ์ฝ๋์ ๋๋ค!
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({ApacheHttpClient.class})
@ConditionalOnMissingClass({"com.netflix.loadbalancer.ILoadBalancer"})
@ConditionalOnMissingBean({org.apache.http.impl.client.CloseableHttpClient.class})
@ConditionalOnProperty(
value = {"feign.httpclient.enabled"},
matchIfMissing = true
)
@Conditional({HttpClient5DisabledConditions.class})
protected static class HttpClientFeignConfiguration {
protected HttpClientFeignConfiguration() {
}
// ์๋ต
@Bean
@ConditionalOnMissingBean({Client.class})
public Client feignClient(HttpClient httpClient) {
return new ApacheHttpClient(httpClient); // ApacheHttpClient๋ก Client ๊ฐ์ฒด ์์ฑ!
}
}
@ConditionalOnClass({ApacheHttpClient.class})
: ApacheHttpClient ํด๋์ค ํ์ผ์ด ์์๋๋ง ์ค์ ํ์ผ ์๋@ConditionalOnProperty( value = {"feign.httpclient.enabled"}, matchIfMissing = true )
: ๊ฐ์ด false๊ฐ ์๋ ๊ฒฝ์ฐ ์ ์ธํ๊ณ ๋ชจ๋ ๊ฒฝ์ฐ์ @Configuration ์ค์ ํ์ผ ์ ์ฉ๋จ (feign.httpclient.enabled ์ค์ ๊ฐ ์์ด๋ ๋จ)@ConditionalOnMissingBean({Client.class})
: Client ํ์ ์ ๋น์ด ์๋ ๊ฒฝ์ฐ ๋น ์์ฑ- ๋น ๋ฅธ ๊ฒฐ๋ก : ์ ์ฉํ๋ ค๋ฉด, ApacheHttpClient ์์กด์ฑ ์ถ๊ฐ๋ง ํ๋ฉด ๋จ
์คํ
๊ทธ๋๋ ํน์ ๋ชฐ๋ผ์ ์คํ์ ์งํํ์ต๋๋ค ๐
1. ์์กด์ฑ ์ถ๊ฐ
// pom.xml
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
// application.yml
# ์๋ฌด์ค์ ๋ ํ์ง ์์
- ๊ฒฐ๊ณผ : ApacheHttpClient๋ก Client ์์ฑ ๋จ
2. ์์กด์ฑ ์ถ๊ฐ && feign.httpclient.enabled=false
// pom.xml
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
// application.yml
feign:
httpclient:
enabled: false
- ๊ฒฐ๊ณผ : ApacheHttpClient๋ก Client ์์ฑ ์๋จ
- ์ด์
- https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/condition/ConditionalOnProperty.html#matchIfMissing
- ๊ณต์ ๋ฌธ์ ๋ด ํ๋ฅผ ๋ณด๋ฉด havingValue ์ด๋ ธํ ์ด์ ์ ์๋ฌ๋ฉด(havingValue="") false๋ง ์๋๋ฉด ๋ชจ๋ yes ์ทจ๊ธ ๋๋๊ฑธ ์ ์ ์์
3. ์์กด์ฑ ์ถ๊ฐ && feign.httpclient.enabled=์๋ฌด๊ฐ์ด๋
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
// application.yml
feign:
httpclient:
enabled: true
--
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
// application.yml
feign:
httpclient:
enabled: 'hi'
- ๊ฒฐ๊ณผ : ApacheHttpClient๋ก Client ์์ฑ ๋จ
4. ์์กด์ฑ ์ถ๊ฐ && feign.httpclient.enabled=off
// pom.xml
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
// application.yml
feign:
httpclient:
enabled: off
- ๊ฒฐ๊ณผ : ApacheHttpClient๋ก Client ์์ฑ ์๋จ
- ์ด์
- boolean๊ฐ ๊ด๋ จํด์ off๊ฐ false์ ๊ฐ์ ๊ฐ์ผ๋ก ์ทจ๊ธ๋จ
- https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes
- YAML configuration can now use
on
oroff
for boolean types.
- https://perlpunk.github.io/yaml-test-schema/schemas.html
- https://youtrack.jetbrains.com/issue/IDEA-223980/Spring-Boot-on-or-off-can-be-used-as-boolean-values-in-application.yml-since-v.-2.2.0
- boolean๊ฐ ๊ด๋ จํด์ off๊ฐ false์ ๊ฐ์ ๊ฐ์ผ๋ก ์ทจ๊ธ๋จ
๊ฒฐ๋ก
- feign์์ http client๋ก apache http client๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด, ์์กด์ฑ ์ถ๊ฐ๋ง ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
- feign.httpclient.enable=true ์ฒ๋ฆฌ๋ ์๋ตํด๋ ๋ฉ๋๋ค
- @ConditionalOnProperty( value = {"feign.httpclient.enabled"}, matchIfMissing = true )
- feign.httpclient.enabled ๊ฐ์ false์ผ๋ก ๋ช ์ํ์ง ์๋๋ค๋ฉด ๋ชจ๋ ๊ฒฝ์ฐ์ client ๊ฐ์ฒด๊ฐ apache http client๋ก ์์ฑ๋๊ฒ ๋ฉ๋๋ค.
- feign.httpclient.enable=true ์ฒ๋ฆฌ๋ ์๋ตํด๋ ๋ฉ๋๋ค
- ๊ฐ์ธ์ ์ธ ํ๊ณ
- ์ด์ฒ๋ผ ๊ธ๋ง๋ค ์ค๋ช ์ด ๋ค๋ฅด๋ค๋ฉด.. ํผ๋์ ๋น ์ ธ ์ฐ์ฐํ ๋ง์๊ณผ ํจ๊ป ์ฝ๋๋ฅผ ๋ค ๊น๋ณด๊ฒ ๋๋๋ฐ์..
- ๊ธ์๋ ์์ฑํ์ง ์์์ง๋ง.. ์ด๋ฒ ๊ฒฝ์ฐ์๋ openfeign์ ์ฝ๋๊ฐ ๋ฏฟ๊ธฐ์ง ์์, ๋ ํผ๋ํ ๋ง์์ผ๋ก openfeign์ ์ฝ๋๋ฅผ ๋ก์ปฌ์ ๋ฐ์ ์ง์ ๊น๋ณด๊ธฐ๋ ํ์ต๋๋ค.
- @ConditionalOnProperty( value = {"feign.httpclient.enabled"}, matchIfMissing = true )
- ์ด ๋ถ๋ถ์์ havingValue๊ฐ true๋ก ์ ํ์ ธ ์์ง ์๋ ๋ถ๋ถ์ด ์ ์ด๋ ๊ฒ ๊ฐ๋ฐํ๊ฒ ๋๊ฑด์ง ์ดํด๊ฐ ์๋์ต๋๋ค.
- ํน์ ์ ๊ฐ ์ฐพ์๋ณด์ง ๋ชปํ ์์ญ์์ feign.httpclient.enabled ๊ฐ์ ๋ ํ์ธํด์ ์ฌ์ฉํ๋ ์์ญ์ด ์๋์ง ํ์ธํ๊ณ ์ถ์ด open feign ๊ฐ๋ฐ ๋น์ ์ปค๋ฐ ๋ด์ญ์ ํ์ธํด๋ณด๊ธฐ๋ ํ์ต๋๋ค. ์ ์ฒ๋ผ ๊ถ๊ธ์ฆํ์ ๋ถ๋ค์ด ์์ผ์ค๊น๋ด ์ฒจ๋ถํฉ๋๋ค.
- @ConditionalOnProperty( value = {"feign.httpclient.enabled"}, matchIfMissing = true )
- ์ด์ฒ๋ผ ๊ณ์ ์ฐ์ฐํ ๋ถ๋ถ์ด ์์ด, ์ ๋ง ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก ์ฐพ์๋ณด์๋๋ฐ์.. ๋ค๋ฅธ ๋ถ๋ค์ ์ด๋ฐ ํผ๋์ ๋น ์ง์ง ์๊ธธ ๋ฐ๋ผ๋ฉฐ ๊ธ์ ๋ง์นฉ๋๋ค!
๋ฐ์ํ