2022-05-10-TIL
2022-05-10-TIL
Today I learned
Spring Boot Admin
Health Check 처럼 API가 살아있는지를 전체적으로 모니터링 할 수 있는 화면을 제공해주는 웹 페이지이다. 화면에 보여지는 정보는 Spring Boot Actuator를 통해 받은 정보이다.
구조는 서버와 클라이언트로 나뉜다. Admin 서버는 별도의 Spring Boot 애플리케이션으로 띄우고, 모니터링 대상 애플리케이션은 클라이언트 라이브러리로 자신을 서버에 등록하거나 Spring Cloud Discovery(Eureka 등)를 통해 발견된다. 서버는 각 애플리케이션의 Actuator 엔드포인트(/actuator/health, /actuator/metrics, /actuator/loggers 등)를 호출해서 상태, 메트릭, 로그 레벨, 환경 정보를 한 화면에 모아 보여 준다.
주의할 점은 Actuator가 기본으로 HTTP에 노출하는 엔드포인트가 health 하나뿐이라는 것이다. Admin 화면에 다양한 정보가 보이게 하려면 management.endpoints.web.exposure.include로 필요한 엔드포인트를 열어야 하고, 그만큼 민감한 정보가 노출되므로 Spring Security나 네트워크 수준에서 접근을 막아 두어야 한다(Spring Boot Actuator 문서).
- https://joomn11.tistory.com/68
- https://codecentric.github.io/spring-boot-admin/current/
- https://www.baeldung.com/spring-boot-admin
- https://docs.spring.io/spring-cloud-dataflow-server-cloudfoundry/docs/1.2.1.BUILD-SNAPSHOT/reference/html/configuration-monitoring-management.html
- https://reflectoring.io/spring-boot-health-check/
데이터 모델링: Supertype과 Subtype
슈퍼타입/서브타입은 여러 엔티티가 공통 속성을 공유하면서 각자 고유한 속성도 갖는 상황을 표현하는 모델링 기법이다. 예를 들어 고객이라는 슈퍼타입 아래에 개인고객, 법인고객 서브타입을 둔다. 공통 속성(고객번호, 연락처)은 슈퍼타입에, 고유 속성(주민번호, 사업자번호)은 서브타입에 둔다. EER(Enhanced Entity-Relationship) 모델에서는 이를 특수화(specialization)와 일반화(generalization)로 설명하고, 서브타입끼리 겹칠 수 있는지(disjoint/overlapping), 모든 슈퍼타입 인스턴스가 반드시 서브타입에 속하는지(total/partial)를 제약으로 표시한다.
물리 모델로 옮길 때는 대표적으로 세 가지 선택지가 있다.
- 하나의 테이블로 통합: 구분 컬럼으로 타입을 나눈다. 조인이 없지만 서브타입 고유 컬럼은 NULL이 많아진다.
- 서브타입마다 테이블: 공통 컬럼이 테이블마다 중복된다. 전체 조회에는 UNION이 필요하다.
- 슈퍼타입과 서브타입을 각각 테이블로: 정규화된 형태다. 상세 조회에 조인이 필요하다.
JPA의 상속 매핑 전략(SINGLE_TABLE, TABLE_PER_CLASS, JOINED)이 정확히 이 세 가지에 대응한다.
- https://learndatamodeling.com/blog/supertype-and-subtype/
- https://books.google.co.kr/books?id=ydHrVBkk3cYC&pg=PA24&lpg=PA24&dq=db+super+type&source=bl&ots=WIQrDQOPak&sig=ACfU3U1bgheyXBA8njw12cTHrDQAuxHxWQ&hl=en&sa=X&ved=2ahUKEwiX49G5ndb3AhWZplYBHTT3COAQ6AF6BAgkEAM#v=onepage&q=supertype&f=false
- https://vertabelo.com/blog/crow-s-foot-notation/
- https://en.wikipedia.org/wiki/Enhanced_entity%E2%80%93relationship_model
- https://velog.io/@cco2416/Database%EC%A0%95%EB%A6%AC3
순환 관계(Recursive Relationship)
순환 관계는 하나의 엔티티가 자기 자신과 관계를 맺는 경우다. 직원 테이블에서 “상사”도 직원이고, 카테고리 테이블에서 “상위 카테고리”도 카테고리인 경우가 대표적이다. 물리 모델에서는 같은 테이블의 PK를 참조하는 FK 컬럼(manager_id, parent_id)으로 구현한다. 1:N 순환은 자기 참조 FK 하나로 충분하고, N:M 순환(예: 부품과 그 부품을 구성하는 하위 부품)은 별도의 연결 테이블이 필요하다. 계층을 끝까지 따라가는 조회는 재귀 CTE(WITH RECURSIVE)로 작성한다.
- https://www.geeksforgeeks.org/recursive-relationships-in-er-diagrams/
- https://web.csulb.edu/colleges/coe/cecs/dbdesign/dbdesign.php?page=recursive.php
배타적 관계(Arc)
Arc는 ERD에서 한 엔티티가 여러 엔티티 중 오직 하나와만 관계를 맺는다는 것을 호(arc)로 묶어 표시하는 표기다. 예를 들어 결제가 카드결제 정보 또는 계좌이체 정보 중 하나와만 연결되는 경우다. 구현 방법은 FK 컬럼을 대상마다 두고 하나만 채우게 하는 방식과, 구분 컬럼과 하나의 대상 ID 컬럼을 두는 방식이 있다. 후자는 DB가 FK 제약을 걸 수 없어서 무결성을 애플리케이션이 지켜야 한다는 단점이 있다.
- https://vnthf.github.io/blog/DB-%EB%AA%A8%EB%8D%B8%EB%A7%81%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC/
- http://wiki.gurubee.net/pages/viewpage.action?pageId=1507663
e.printStackTrace()를 쓰지 말아야 하는 이유
e.printStackTrace()는 스택 트레이스를 표준 에러(System.err)로 바로 출력한다. 링크의 답변들이 지적하는 문제는 다음과 같다.
- 로깅 프레임워크를 거치지 않으므로 로그 레벨, 포맷, 출력 대상(파일, 수집기) 설정이 적용되지 않는다.
- 서버 환경에서는 표준 에러가 어디로 가는지 보장되지 않아 정보가 유실되거나, 다른 로그와 시간 순서가 섞인다.
- 예외를 출력만 하고 삼키면 호출자는 실패를 알 수 없다.
대신 log.error("주문 처리 실패 orderId={}", orderId, e)처럼 로거에 예외 객체를 마지막 인자로 넘기면 스택 트레이스가 같은 로그 이벤트에 함께 기록된다.
- https://stackoverflow.com/questions/7469316/why-is-exception-printstacktrace-considered-bad-practice
댓글
아직 댓글이 없습니다