[Tistory] 23.08.26

원글 페이지 : 바로가기

앞으로는 티스토리에 TIL을 올리려고 한다! 아자아자 화이팅~ 1. ‘실행중인 도커 컨테이너의 포트포워딩 변경`에 대한 글을 썼다. 레벨3 막바지에 로그 모니터링을 도입하는 과정에서 필요했던 내용! 당시에 이미 구축한 젠킨스 파이프라인을 다시 처음부터 만들어야할까봐 엄청 긴장상태로 진행했던 기억이 난다.. 근데 도커 너무 재밌어보인다. 레벨4 때 도커를 좀 더 본격적으로 사용해볼 수 있으면 좋겠다. https://velog.io/@hanueleee/Docker-%EC%8B%A4%ED%96%89%EC%A4%91%EC%9D%B8-%EB%8F%84%EC%BB%A4-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%9D%98-%ED%8F%AC%ED%8A%B8%ED%8F%AC%EC%9B%8C%EB%94%A9-%EB%B3%80%EA%B2%BD [Docker] 실행중인 도커 컨테이너의 포트포워딩 변경 Intro 우테코에서 진행중인 팀 프로젝트에 로그 모니터링 시스템을 도입하기 위해, 현재 작동중인 젠킨스 컨테이너의 port를 바꿔야 하는 상황이 생겼다. 우테코에서 제공하는 ec2는 원래 8080포트 velog.io 2. Spring의 Session에 대해 꽤나 깊이 알아보는 글을 썼다. 펀잇은 로그인 방식으로 ‘세션’을 사용했다. 내가 로그인을 직접 구현하지는 않았지만, 우리팀 레전드 사건 2가지 중 하나인 로그인 사태(로그인 이슈로 팀원 7명 중 5명이 9시간동안 디버깅) 때 함께 무한 핫픽스를 하면서 Spring의 Session에 대해 접해볼 수 있었다. 당시에 intro만 적어둔 글이 있길래 오늘 날잡고 싹 정리해보았다! 꽤나 뿌듯하다 😋 https://velog.io/@hanueleee/Spring-Spring%EC%97%90%EC%84%9C-Session-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0 [Spring] Spring에서 Session 사용하기 Intro HTTP는 connectionless하고 stateless하다 HTTP의 특징에는 connectionless와 stateless가 있다. connectionless (무연결성) : 클라이언트가 요청을 한 후 응답을 받고나면 연결을 끊어버린다. statel velog.io 3. 영한님 스프링 DB 1편의 [섹션4 : 스프링과 문제 해결 -트랜잭션] 강의 자료를 읽었다. 📍 트랜잭션 매니저 스프링이 제공하는 트랜잭션 매니저는 크게 2가지 역할을 한다. 1) 트랜잭션 추상화 각각의 데이터 접근 기술들은 트랜잭션을 처리하는 방식에 차이가 있다. 예를 들어 JDBC 기술과 JPA 기술은 트랜잭션을 사용하는 코드 자체가 다르다. 스프링은 이런 문제를 해결하기 위해`PlatformTransactionManger`라는 인터페이스를 사용해 트랜잭션 사용을 추상화해뒀다. 2) 트랜잭션 동기화 트랜잭션을 유지하기 위해서는 트랜잭션 시작부터 끝까지 같은 connection을 유지해야 한다. 스프링이 제공하는 트랜잭션 동기화 매니저는 ThreadLocal을 사용해서 커넥션을 동기화해준다 (-> 멀티쓰레드 상황에 안전하게 커넥션을 동기화 할 수 있다) 따라서 커넥션이 필요하면 트랜잭션 동기화 매니저를 통해 커넥션을 획득하면 된다. 📍 트랜잭션 템플릿 트랜잭션을 적용하기 위해서는 ‘트랜잭션을 시작하고, 비즈니스 로직을 실행하고, 성공하면 커밋하고, 예외가 발생해서 실패하면 롤백한다.’ 라는 동일한 구조가 반복된다. 달라지는 부분은 비즈니스 로직 뿐이다. 이럴 때 템플릿 콜백 패턴을 활용하면 이런 반복 문제를 깔끔하게 해결할 수 있다. 📍 트랜잭션 AOP @Transactional을 사용하면 스프링이 AOP를 이용해 트랜잭션을 편리하게 처리해준다. 스프링의 트랜잭션 AOP는 이 애노테이션을 인식해서 트랜잭션을 처리하는 프록시를 적용해준다. 4. 영한님 스프링 DB 1편의 [섹션 5 : 자바 예외 이해] 강의를 들었다. 오랜만에 보는 체크 언체크 예외 계층도 예외는 폭탄 돌리기와 같다. 잡아서 처리하거나(try-catch), 처리할 수 없으면 밖으로 던져야한다(throws). 📍 체크 예외 vs 언체크 예외 체크 예외 : 예외를 잡아서 처리하지 않으면 항상 throws 에 던지는 예외를 선언해야 한다. 언체크 예외 (런타임 예외) : 예외를 잡아서 처리하지 않아도 throws 를 생략할 수 있다. 📍 언제 체크 예외를 사용하고 언제 언체크(런타임) 예외를 사용하면 좋을까? 기본적으로 언체크(런타임) 예외를 사용하자. 체크 예외는 비즈니스 로직상 의도적으로 던지는 예외에만 사용하자. (ex. 계좌 이체 실패 예외) 📍 체크 예외를 최대한 사용하지 않아야 하는 이유 처리할 수 있는 체크 예외라면 서비스나 컨트롤러에서 처리하겠지만, 데이터베이스나 네트워크 통신처럼 시스템 레벨에서 올라온 예외들은 대부분 복구가 불가능하다. 그리고 실무에서 발생하는 대부분의 예외들은 이런 시스템 예외들이다. 문제는 이런 경우에 체크 예외를 사용하면 아래에서 올라온 복구 불가능한 예외를 서비스, 컨트롤러 같은 각각의 클래스가 모두 알고 있어야 한다. 그래서 불필요한 의존관계 문제가 발생하게 된다. 📍 로그를 출력할 때 마지막 파라미터에 예외를 넣어주면 로그에 스택 트레이스를 출력할 수 있다. log.info(“예외 처리, message={}”, e.getMessage(), e); log.info(“예외 처리”, e); 📍 예외를 전환할 때는 꼭 기존 예외를 포함하자 기존 예외를 포함해야 기존에 발생한 예외의 스택 트레이스를 확인할 수 있다 (Caused by 부분) 이를 위해서는 Custom exception 만들 때 Throwable cause를 파라미터로 받는 생성자도 열어야한다! (예외는 원인이 되는 예외를 내부에 포함할 수 있다) 5. 영한님 스프링 DB 1편의 [섹션 6 : 스프링과 문제 해결 – 예외 처리, 반복] 강의의 앞 부분을 들었다. (나머지는 내일 들을 예정!) 서비스 계층은 가급적 특정 구현 기술에 의존하지 않고, 순수하게 유지하는 것이 좋다. 그러려면 예외에 대한 의존도 함께 해결해야한다. 예를 들어서 서비스가 처리할 수 없는 SQLException 에 대한 의존을 제거하려면 어떻게 해야할까? 서비스가 처리할 수 없으므로 리포지토리에서 SQLException 체크 예외를 런타임 예외로 전환해서 서비스 계층에 던지자. 이렇게 하면 서비스 계층이 해당 예외를 무시할 수 있기 때문에, 특정 구현 기술에 의존하는 부분을 제거하고 서비스 계층을 순수하게 유지할 수 있다. 📍 예외 누수 문제 해결 (throws SQLException 제거)을 위해 체크 예외를 언체크 예외로 전환할 수 있다. catch (SQLException e) {
throw new MyDbException(e);
} (잘 보면 생성자를 통해서 기존 예외를 포함하고 있는 것을 확인할 수 있다. 예외는 원인이 되는 예외를 내부에 포함할 수 있는데, 꼭 이렇게 작성해야 한다. 그래야 예외를 출력했을 때 원인이 되는 기존 예외도 함께 확인할 수 있다. MyDbException 이 내부에 SQLException 을 포함하고 있다고 이해하면 된다. 예외를 출력했을 때 스택 트레이스를 통해 둘다 확인할 수 있다.) 📍 하지만 위 방식대로 모든 SQLException을 MyDbException으로 바꿔서 던지면 예외를 구분할 수 없다. 만약 특정 상황에는 예외를 잡아서 복구하고 싶으면 예외를 어떻게 구분해서 처리할 수 있을까? 특정 예외는 복구하고 싶다면? SQL ErrorCode로 데이터베이스에 어떤 오류가 있는지 확인할 수 있다. catch (SQLException e) {
if (e.getErrorCode() == 23505) { // h2 db의 경우
throw new MyDuplicateKeyException(e);
}
throw new MyDbException(e);
} 6. 기타 – Thread Local 쓰레드 로컬을 사용하면 각각의 쓰레드마다 별도의 저장소가 부여된다. 따라서 해당 쓰레드만 해당 데이터에 접근할 수 있다. – @TestConfiguration : 테스트 안에서 내부 설정 클래스를 만들어서 사용하면서 이 에노테이션을 붙이면, 스프링 부트가 자동으로 만들어주는 빈들에 추가로 필요한 스프링 빈들을 등록하고 테스트를 수행할 수 있다. – CGLIB : 자바의 클래스 코드를 동적으로 생성하고 수정하는 라이브러리로, 클래스의 상속을 통해 프록시를 생성하거나 클래스의 동작을 확장하는 데 사용된다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다