MSA 환경에서 공통 에러코드 사용하기 - Config Server

0

back-end

목록 보기
9/18

코드
config server: https://github.com/khc41/config-server
config client: https://github.com/khc41/config-client

MSA 구조의 프로젝트를 시작하면서 고민이 생겼다.

에러코드가 프로젝트별로 중복되는데 어떻게 공통으로 처리해줄 것인가?

데이터베이스에 에러코드를 저장해서 도메인 프로젝트별로 조회하는 방법은 에러가 발생할 때마다 디비에 접근해야 하므로 성능이 안좋을 것 같다고 생각했다.

이 방법에 캐시를 더해서 사용하는 방법도 있지만, 그렇게 되면 에러코드가 바뀔때마다 바로 대응이 안된다는 단점이 있었고, 캐시를 효율적으로 사용하기 힘들 것 같았다.

그래서 고안했던 방법이 바로 Config서버에 property 형식으로 에러코드를 저장하고, 
각 도메인 프로젝트에서 시작할때, 일정 주기별로 이 코드를 가져와서 사용하면 괜찮지 않을까..?

스프링에서 제공하는 기능중에 @ConfigurationProperties라는 어노테이션이 있다.

이 어노테이션을 이용해 property의 값을 읽어와 hashmap 형태로 만들면, 소스코드에서 사용할 때에 성능상의 이슈 없이 에러코드를 불러올 수 있을 것이라고 생각했다.

구현 과정

먼저 사용할 에러 코드와 그것을 가지고 있을 클래스를 정의한다.

@Getter
@Setter
@ToString
public class ErrorCode {
    private Integer code;
    private String value;
}
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "error.codemap")
public class ErrorCodeManager {
    public Map<String, ErrorCode> common = new HashMap<>();
    public Map<String, ErrorCode> shop = new HashMap<>();
}

ErrorCodeManager를 사용해 공통으로 사용하는 에러코드, shop이라는 도메인에서 사용하는 에러코드를 불러올 것이다.
자료형이 Map<String, ErrorCode>인 이유는 Map형태의 자료구조에서 String으로 식별자를 두고 ErrorCode를 가져오는 방식으로 채택했기 때문이다.

이렇게 세팅하면 다음의 Config Server의 Property에서 HashMap형태로 읽어올 수 있게 된다.

error:
  codemap:
    common:
      C401:
        code: 401
        value: LOGIN ERROR
      C500:
        code: 500
        value: INTERNAL SERVER ERROR
    shop:
      S400:
        code: 400
        value: 상품등록 실패
      

ErrorCodeManager에 각각의 HashMap에 에러코드가 담기게 되고 실제로 테스트 코드로 출력해보면 다음과 같이 저장된 것을 확인할 수 있다.

실행 테스트 코드

Map<String, ErrorCode> common = errorCodeManager.common;
for (String key : common.keySet()) {
     log.info("key = {}, value = {}", key, common.get(key));
}
Map<String, ErrorCode> shop = errorCodeManager.shop;
for (String key : shop.keySet()) {
     log.info("key = {}, value = {}", key, shop.get(key));
}

실행 테스트 결과

실제 사용

구현이 완료되고 실제 사용은 어떻게 하냐?
HttpStatus의 resolve를 사용하면 해당 HttpStatus를 가져올 수 있다.

응답할 때 해당 map에서 상황에 맞는 코드 조회 후, ResponseEntity로 응답해주면 된다.

 ErrorCode errorCode = errorCodeManager.common.get("C401");
 return new ResponseEntity<>(errorCode.getValue(), HttpStatus.resolve(errorCode.getCode()));

null 체크는 해주길 바란다.
이렇게 응답하면, 상황에 맞는 메시지와 에러를 client에 응답해줄 수 있다.

마무리

일단, msa환경에서 여러 프로젝트에서 사용하는 error code가 중복될 수도 있고, 한곳에 있으면 관리하기 편하기 때문에 이같은 방법을 고안해봤다.
spring cloud의 config server를 사용하면 에러코드 변경 시에도 편하게 대응할 수 있고, map을 사용해서 error code를 찾을 때의 성능도 괜찮을 것이라 생각했다.

하지만, 이 방법보다 더 좋은 방법들도 많을 것이다.
더 좋은 방법이 있으면 다시 글로 공유할 예정이다..
-끝-

0개의 댓글