Interface 선언을 통해 자동으로 Http Client를 생성
기존 RestTemplate은 concreate 클래스라 테스트가 어려움
관심사 분리
- 서비스의 관심: 다른 리소스, 외부 서비스 호출과 리턴값
- 관심x : 어떤 URL, 어떻게 파싱할 것인가
참조하면 좋은 사이트
우형 기술 블로그
https://woowabros.github.io/experience/2019/05/29/feign.html
공식 문서
실습
1. 의존성
ext['springCloudVersion'] = 'Finchley.SR2'
...
dependencies {
compile('org.springframework.cloud:spring-cloud-starter-openfeign') // To use Feign
...
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
2. 설정
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class DisplayApplication {
public static void main(String[] args) {
SpringApplication.run(DisplayApplication.class);
}
}
3. FeignClient 인터페이스 구현
// @FeignClient(name = "product", url = "http://localhost:8082/") // 유레카 미 사용시
@FeignClient(name = "product")
public interface FeignProductRemoteService {
@RequestMapping(path = "/products/{productId}")
String getProductInfo(@PathVariable("productId") String productId);
}
4. 인터페이스 사용
@RestController
@RequestMapping(path = "/displays")
public class DisplayController {
private final ProductRemoteService productRemoteService;
private final FeignProductRemoteService feignProductRemoteService;
public DisplayController(ProductRemoteService productRemoteService,
FeignProductRemoteService feignProductRemoteService) {
this.productRemoteService = productRemoteService;
this.feignProductRemoteService = feignProductRemoteService;
}
@GetMapping(path = "/{displayId}")
public String getDisplayDetail(@PathVariable String displayId) {
String productInfo = getProductInfo();
return String.format("[display id = %s at %s %s ]", displayId, System.currentTimeMillis(), productInfo);
}
private String getProductInfo() {
return feignProductRemoteService.getProductInfo("12345");
}
}
5. hystrix 설정을 - Feign 의 모든 요청에 hystrix가 적용됨
feign:
hystrix:
enabled: true
6-1. fallback
@FeignClient(name = "product", fallback = FeignProductRemoteServiceFallbackImpl.class)
public interface FeignProductRemoteService {
@RequestMapping(path = "/products/{productId}")
String getProductInfo(@PathVariable("productId") String productId);
}
@Component
public class FeignProductRemoteServiceFallbackImpl implements FeignProductRemoteService {
@Override
public String getProductInfo(String productId) {
return "[ this product is sold out ]";
}
}
6-2. FallbackFactory
@Component
public class FeignProductRemoteServiceFallbackFactory implements FallbackFactory<FeignProductRemoteService> {
@Override
public FeignProductRemoteService create(Throwable cause) {
System.out.println("t = " + cause);
return productId -> "[ this product is sold out ]";
}
}
@FeignClient(name = "product", fallbackFactory = FeignProductRemoteServiceFallbackFactory.class)
public interface FeignProductRemoteService {
@RequestMapping(path = "/products/{productId}")
String getProductInfo(@PathVariable("productId") String productId);
}
7. Feign의 hystrix 설정
hystrix:
command:
FeignProductRemoteService#getProductInfo(String):
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 # default 1,000ms
circuitBreaker:
requestVolumeThreshold: 1 # Minimum number of request to calculate circuit breaker's health. default 20
errorThresholdPercentage: 50 # Error percentage to open circuit. default 50
'Spring Cloud' 카테고리의 다른 글
6. Spring Cloud Config (0) | 2021.06.20 |
---|---|
5. zuul - [Spring Cloud를 활용한 MSA 기초 온라인 강의 실습] (0) | 2021.06.18 |
3. Eureka - [Spring Cloud를 활용한 MSA 기초 온라인 강의 실습] (0) | 2021.06.16 |
2. Ribbon - [Spring Cloud를 활용한 MSA 기초 온라인 강의 실습] (0) | 2021.06.15 |
1. hystrix - [Spring Cloud를 활용한 MSA 기초 온라인 강의 실습] (0) | 2021.06.13 |