2022-02-11-TIL
2022-02-11-TIL
Today I Learned
Java Logging
어느 부분에 로그를 남기는 것이 좋을까? 주로 예외나 에러가 발생할만한 곳, 크리티컬한 곳, 입출력을 받는 곳 등이 있을 것이다.
링크된 글들이 공통으로 권하는 원칙은 다음과 같다.
- 구현체에 직접 의존하지 않고 SLF4J 같은 로깅 퍼사드를 쓴다. Spring Boot는 기본으로 SLF4J와 Logback을 쓴다.
- 레벨을 의도에 맞게 쓴다.
ERROR는 즉시 확인이 필요한 실패,WARN은 당장 문제는 아니지만 살펴볼 상황,INFO는 주요 비즈니스 흐름,DEBUG는 개발 중 상세 정보다. - 메시지에 맥락을 담는다. “실패”만 남기지 말고 어떤 요청(주문 ID, 사용자 ID)에서 무엇이 실패했는지 적고, 예외는 메시지만이 아니라 예외 객체를 넘겨 스택 트레이스를 남긴다.
- 문자열 결합 대신
log.info("order {} paid", orderId)처럼 자리표시자를 쓴다. - 비밀번호, 토큰, 개인정보는 로그에 남기지 않는다.
로그를 수집하고 검색할 계획이라면 JSON 같은 구조화된 형식이 유리하다.
- https://sematext.com/blog/java-logging-best-practices/
- https://coralogix.com/blog/spring-boot-logging-best-practices-guide/
- https://huisam.tistory.com/entry/springlogging
Swagger 적용
Springfox Swagger를 Spring 프로젝트에 적용하는 방법과, 자주 헷갈리는 두 애너테이션의 차이다. @ApiParam은 컨트롤러 메서드의 파라미터(쿼리 파라미터, 경로 변수)에 설명을 붙이고, @ApiModelProperty는 요청이나 응답 본문으로 쓰이는 모델 클래스의 필드에 설명과 예시 값을 붙인다. 즉 하나는 엔드포인트 쪽, 하나는 데이터 모델 쪽 문서화다.
- https://hyeran-story.tistory.com/73
- https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty
AWS 배스천 호스트
배스천 호스트는 외부에서 접근할 수 없는 프라이빗 서브넷의 인스턴스에 접속하기 위해 퍼블릭 서브넷에 두는 관문 서버다. AWS Quick Start의 Linux 배스천 호스트 아키텍처는 배스천을 퍼블릭 서브넷에 두고, 관리자는 배스천에 SSH로 접속한 뒤 그곳에서 프라이빗 인스턴스로 다시 접속하는 구성을 제공한다. 프라이빗 인스턴스의 보안 그룹은 배스천에서 오는 SSH만 허용하고, 배스천 자체도 허용된 IP에서만 접속하게 제한해 공격 면을 한곳으로 줄인다.
- https://aws.amazon.com/ko/quickstart/architecture/linux-bastion/
- https://aws-quickstart.github.io/quickstart-linux-bastion/
MyBatis 트랜잭션 처리
MyBatis-Spring을 쓰면 트랜잭션을 MyBatis가 아니라 Spring이 관리한다. DataSourceTransactionManager를 등록하고 서비스 메서드에 @Transactional을 붙이면, 그 안에서 실행되는 여러 매퍼 호출이 같은 커넥션과 트랜잭션을 공유하고, 런타임 예외가 나면 함께 롤백된다. MyBatis-Spring 문서도 Spring의 트랜잭션 관리에 참여하는 방식을 기본으로 설명한다.
- https://codevang.tistory.com/264
- https://e2e2e2.tistory.com/12
for vs forEach
향상된 for문(for (T t : list))은 내부적으로 Iterator를 쓰고, 인덱스 for문은 get(i)를 호출한다. ArrayList에서는 둘의 차이가 거의 없지만, LinkedList에서 get(i)는 매번 처음부터 따라가므로 인덱스 for문이 전체 O(n²)이 된다. 그래서 컬렉션을 순회할 때는 향상된 for문이나 forEach()가 무난하다. Java 8의 Iterable.forEach()는 람다로 간결하게 쓸 수 있지만, 람다 안에서는 break, continue를 쓸 수 없고 바깥의 지역 변수를 바꿀 수 없다.
- https://stackoverflow.com/questions/9226483/java-loop-efficiency-for-vs-foreach
- https://siyoon210.tistory.com/99
RabbitMQ Tutorial
RabbitMQ 공식 튜토리얼의 첫 단계는 생산자가 큐에 메시지를 보내고 소비자가 받는 가장 단순한 구조를 Spring AMQP로 구현한다. RabbitTemplate.convertAndSend()로 보내고, @RabbitListener(queues = "hello")를 붙인 메서드가 메시지를 받는다. 이후 단계에서 작업 큐(여러 소비자에게 분배), 발행/구독(fanout exchange), 라우팅(direct exchange), 토픽(topic exchange)으로 확장된다. 나머지 링크는 설치 방법과 Spring Boot 연동 예제다.
- https://kimseunghyun76.tistory.com/423
- https://psychoria.tistory.com/550
- https://www.rabbitmq.com/tutorials/tutorial-one-spring-amqp.html
- https://yoonwould.tistory.com/157
- https://co-de.tistory.com/9
- https://colinch4.github.io/2020-12-03/README.rabbitmq-python/
- https://velog.io/@hellozin/Spring-Boot%EC%99%80-RabbitMQ-%EC%B4%88%EA%B0%84%EB%8B%A8-%EC%84%A4%EB%AA%85%EC%84%9C
댓글
아직 댓글이 없습니다