Index를 생성해서 약 10배 성능 개선
·
Dev
자주 조회되는 컬럼에 인덱스를 생성해두면 빠른 검색이 가능해지기 때문에 프로젝트에서 인덱스를 생성해서 성능을 높일 수 있는 부분이 있는지 찾아 보았습니다. 인덱스가 단점으로는 데이터 변경 시 인덱스도 업데이트 해야 되기 때문에 데이터를 추가하거나 변경, 삭제시에 느려지게 됩니다.재료를 이용해 레시피를 검색하는 쿼리가 있어서 재료에 대해 인덱스를 생성해보았습니다.jpa를 이용해 index를 생성했습니다.@Table( name = "recipe", indexes = @Index(name = "idx_ingredient", columnList = "ingredient")) index를 생성하고 explain을 이용해서 인덱스가 잘 사용되는지 확인 했더니 인덱스가 사용되지 않고 있었습니..
stream 만들어낸 이유가 있지 않을까?
·
Dev
글을 작성하는 이유Java로 개발을 하다 보면 컬렉션이나 배열의 요소를 처리할 때 for문 대신 Stream을 사용하는 코드를 자주 마주하게 됩니다. 더 빠르다는 말에 이끌려 저 또한 Stream을 사용했습니다. 하지만 최근 들어 단순히 빠르다는 이유만으로 기술을 선택하는 것은 안일하다는 생각이 들었습니다. '왜 Stream을 사용해야 할까?'라는 근본적인 질문에 대한 답을 찾고 싶어졌습니다. 그리고 좋은건 더 공부해서 적극적으로 사용해야 한다고 생각했습니다.for문과 Stream, 어떤 차이가 있을까?특징for문Stream개념명시적인 반복함수형 스타일의 데이터 처리구조순차적인 실행파이프라인 구성장점직관적, 간단한 로직가독성, 유지보수성, 병렬 처리 가능단점복잡한 로직에서 가독성 저하, 병렬 처리 어려움..
N+1 문제 해결해서 성능 개선하기
·
Dev
문제상황조회 할 때 쿼리가 조회된 데이터 갯수(n) 만큼 연관관계의 조회 쿼리가 추가로 발생하는 n+1 문제가 발생하였습니다. 쿼리가 추가로 발생해서 성능 저하로 이어지기 때문에 문제를 해결해야 하는 상황입니다.추가로 발생되는 쿼리 확인Post가 10개씩 조회되는데 아래의 쿼리가 10개씩 추가로 발생하고 있습니다.2024-10-23 04:00:12.166 DEBUG 71806 --- [nio-8080-exec-1] org.hibernate.SQL : select postimgs0_.post_id as post_id4_10_0_, postimgs0_.post_img_id as post_img1_10_0_, postimgs..
일단 단위 테스트부터 테스트 코드 작성해보기
·
Dev
테스트 코드 작성하는 이유지금까지 테스트를 Swagger로 했는데 리팩토링 작업을 하면서 테스트 작업을 해야하는데 Swagger로 다시 테스트를 하기에는 너무 번거로운 작업이었고 테스트 코드를 작성하면서 기존에 발견하지 못했던 버그가 있으면 찾고자 작성하였습니다.단위테스트 vs 통합테스트단위 테스트는 개별 구성 요소의 기능을 개별적으로 확인하고 통합 테스트는 여러 구성 요소가 올바르게 함께 작동하는지 확인합니다.단위 테스트는 개발하면서 같이 작성해야 했는데 업보라고 생각하고 단위테스트부터 작성하였습니다.JUnit5와 MockitoJUnit 5와 Mockito는 Java 개발자가 단위 테스트를 작성하고 모의 객체(Mock Objects)를 사용하여 테스트하는 데에 널리 사용되는 라이브러리입니다.각각 JUn..
상품 주문하기 동시성 문제 해결하기
·
Dev
시나리오사용자 5명이 상품의 재고가 2개가 남았을 때 동시에 주문을 했을 때 정상적으로 동작하려면 3명의 사용자는 예외 처리(품절)가 되어야 합니다. 코드의 일부분을 보면 재고가 주문한 수량보다 많으면 예외 처리가 되어야 합니다. request.getOrderItemDTOList().forEach(orderItemDto -> { Item item = itemRepository.findById(orderItemDto.getItemId()).get(); orderItemDto.getOrderDetailDTOList().forEach(orderDetailDTO -> { if (orderDetailDTO.getItemOptionId() != null) { // 옵션이 있는 상품..
과도한 트래픽에 대한 방어하기
·
Dev
고민한 부분서비스를 배포하게 되면 한 사용자가 악의적으로 트래픽을 많이 보내게 될 경우 서버가 다운될 수도 있고 특정 기능은 외부 api를 사용하는 기능도 있어서 금전적으로 손해를 볼 수도 있겠다고 생각했습니다.그래서 특정 위치에서 발생하는 과도한 트래픽을 제한해야겠다고 생각했습니다.구현 방법 Bucket4j토큰 버킷(Token Bucket) 알고리즘을 사용하여 API 요청률을 제한하는 데 사용됩니다. 동작원리각 사용자 또는 API 키에 대한 버킷을 생성한다. 버킷으로 토큰의 개수를 제한할 수 있습니다.일정한 속도로 버킷에 토큰이 추가됩니다.API가 호출이 될 때 마다 버킷에 있는 토큰을 사용하게 되고 토큰이 부족하면 요청을 거부하거나 지연시킵니다. 구현HTTP 요청에 대한 Rate Limiting을 구..
GCP에 ElasticSearch 띄워서 검색 기능 구현하기
·
Dev
intro앱 기능 중 음식명으로 레시피를 조회하는 기능이 있습니다. 이 검색 기능에는 ElasticSearch를 사용해서 구현했습니다. ElasticSearch를 사용하면 성능이 매우 좋다는 정보를 많이 접했기 때문에 이를 기반으로 구현해 보았습니다.elasticsearch를 사용한 이유엘라스틱서치를 검색 엔진으로 사용할 때 독보적인 성능을 가지고 있습니다. 그 이유는 데이터를 저장하는 방식이 rdb와는 다른 방식을 사용해서 저장을 하고 있습니다. 엘라스틱 서치에서는 색인이라고 표현하는데 rdb에서 인덱스라고 표현하는 것을 역인덱스 구조로 저장하는 방식입니다.키워드에 인덱스를 주어지게 되어서 검색할 때 키워드를 이용해서 찾기 때문에 빠른 검색을 할 수 있습니다.ToolSpring 2.7.7ElasticS..
위치 기반으로 글 조회 기능 구현
·
Dev
들어가며게시판 기능인데 근처에 거주하고 있는 사람의 글을 조회할 수 있는 기능이 필요해서 게시글을 저장할때와 조회할때 위치를 반영해서 조회와 저장하도록 구현했습니다.ToolSpring boot 버전 2.7.7Naver Cloud MapsNaver Cloud Platform에서 Service 이용신청하기저는 위도, 경도를 이용해서 위치를 찾아낼 수 있는 Reverse Geocoding API를 사용했습니다.API요청은 가이드대로 요청하였습니다.https://api.ncloud-docs.com/docs/ai-naver-mapsreversegeocoding 일단 사용자 위치를 저장하고 조회할 수 있는 기능을 먼저 구현했습니다. 위도와 경도는 클라이언트에서 받아온 뒤 위치를 저장하고 조회하는 기능을 구현했습니다..
fcm 이용해서 앱 푸쉬 구현
·
Dev
의존성spring boot 버전 : 2.7.7implementation 'com.google.firebase:firebase-admin:9.1.0'  https://firework-ham.tistory.com/111Google Firebase에서 새로운 프로젝트를 생성하고 새로운 비공개 키를 다운받습니다.Client에서 Firebase 서버에 요청을 해서 Token을 발급받습니다.우리 서버에 Client에서 발급 받은 Token을 저장합니다.서버에서 Push 알림을 보내야할 때 Token과 Message를 만들어서 Firebase 서버에 전송합니다.Firebase 서버에서 Push 알림을 Device에 전송합니다.구현일단 firebase 프로젝트를 만들면서 생성된 json파일을 resources 폴더에 ..
소켓 통신(채팅방 구현)
·
Dev
소켓 통신 사용하는 이유소켓 통신은 실시간 통신을 할 수 있고 HTTP 통신보다 효율적으로 통신을 할 수 있습니다.HTTP와 소켓 차이 HTTP 통신HTTP 통신은 클라이언트에서 서버로 요청을 보내고 서버가 응답하는 방식으로 통신이 이루어진다. 응답에는 클라이언트의 요청에 따른 결과를 반환한다.클라이언트의 요청이 있을 때 서버가 응답하는 방식(단방향 통신)최근에는 Keep Alive 옵션을 통해 일정 기간 동안 클라이언트와 Connection을 유지하는 방식으로 통신이 가능해졌다.소켓 통신클라이언트와 서버 양쪽에서 서로에게 데이터 전달을 하는 방식의 양방향 통신보통 스트리밍이나 실시간 채팅 등 실시간으로 데이터를 주고 받아야 하는 경우 Connection을 자주 맺고 끊는 HTTP 통신보다 소켓 통신이 ..