2월은 이직준비로 여러가지 바빴다. 지난번 회사에서는 이직에 대한 생각을 동료들과 공유하지 않았는데 이곳에서는(현재는 전회사가 된) 주변의 동료들이 한마음을 가지고 있다보니 이직에 대한 생각을 동료들에게 공유하게 되었고 서로 응원해주는 상황이 되었다. 회사에 대한 정보도 공유하고 이력서, 면접 등 각자 부족한 부분을 지적해주고 조언해 주는 등 마치 가족같이 서로를 위해주는 모습들을 보면서 이런 동료들을 또 어디서 만날 수 있을까 싶었다.

지원한 회사 중 한 곳이 결정 나면서 2월 19일 부로 전 직장에서 퇴사를 하였다. 회사에 대한 미련은 없지만 정든 동료들과 작별을 고하니 발길이 쉽게 떨어지지 않았다. 짧지만 굵었던 클래스101 안녕.

퇴사 후 새로운 회사로 입사하기까지 2주의 시간이 남아 있었다. 그동안 아직 다른 회사의 채용절차가 조금 남아있긴 하지만 자주 찾아뵙지 못하는 죄송함도 만회할 겸 부모님 일도 도와드릴겸 일주일 정도 시골 본가에 갔다. 그리고 정말 오랜만에 부산에서 친구들을 만났고 나머지 기간동안 서울에서 직장 생활로 못다한 일들을 하였다.

2월은 그래서 이런저런 핑계로 코드를 많이보질 못했다. 맞다. 핑계다. 지쳐서 그런지 컴퓨터를 켰을 때, 코드를 봤을 때 설렘이 없다. 이 설레임을 찾기 위해 뭘해야 할지 고민해봐야 겠다.

아래는 2월동안 내가 배우거나 겪었던 이슈에 대해서 정리한 내용이다.

JPA 도메인 이벤트 처리

Spring Data JPA에서는 DDD에서 도메인 이벤트를 처리하기 위한 메커니즘을 제공해준다. Publishing Events from Aggregate Roots 도메인 이벤트를 사용하면 기능을 확장할 때 해당 도메인의 이벤트를 구독하는 리스너를 추가하는 방식으로 구현하면 되기 때문에 유연성이 아주 뛰어나게 설계를 할 수 있다. (물론 도메인 이벤트를 잘 정의하는게 쉽지는 않다.) 다만 해당 기능에서 아쉬운 부분이 2가지가 있다. 첫번째, 도메인 이벤트를 쌓기 위해서는 반드시 Repository의 save함수를 사용해야 한다. Spring Data JPA를 사용하다보면 새로운 Entity를 생성시에는 save함수를 사용하지만 수정시에는 dirty checking을 많이 사용한다. 테스트 해보니 dirty checking에서는 도메인 이벤트가 쌓이지 않아서 무조건 save함수를 써야 하는 불편함이 있다. 두번째, 가시성이 떨어진다. 이부분은 의견이 갈릴 수 있다고 생각한다. 명시적으로 이벤트를 발행한다는 코드가 서비스 코드에 존재하지 않기 때문에 DomainEvents가 선언되어 있다는 것을 모르는 개발자라면 코드를 추적하는데 애를 먹을 수 있다. 추상화가 되어 코드를 잘 숨기는 것도 좋지만 이런 학습곡선이 오르는 것 또한 경계해야 할 것이라 생각이 든다.

부하 테스트 자료

우연히 실전 서버 부하 테스트라는 자료를 보게 되었다. 여기서 JMeter를 다루는 내용이 나오는데 JMeter 튜토리얼을 다루는 링크를 공유해 주어서 보게 되었는데 유용할 거 같아서 적어본다. 처음 JMeter 사용할 때 블로그를 참고하면서 만들어 보곤 했는데 튜토리얼이 있으면 처음 배우는 사람들에게 참 도움이 많이 될것이라 생각된다.

JPA Transient in kotlin

kotlin에서 @Transient 사용하면 해당 프로퍼티에 null이 세팅되는 이슈가 있다. null이 세팅되지 않도록 하는 방법으로는 @PostLoad를 사용하는 것이다.

class KitEntity {
    @Transient
    lateinit var events: MutableList<String>

    //...

    @PostLoad
    private fun init() {
        events = mutableListOf()
    }
}

기술 공부

면접하면서 힘든부분 중 하나가 평소에는 크게 신경쓰지 않거나 사용하지 않는 기술용어나 지식을 익혀야 한다는 것이다. 물론 내부원리를 다 이해하고 공부해두면 좋다고 생각한다. 하지만 실무를 하다보면 이러한 부분은 뒷전으로 밀리기 쉽다. 비지니스로직에 집중을 하다보면 어쩔 수 없는 부분이기도 하다. 동료가 면접 때 SpringBoot Application이 동작하는 방식에 대해 질문을 받았다고 하는데 이 질문을 만약 내가 받았다면 아마 대답하지 못했을 것이다. 평소에라도 기술질문들 만들어 공부하는 습관을 가지도록 해야겠다.

Spring Async

Spring의 Async에 대한 좋은 글이 있어서 적어둔다. 자바의 병렬 프로그래밍에 대해서 깊이가 부족했는데 조금이나마 이해력을 높이는데 도움이 되었다.

에디님의 블로그

카프카 공부 페이지

메시징 서비스에 대한 필요성은 전전회사때 부터 느끼고 있었고 활용해보고 싶은 마음이 컷으나 아직까지도 어플리케이션에 적극 활용해본 경험을 갖지 못하고 있다. 아무래도 비동기에 대한 거부감이 적지 않고 Rest API에 대한 익숙함과 인프라 관리 포인트가 증가한다는 점이 회사에서 메시징 서비스를 도입하는 것을 미루게 되는 원인이지 않나 싶다.

그렇다고 마냥 준비를 미룰 순 없으니 조금씩 공부를 하고 있는데 ActiveMQ는 조금 써봤지만 카프카를 사용해보지는 못했다. 얼마전에 카프카 공부를 위한 페이지를 알게 되어서 적어 두고 공부를 해보고자 한다.

Apache Kafka Design

OSIV(Open Session In View)

OSIV는 Spring Data JPA를 사용한다면 한번쯤은 접해보았을 단어이다. 쉽게말해 데이터베이스 커넥션을 어느 범위까지 유지할 것인지에 대한 설정인데 SpringBoot에서는 기본값으로 true로 설정되어 있다.

설정값이 true이면 데이터베이스 커넥션을 Transaction 범위 밖에까지 유지할 수 있으므로 만약 지연로딩을 사용한다면 클라이언트가 해당 데이터를 호출할 때까지 데이터 조회를 미룰 수 있으므로 성능상의 이점을 가져갈 수 있다. 하지만 단점 또한 존재하는데 데이터베이스의 커넥션을 유지하는 시간이 길어지므로 다량의 트래픽을 감당해야하는 서버라면 DB의 커넥션 풀이 부족해지는 현상이 발생할 수 있다.

그러면 off를 설정하면 좋지 않느냐라고 할 수 있는데 만약 OSIV를 off하는 경우 지연로딩을 사용할 수 없어 우리가 무심코 사용하던 코드들이 런타임에서 오류가 발생할 수 있다. 왜냐하면 OSIV 설정이 off인 경우에는 Transaction 범위 밖에서는 지연로딩을 사용할 수 없기 때문이다. 해당 문제를 해결하는 방법은 fetch join을 사용하거나 Query 전용 서비스를 생성하여 지연로딩을 Transaction 범위내로 제한하거나 CQS를 사용하는 방법이 있다. 이러한 해결방법은 내부에 정책을 잘 잡아야 하고 시스템 디자인적으로 복잡성을 높일 수 있으므로 잘 선택해서 해야할 것이다.

김영한님의 영상자료에서 보면 관리자 서버와 같은 곳에서는 OSIV를 true로 설정하고 사용자 트래픽이 많은 API서버의 경우에는 off로 설정한다고 한다.

shape-up

새롭게(?) 나온 개발방법론이라는데 내용이 너무 방대해서 못읽어봤다. shape-up