[MSA] Hystrix 사용해보기

0

MSA

목록 보기
1/10

동기 요청 예시

첫번째

  • Catalogs1 이라는 프로젝트가 있고, Customers1이라는 프로젝트가 있을 때

  • Catalogs의 Controller에서 service를 호출하는데, service에서 RestTemplate라이브러리를 주입하여 getForObject라는 대표 메서드를 통해 Customer1에 요청을 보냄.
    응답 결과가 Customer1에서 나옴, Customer1의 return값을 호출한 Catalogs에 보내준다.
  • 서버는 둘다 돌려야되고 postman에서는 http://localhost:8081/catalogs/customerinfo/{id}로 확인

서비스간 장애가 났을때 장애를 차단하는 방법

: Hystrix 사용해보기

-> advice와 비슷하다. getForObject를 호출하다가 문제가 생겼을 때 그 즉시 처리용 메서드(fallbackMethod)를 실행하라.

  • 사용자에게 문제를 알릴것인가? 정확한 메시지를 알릴 수 있겠지만, 간단하게 정상응답을 못합니다라고 return값으로 가공해서 보냄
    • 서비스역할을 하는 customer까지 가지 않고, endpoint역할을하는 catalog에서 보냄

두번째


Circuit Open 
* 요청이 다음단계로 넘어가지 않고 미리 반환하는 작업
* 기본설정은 
* 10초동안 20개이상의 @HystrixCommand메서드호출이 발생했을때,
* 50%이상의 호출에서 에러가 발생되면 자동 Circuit Open된다. 
-> 회로차단 -> 이 경우 수가 발생하면 그때부턴 더 메서드 호출하러 안감.
-> 그즉시 fallback해버림
*  Circuit Open되면 fallbackMethod로 처리
*  프로퍼티 : requestVolumeThreshold - @HystrixCommand메서드 호출건수(1)
*          errorThresholdPercentage - 에러발생확률(50)
  • 문제가 발생하면 getForObject를 완전히 호출안하는것은 아니고 내버려 두고 결과가 올때까지 기다리지 않고 에러 조건을 만족했을 경우 요청이 오면 작업을 요청은 하되, 그 즉시 fallBack메서드를 호출함(요청에 대한 응답을 계속 기다리지 않음)

Catalog 의 서비스

1) 어노테이션
	@Override
	@HystrixCommand(fallbackMethod = "getCustomerDetailFallback"
////	,commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="500") }
////	,commandProperties = {@HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="1"),
////					      @HystrixProperty(name="circuitBreaker.errorThresholdPercentage", value="50")}
//	      
	)
    
2) yml 사용
hystrix:
  command:
    default:    # command Key. use 'default' for global setting.
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 500   
            // 0.5초 내에 응답안오면 exception 보낼거야~
// 응답이 올 때 까지 기다리지 않고 이 시간이 지나면 바로 fallbackMethod 보냄

# metrics.rollingStats.timeInMilliseconds : 오류 감시 시간, 기본값 10초
# circuitBreaker.requestVolumeThreshold : 감시 시간 내 요청 수, 기본값 20
# circuitBreaker.errorThresholdPercentage : 요청 대비 오류율, 기본값 50  
         
      metrics: #1(60000)동안 최소 2회 호출 이상, 50% 이상 실패면 circuit open
        rollingStats: 
          timeInMilliseconds: 60000     
      circuitBreaker:
        requestVolumeThreshold: 2
        errorThresholdPercentage: 50

CustomerController

@RestController
@RequestMapping("/customers")
public class CustomerController {
	int cnt=0;
	@GetMapping("/{customerId}")
	public String getCustomerDetail(@PathVariable String customerId) {


// 1) timeout test : 기본 timeout값은 1000 (1초)
		long milli = 3*1000; // 3초가 지난 다음에 응답하라
		try {
			Thread.sleep(milli);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("request customerId :" + customerId);
		return "[Customer id = " + customerId + " at " + System.currentTimeMillis() + "]";
//2) exception test
//		throw new RuntimeException("I/O Exception");
//3)circuit open test
//		System.out.println("처리횟수:" + (++cnt));
//		throw new RuntimeException("I/O Exception");
	}

↳ CustomerController에서 3초 지난다음에 응답하라고 했고, catalog에서는 0.5초만 기다린다고 해서 무조건 exception발생할것임.

  • 지연되고 있습니다 라는 메시지를 굳이 볼 필요가 있는가?
    조회 작업할 때는 의미가 있다. 그러나 추가작업을 할 때는 사용자에게 메시지를 보낼 필요가 있나? -> 동기처리가 좋은 방법이 아니다.
    기다리는 것은 Select와 같은 조회작업일 때만.

1) timeOut : hystrixException보냄
2) 서킷브레이커가 오픈될 때 : RuntimeException을 발생시키면 internalServerError가 발생함 -> 사용자에게 던져주는 것이 아니라 고객 정보 조회가 지연된다는 fallback메서드로 가공돼서 보내짐
-> 클라이언트에 500번으로 그대로 노출하지 않고 endpoint로 지정해놓은 catalog에서 메시지를 가공해서 보내는것이다.
-> fallback메서드 안지정해놓으면 그 에러 그대로 노출함!

  • 서킷브레이커로 회로를 차단했기 때문에 지정확률 이 넘어가면 fallback메서드로 바로 넘어가는 것이다~ 그래서 사용하는 것.
    -> 계속 지연되면 먹통이 계속 유지되므로 지연상황을 빨리! 끊어줘야함
    -> 그러기 위해서 서킷브레이커를 설정해주는 것이다.
  • Exception이 발생하는 것을 클라이언트에게 보내주지말고 확률을 계산해서 그 즉시 fallback메서드로 빠질 수 있도록 방법을 구상해라~
  • fallback말고도 서킷브레이커가 열릴 수 있는 상황이 현업에서 굉장히 많다.
profile
백엔드를 공부하고 있습니다.

0개의 댓글