전체 글 58

kafka 성능 개선기 (feat. 배치 리스너)

들어가며 최근 사용자들의 행동 로그를 활용해 추천 서비스 기업에 관련 데이터를 보내는 프로젝트를 진행했었다. 아직 어리둥절한 신입에게 다소 무서웠던 프로젝트였지만, 어찌저찌 잘 해결해나가고 있었다.해당 프로젝트를 진행하며 처음으로 kafka를 활용했었고, 현재 회사 내 다른 프로젝트에서 사용하고 있는 설정법을 보며 똑같이 설정을 했었다.서비스 기업에서 어느날 피드백이 왔었는데, 지금 데이터들이 20시간가량 밀려있다고 해서, 확인을 했었는데, 잘못된 kafka 사용으로 인해 lag가 14,500,000개 정도 쌓여있었다. 이를 해결하기 위해 했던 과정들을 기록하고자 한다. 문제 원인1. consumer와 producer의 차이 현재 회사의 로그 관련한 서비스 구조는 다음과 같다. 기존에 추천 서비스 기업을..

개발일지 2024.09.02

[Git] SubModule에 대해서

들어가기 앞서 최근에 프로젝트에 투입되어 Github에 있는 code를 다운로드하여 확인하는 도중 특정 module 하위에 아무런 코드가 존재하지 않아 컴파일 에러가 나 당황했던 적이 있습니다. 동료에게 물어보고 도움을 받을 때 간단한 코드 두줄만에 해결이 되었습니다. git submodule init git submodule update 그 당시 github에서 제공하는 submodule에 대해 몰랐었고, 이러한 부분들에 대해 정리를 해 보고자 합니다. SubModule이란 무엇인가? git의 공식 홈페이지에는 다음과 같이 정의되어 있습니다. 프로젝트를 수행하다 보면 다른 프로젝트를 함께 사용해야 하는 경우가 종종 있다. 함께 사용할 다른 프로젝트는 외부에서 개발한 라이브러리라던가 내부 여러 프로젝트에..

개발일지 2024.04.16

백엔드 개발자 취업 준비 회고록

들어가기 앞서 2023년 6월부터 12월까지 프로그래머스에서 진행한 클라우드 기반 백엔드 엔지니어링 데브코스 과정을 수료했습니다. 본격적으로 1월부터 3월까지 취업활동을 진행했습니다. 취업 준비를 하며 느꼈던 부분들에 대해 적어보고자 합니다. 무엇을 공부해야 하는가? 취업 준비를 위해 공부해야 하는 분야를 크게 나눠보면 다음과 같다고 생각합니다. 코딩테스트 / 사용하는 언어 및 프레임워크 / Computer Science (팀프로젝트 및 토이 프로젝트 내용은 생략하였습니다.) 코딩테스트 23년 초기에만 하더라도 코딩테스트가 어렵기도 하고 막막했습니다. 그래서 과제 전형 혹은 코딩테스트 전형이 포함되지 않은 채용 프로세스만 지원을 했었는데 다음의 문제들이 존재했습니다. 지원 폭이 되게 좁다 체계가 갖춰진 ..

회고 2024.04.12

[Spring] 테스트 환경 통합

들어가며 요즘 테스트 코드의 중요성이 부각되며 테스트 코드들을 많이 작성하실 것 같습니다. 혹시 통합 테스트코드를 작성하기 위해 다음과 같이 작성하셨다면 오늘 글이 도움이 되길 바라며 적어봅니다. @SpringBootTest class MemberServiceTest { // test code .. } @SpringBootTest class PostServiceTest { // test code .. } Spring TestContext Framework Spring TestContext Framework는 Spring Application 테스트를 위한 핵심 기능들을 제공합니다. Context Management Dependency Injection of Test Fixtures Transaction ..

Spring 2024.03.09

[Java] Optional

들어가기 앞서 자바를 사용해 프로그래밍을 할 경우 종종 마주치는 예외는 NullPointerException일 것입니다. public class Person{ private Car car; public Car getCar(){ return car; } } public class Car { private Insurance insurance; public Insurance getInsurance{ return insurance; } } public class Insurance{ private String name; public String getName(){ return name; } } public String getCarInsuranceName(Person person){ return person.get..

Java 2024.01.26

[Java] Stream

Stream이란 무엇인가? Java 8에 새로 추가된 기능으로 스트림을 사용하면 선언형으로 Collection 데이터들을 처리 할 수 있다. 예를 들어 칼로리가 400 미만인 요리들을 정렬해 Collection에 저장한다고 가정을 했을 때 스트림을 사용하지 않으면 다음과 같이 구현할 수 있다. List lowCaloricDishes = new ArrayList(); for(Dish dish : menu) { if (dish.getCalories() < 400){ lowCaloricDishes.add(dish); } } Collections.sort(lowCaloricDishes, new Comparator(){ public int compare(Dish dish1, Dish dish2){ return I..

Java 2024.01.24

[Java] 인터페이스 default method, static method

들어가며 자바에서는 인터페이스를 사용해 인터페이스를 구현하는 클래스에서 추상 메서드를 구현해야 합니다. public interface A { void doSomething(); } A 인터페이스에는 doSomething 이라는 추상 메서드가 존재합니다. public class AImpl implements A{ @Override public void doSomething() { System.out.println("this is A"); } } A인터페이스를 구현한 AImpl의 경우 doSomething 메서드를 override 하여 재정의 해 주어야 합니다. 만약 인터페이스에 추상 메소드가 추가되는 경우에는 이를 구현하는 클래스에서 다시 재정의 해 주어야 합니다. public interface A { v..

Java 2024.01.18

[Java] 함수형 인터페이스, 람다, 메소드 레퍼런스에 대하여

함수형 인터페이스, 람다, 메소드 레퍼런스 모두 긴밀한 연관을 가지고 있는 개념입니다. 이번 글을 통해 해당 개념들을 살펴 보고자 합니다. 함수형 인터페이스 @FunctionalInterface public interface Foo { int add (int a, int b); default void printDate(){ System.out.println(LocalDate.now()); } } 함수형 인터페이스란 추상 메소드를 단 하나 가지고 있는 인터페이스를 의미합니다. default method, static method가 몇개 존재하던 추상 메소드를 단 하나만 가지고 있다면 함수형 인터페이스라고 합니다. Q) 추상 메소드란 ? A) 선언만 되어 있고, 구체적인 구현은 되어있지 않은 메소드입니다. ..

Java 2024.01.15

[Spring] @Retryable, Event 적용기

들어가기 앞서 커플 기반 다이어리 프로젝트에서 커플의 활동 지표를 나타내는 사랑의 온도라는 기능이 존재합니다. 사랑의 온도는 해당 서비스를 사용할 때마다 특정 조건에 대해 온도를 높여주는 기능입니다. 사용자들의 서비스 참여도를 높이기 위해 해당 기능을 추가했었습니다. 리팩토링을 진행하며 @Retryable 그리고 ApplicationEventPublisher를 적용했던 일화에 대해 기록하고자 합니다. @Retryable 적용기 기존 코드 온도 증가 기능 사랑의 온도 기능의 경우 다이어리 작성, 오늘의 질문에 대한 답변 작성 시마다 온도가 1도씩 증가하도록 설계했습니다. 앱 사용량이 많은 커플의 경우 동시성 문제가 발생 할 수 있다고 판단을 했었고 이에 따라 optimistic lock을 적용해 온도 증가..

Spring 2023.12.04

커플 재결합 관련 Code Refactoring

들어가기 앞서 현재 커플 기반 다이어리 서비스를 제작하고 있습니다. 커플 끊기와, 커플 재결합 기능을 맡아 개발을 진행했습니다. 그와 관련되어 코드를 리팩터링 하게 된 일화에 대해서 다뤄보려고 합니다. 처음에는 간단하게 API를 세개를 두고, 커플 끊기, 커플 재결합 로직을 구현했습니다. [DELETE] /v1/couples/{coupleId} => 커플 끊기 API [POST] /v1/couples/recouple/{coupleId} => 커플 재결합 신청 API [POST] /v1/couples/recouple-decide/{recoveryId} => 커플 재결합 결정 API 각 API에 대한 처리 로직은 다음과 같았습니다. 커플 끊기 Couple Entity에 @SQLDelete 어노테이션을 사용해..

개발일지 2023.11.22