실무에서 알게된 내용
-
복잡했던 조회 및 CSV 다운로드 API 이관기실무에서 알게된 내용 2022. 7. 21. 18:12
이관 API 조회 API CSV 다운로드 API (최대 10만 개까지 가능) 고려했던 사항 2가지 검색 필드와 상관없이 기존 한 개로 사용되던 쿼리를 특정 검색 필드 포함 여부에 따라 쿼리를 분리 시킴. 이를 통해 불필요한 join을 제거함 CSV 다운로드를 위해 최대 10만 개까지 조회할 수 있는 쿼리를 더보기(more) 방식으로 변경함. 이를 통해 성능 개선함 1. 조회 페이지 join이 필요한 검색 필드 조사 (검색 비율 적음) 총 2개 위 필드로 검색됐을 때만 join 수행 2. 그 외 검색 필드 테이블 하나로 쿼리 수행 3. 추가 사항 특정 서비스를 통해 조회하는 경우에는 특별히 담당하고 있는 사람들의 정보만 보여줘야 하기 때문에 또 하나의 join 수행 2. CSV 다운로드 조회 페이지에 노출..
-
Edge API로 전환 작업을 하며 고민했던 사항 [진행 중]실무에서 알게된 내용 2022. 7. 15. 01:11
고민했던 사항 1. 모듈 간 의존성 방향은 api 모듈 → service 모듈 → domain 모듈 ← client 모듈 방향을 지키도록 한다. 이를 통해 domain 모듈은 client 모듈의 구현으로부터 독립되도록 한다. 2. api 모듈에서는 domain 모듈에 있는 객체를 웬만하면 바로 반환하지 않고 common-web 모듈에다가 화면에 fit 한 response객체를 만들어 이를 반환하도록 한다. 왜냐하면, domain 모듈에 있는 객체를 바로 반환하게 되면 신규 입사자가 domain 모듈에 있는 객체의 필드를 변경하게 됐을 때, 컴파일 시점에 에러를 잡을 수 없을뿐더러 이 영향이 클라이언트까지 미칠 수 있기 때문이다. 3. response 객체에 있는 Enum 타입 필드들은 Enum 값으로 내..
-
좌충우돌 Coroutine 적용기실무에서 알게된 내용 2022. 7. 1. 01:41
최근 담당하고 있는 서비스에 Coroutine을 적용할 기회가 있었다. 이에 Coroutine를 적용하면서 알게 된 내용을 정리해보고자 한다. 참고로 코루틴 개념을 처음 접한 건 3년 전 어드민 서비스를 만들 때 Generator함수를 사용해 보면서 였다. Coroutine이란 무엇일까? 사람들마다 정의가 조금씩 다를 순 있겠지만 나는 코루틴을 비동기 프로그래밍을 하기 위한 일시 정지 가능한 경량화된 스레드(light-weight thread)라고 정의를 내린다. 그럼 경량화된 스레드란 무엇일까? 이것에 앞서 프로세스와 스레드의 개념부터 우선 정리해 보고자 한다. 흔히 프로세스는 실행되고 있는 프로그램(disk에 있는 program이 memory에 올라간 상태) 또는 OS로부터 시스템 자원을 할당받는 작..
-
모듈간 의존성 개선 및 정리 작업실무에서 알게된 내용 2022. 6. 30. 10:08
Edge API 전환 작업을 진행하며, 추가로 모듈 간 의존성을 개선 및 정리하는 작업을 조금 진행했었다. 아직, 완벽하다고 말할 수 있는 상태는 아니지만 해당 작업을 진행하며 개인적으로 고민했던 사항들을 아래와 같이 정리해 봤다. 참고로, 내가 담당하고 있는 서비스의 모듈은 아래와 같이 총 7개로 구성돼 있다. internal api external api service domain common common-web client 1. api 모듈(internal/external)이 의존하고 있는 모듈 (as-is: 5개, to-be: 4개) common common-web api 모듈(internal/external)에서 각각 선언해서 사용하고 있던 request/response 객체를 common-w..
-
로그가 간헐적으로 중복 노출되는 이슈실무에서 알게된 내용 2022. 6. 29. 08:56
작업했었던 프로젝트를 배포하고 모니터링을 하는데, 로그가 간헐적으로 중복 노출되는 이슈가 있었다. 사실 처음에는 다른 로그들은 한 번씩만 남고 있는 상태였기 때문에 로그가 중복 노출될 거라는 생각은 전혀 하지 못했다. 따라서, 당연히 휴먼에러로 인해 애플리케이션 레벨에서 의도치 않게 작업이 여러 번 수행되고 있을 거라는 생각을 가장 먼저 했다. 하지만, 아무리 생각해봐도 애플리케이션 레벨의 이슈는 아닌 것 같았다. 왜냐하면, 간헐적으로 중복 노출됐던 로그 중 하나가 아래 코드 부분이었는데 DB로부터 데이터를 읽어와서 publish 메소드를 호출하는데, 여기서 간헐적으로 해당 메소드가 여러 번 호출되는 건 로직상 불가능하다고 생각했기 때문이다. 또한, 이 시점에 중복 노출됐던 로그 정보를 자세히 확인해 봤..
-
ClientAbortException은 언제 발생하는가?실무에서 알게된 내용 2022. 6. 23. 08:05
서비스 모니터링을 하다가 아래처럼 ClientAbortException(java.io.IOExceiption: Broken pipe)이 발생하고 있는 것을 확인했다. 이에 해당 Exception이 언제 발생하는지를 분석해 봤다. 일단 해당 로그를 보면서 가장 눈에 띄었던 포인트는 특정 API를 호출하는데 4초가 걸리는 점과 예외 메시지에 org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe이 있다는 점이었다. 이를 근거로 클라이언트 쪽에서 API 응답 시간이 오래 걸리니까 서버에서 응답을 내려주기 전에 커넥션을 끊어 버려서 그런가?라는 의심을 했었다. 코드를 분석해보니 아래 빨간 네모 부분에서 Excepti..
-
운영 배포 전에 챙겼던 Kafka Producer Client 포인트들실무에서 알게된 내용 2022. 6. 22. 11:36
1. 주요 옵션 정리 buffer.memory producer가 kafka 서버로 데이터를 보내기 전에 잠시 기다리는 버퍼 메모리 공간 기본값은 33,554,432 byte (32MB), compression.type producer가 데이터를 보낼 때 압축을 해서 보낼 수 있는데, 이때 압축하는 방식 기본값은 none retries 일시적인 오류로 producer가 데이터 전송에 실패할 경우, 재전송할 횟수 acks producer가 kafka로 데이터를 전송한 뒤 요청 완료를 결정하기 위한 옵션 0(빠른 전송), 1(리더만 메시지를 받았는지 확인), all(모두 메시지를 받았는지 확인) batch.size producer가 여러 데이터를 같은 파티션을 전송할 때 batch방식으로 보내는데 이때의 크기..
-
컬럼 값을 Collection으로 받을 때 Querydsl 이슈실무에서 알게된 내용 2022. 6. 21. 21:09
최근 팀 내에서 GW 방식으로 통신하던 것들을 Edge API로 전환하는 작업을 하고 있다. 이 때문에 Querydsl를 사용해서 쿼리를 작성해야 하는 일이 있었다. 그런데, 특정 검색조건에 대해 Querydsl을 작성하고 DB 통합 Test를 돌렸더니 갑자기 NPE(NullPointerException)가 발생했다. (참고로 현재 내가 맡고 있는 서비스에서는 DB 통합 Test를 위해 Database Rider을 사용하고 있다.) 처음 들었던 생각은 애초에 말도 안 되는 생각이지만 '데이터가 없어서 그런가?'였다. 역시나 이건 아니었다. 이에 코드를 분석해 봤더니 아래 빨간 네모에서 null 값을 리턴하고 있어서 NPE가 발생하고 있었다. [MethodNode 클래스] 여기서 궁금증이 하나 생겼다. ..