Backend 42

Node.js Graceful Shutdown 적용

시작하며Node.js 서버에서 금전적인 행위를 처리하는 배치 작업이 종료(Shutdown)될 때 안전하게 종료되지 않아 특정 유저의 출금이 두 번 발생하는 문제가 종종 발생했다. 원인을 분석해보니, Shutdown 시점에 출금 처리는 되었으나 데이터 처리까지 완료되지 않아, 다음 배치 작업에서 중복 출금이 발생하는 문제였다. 이를 해결하기 위해 Graceful Shutdown을 도입하는 과정에서 배운 점들을 기록하였다.Graceful Shutdown이란?직역하면 우아한 종료로, 애플리케이션이 완전히 종료되기 전에 진행 중인 모든 작업을 마무리하고, 리소스를 해제하며 데이터의 무결성을 유지한 상태로 안전하게 종료되는 과정을 의미한다.Node-schedule 사용Node.js에서 스케줄업무를 하는 라이브러리..

Backend/Node.js 2024.10.30

Readable Code

시작하며Readable Code: 읽기 좋은 코드를 작성하는 사고법 강의를 보고 정리한내용으로,회사의 서비스 개선을 준비하는 단계에서 우리팀에 적용해보면 좋겠다. 라는 생각이 들어 정리한 내용입니다. 이름짓기1. 단수와 복수를 구분하기~(e)s를 붙여 변수, 클래스 등 단수인지, 복수인지 구분2. 이름줄이지 않기관용어처럼 많은 사람들이 자주사용하는 줄임말 정도만 사용하고, 무분별한 줄임말은 자제 또한, 줄임말이 이해될 수 있는 것은 문맥때문이기에 문맥을 잘 활용ex) column -> col, latitude -> lat, longitude -> lon 3. 은어 / 방언 사용하지 않기일부 팀원 / 현재의 우리팀만 아는 용어금지새로운 사람이 팀에 합류했을때 용어를 이해하기 힘들다.도메인 용어 사용하기팀단..

Backend 2024.10.02

Spring REST API 요청 및 응답시 직렬화, 역직렬화의 원리

먼저 직렬화와 역직렬화란 무엇인가? 직렬화 : 메모리를 바이트 스트림으로 변환하는 과정으로 이를통해 네트워크 통신이 가능해진다. 역직렬화 : 네트워크 통신으로 받은 데이터를 메모리에 쓸수 있는 형태로 변환하는것이다. Spring의 직렬화 및 역직렬화 일반적으로 Spring에서는 직렬화 및 역직렬화시 Java 객체 ↔ JSON 형태로 변환한다. Spring-web 라이브러리에는 HttpMessageConverter를 상속받는 다양한 Converter가 존재한다. 유형에 따라 Converter가 사용되며, RestApi 유형의 경우에는 MappingJackson2HttpMessageConverter 가 사용된다. 여러 Converter 중 적합한 Convert를 판단하는 방법은? public interfac..

Backend/Spring 2024.04.23

동시성 문제에 대한 N개의 해결방법

시작하며 인프런의 모든강의가 30% 할인 하길래 동시성관련 강의를 구매 후 공부한 내용을 기록하였다. [강의] 동시성 문제란? 동시성 문제란 여러 쓰레드들이 공유 자원에 대한 경쟁을 벌여 의도하지 않은 결과를 말한다. 강의는 상품의 재고에대한 동시성문제를 다루는 내용이다. 재고 감소로직의 순서로는 1) 재고 감소 로직은 해당 ID값을 통해 엔티티를 조회 @Transactional public void decrease(Long id, Long quantity) { Stock stock = stockRepository.findById(id).orElseThrow(); stock.decrease(quantity); stockRepository.saveAndFlush(stock); } 2) 요청 재고가 기존 재..

Backend/Spring 2024.03.24

커버링 인덱스 적용

시작하며 MMS 발송 모듈에서 히스토리 테이블의 Select 시 성능 저하로 커버링 인덱스를 적용하였다. 현재 상황 테이블은 4개의 컬럼으로 구성되어있고, 4개의 컬럼이 복합 PK로 구성 및 파티션이 적용 되어 있다. 발송 배치시 Select 쿼리 성능 저하로 TPS가 맞춰지지 않았다. 원인 복합 PK를 사용시 단점으로 Where 조건절이 복합키 컬럼이 모두 만족 되지 않는다면 인덱스가 적용이 되지않는다. 현재의 Where 조건절에는 하나의 컬럼만이 사용되었다. History 테이블로서 데이터가 지속적재 되기때문에 시간 경과에 따른 누적 성능 저하가 발생한다. 해결방안 Where 조건절에 해당하는 컬럼을 추가 적용하여, 인덱스가 적용되도록 추가하여, 기존 성능 2초에서 0.01초로 감소시켰다. 링크 : ..

Backend/DB 2024.03.21

Spring boot, Kafka 연동

시작하며Kafka에 대한 지식이 부족하다고 판단하여, Local 환경에서 Spring boot와 Kafka의 연동실습이며, 이론적인 내용은 추후에 작성할 예정이다. Kafka 서버 구축하기1. Apache Kafka 공식 홈페이지에서 Kafka 다운로드Apache Kafka 홈페이지다운로드 후 압축을 해제하면, bin과 config 파일이 존재한다.bin 디렉토리내에는 Kafka 관련 각종 실행 sh가 , config 디렉토리내에는 설정관련 파일이 위치한다. 2. Kafka Zookeeper 구동하기./bin/zookeeper-server-start.sh ./config/zookeeper.propertiesZookeeper는 기본적으로 2181 포트에서 구동한다.3. Kafka Broker 구동하기./b..

Backend/Spring 2024.01.14

Springboot Slack으로 알림 받기

시작하며 Error 또는 중요한 배치 시 알람을 받을 방법으로 회사에서 사용하는 Slack을 접목시켰다. 링크 : https://github.com/seungsoos/slack-demo Slack 의존성 추가 및 yml 설정 implementation("com.slack.api:bolt:1.18.0") implementation("com.slack.api:bolt-servlet:1.18.0") implementation("com.slack.api:bolt-jetty:1.18.0") 구글링을 통해 방법을 찾고, 해당 토큰을 입력한다. 코드내용은 아래와 같다. @Slf4j @Component @RequiredArgsConstructor public class SlackComponentImpl implemen..

Backend/Spring 2023.09.11

[ERROR] ClientAbortException

시작하며서버로그중 가끔씩 ClientAbortException가 보인다. Response body : {"code":"400","msg":"Insufficient parameters.","data":"I/O error while reading input message; nested exception is org.apache.catalina.connector.ClientAbortException: java.io.EOFException"} 발생원인 : 클라이언트가 연결을 끊었을때 발생하는것이 일반적이다.서버가 클리이언트로 응답을 보내려하지만, 클라이언트의 연결이 이미끊어진경우 발생한다. 해당 에러는 클라이언트 단에서 발생하였다. 해당 에러는 Filter에서 Handling설정을 하였다. 참고사이트 https..

Backend/Spring 2023.08.10

데이터베이스(DB) index

시작하며 Index 정리 및 예시를 통해 학습한 내용을 정리하였다. 인덱스란? - 인덱스는 데이터베이스 테이블에 대한 검색 성능 속도를 향상시켜주는 자료 구조이다. 인덱스는 특정 컬럼(여러컬럼의 조합)에 대한 정렬된 값의 집합으로, 데이터베이스 엔진이 데이터를 빠르게 찾을수 있도록 도와준다. Ex) 책의 목차라고 생각하면 이해가 쉽다. 책의 목차에서는 내가 찾고자 하는 페이지가 어디 있는지 빠르게 찾을 수 있도록 해준다. 인덱스는 데이터베이스 테이블의 특정 컬럼(여러 컬럼)의 값을 사전 순서 또는 정렬 순서로 저장하여 데이터 접근과 검색을 최적화한다. 일반적으로 B-트리(B-tree)나 해시 테이블 등의 자료구조를 사용하여 인덱스를 관리한다. 실생활에서의 인덱스 사용예제) 인덱스의 자료구조 해시 테이블..

Backend/DB 2023.07.30