전체 글 361

Sequelize - 일괄 등록, 일괄 수정 하기 (bulk create, bulk update)

일괄 등록 (bulkCreate) const result = await User.bulkCreate(usersDTO) 일괄 등록의 경우 Sequelize는 bulkCreate 메서드를 지원하고 있습니다. bulkCreate()를 이용해서 배열을 한 번에 insert 칠 수 있습니다. 일괄 수정 (bulkUpdate) Sequelize에서 일괄 수정을 하는 방법은 3가지가 있습니다. 한 가지씩 소개해드리겠습니다 ! 1. update const result = await User.update({ name: updateUsersDto.name }, { where: { id: { [Op.in]: updateUsersDto.users } } }); // UserDTO.ts export interface Updat..

Server/Node.js 2022.01.05

Effective Java - 생성자 대신 정적 팩토리 메서드를 사용하라!

정적 팩토리 메서드 저는 클래스를 작성할 때 객체를 인스턴스화 하는 코드를 작성할 때는 무조건 생성자를 사용했었어요! Effective 자바의 내용 중에 생성자 대신 정적 팩토리 메서드를 사용하는 것을 검토해봐야 한다는 논의가 있었는데 좋은 내용 같아서 가지고 왔어요! 팩토리 메서드란 객체를 생성하는 메서드를 말합니다! 정적 팩토리 메서드는 객체를 생성하지 않고, 정적 메서드를 활용해서 객체를 만드는 방법이겠네요 ! 정적 팩토리 메서드를 사용하는 이유 1. 이름을 가질 수 있다. 생성자는 클래스명을 이름으로 하고, 클래스 하나당 생성자 1개 밖에 둘 수 없기에 어떤 객체를 생성하는 지 직관적이지 않습니다. public class Car{ String brand; String color; public Ca..

Language/Java 2022.01.02

MySQL - 인덱스 타는지 체크 방법 (+개선 방법, 인덱스를 타게 하는 방법)

MySQL 인덱스 타는지 확인하는 방법 mysql에서는 인덱스를 여러 개 걸었을 때 하나밖에 타지 않습니다. 그래서, 인덱스를 적절하게 걸어주지 않으면 데이터가 커졌을 때 트래픽이 튀거나 슬로우쿼리 등 문제가 될 확률이 거의 99%입니다. 인덱스를 타는 지 확인하는 방법은 MySQL의 Explain을 사용하는 것입니다. explain은 쿼리의 실행 계획을 반환해주므로 쿼리 튜닝, 성능 분석, 전략 수집 등의 기초가 됩니다 ! 사용 방법은 SELECT문 앞에 explain을 붙여주면 됩니다. explain select * from booking where resource_id=1 and start_time > NOW() order by rand(); 실행계획 분석 직접 쿼리문을 실행해보니 아래와 같은 결과..

Database/SQL 2022.01.01

NodeJS - 전역 예외 핸들러 구현 (Custom global exception handler)

전역 예외 핸들러 저의 경우 Sequelize + express + nodejs의 프로젝트를 하고 있었는데, Sequelize가 500번대 예외를 뱉는 경우가 많았습니다. 해당 부분은 App단에서 최대한 검증을 해서 요청을 보내면 좋겠지만, 동시성 문제로 어쩔 수 없이 예외가 발생하기도 합니다. 요즘은 500번대 에러는 핸들링을 하는 것을 원칙으로 하는 기업이 많은 걸로 알고 있습니다. 특히 네이버 특정 계열사 Open API Reference에 보면 500번대 에러가 나오면 제보해달라는 내용이 있기도 하기도 합니다. 따라서, 해당 예외를 핸들링하고 싶었는데, 각 메서드에 여러개의 예외처리를 전부 공통적으로 붙이면 유지보수성이 떨어지니까, 전역 범위로 적용해야 했습니다. 스프링은 @ControllerAd..

Server/Node.js 2021.12.29

NodeJS - API Response를 snake case로 변환하기(DTO, Entity 필드는 camel case)

API Request, Response body를 snake_case로 변환 ? 데이터베이스의 테이블 스키마를 작성할 때는 주로 snake_case를 사용합니다. 또한, 최근 들어 API의 Request, Response body 컨벤션으로 snake_case를 사용하면서 통신하는 것이 많이 선호되고 있는 것 같습니다. 스프링은 Jackson 라이브러리를 사용해서 이를 쉽게 처리할 수 있는데, 아쉽게도 nodejs, express에서는 코드 한 줄로 이를 처리할 수 있는 방법이 없습니다. 방법은 2가지가 있습니다. 포스팅에서는 2번째 방법을 다룹니다. 1. DTO 및 엔터티를 전부 snake_case로 작성하는 방법 2. middleware를 사용해서 snake_case로 변환해주는 방법 (DTO 및 엔..

Server/Node.js 2021.12.27

NodsJS - BullMQ 사용 (대기열, 동시성 제어 등)

BullMQ BullMQ는 Redis를 기반으로 하고, kafka나 RabbitMQ보다 훨씬 가볍고 편리한 Message queue입니다. 현재 기준 Github Star 11.8K 정도 되고, 거의 매일같이 커밋이 올라오는 뜨거운 라이브러리입니다. 제가 BullMQ를 도입하게 된 이유는 잔량을 파악해서 순차적으로 작업을 실행해야 하는 일이 있었는데, 테이블 구조가 DB 락(Select... for update)을 걸 수가 없는 상황이었습니다. 그래서, 대기열을 따라서 순차적인 처리를 위해 도입했습니다. BullMQ를 도입하기 전에 kafka 도입을 검토했었는데, 앱 서버만해도 2개가 추가되고 (Producer, Consumer)랑 또 추가로 Zookeeper, kafka 등 띄울게 너무 많고 무거웠어요..

Server/Node.js 2021.12.25

대규모 서비스 - I/O 부하 (느려졌다고 무조건 서버 증설? No!)

부하 종류 일반적으로 부하는 크게 두 가지로 분류됩니다. CPU 부하 I/O 부하 CPU 부하는 무언가를 계산할 때 일어나는 부하를 말합니다. CPU 부하의 규모조정은 간단합니다. 같은 구성의 서버를 늘리고, 로드밸런서로 분산을 시키면 됩니다. 반면, I/O 부하의 규모조정은 어렵습니다. I/O 부하란, 입력, 출력에 생기는 부하를 말합니다. 예를 들어, DB에 접근할 때 DB의 레코드 데이터를 출력하거나, DB에 데이터를 입력할 때 생기는 부하입니다. (I/O 부하를 해결하기 위해서 각 OS마다 캐시를 이용해서 메모리를 추상화 합니다.) 부하 파악 sar 명령어(sar command)로 CPU 사용률과 I/O 대기율을 확인할 수 있습니다. %user는 사용자 모드에서의 CPU 사용률이고, %system..

Markdown으로 Rest API 문서화하기 !

📝 markdown-api-docs API 문서, API Reference, API docs를 작성하실 때 깃허브(Git hub)나 깃랩(Git lab)에 markdown으로 작성한 템플릿을 공유하고자 합니다. Source : https://github.com/violetbeach/markdown-api-docs 📚 API 설계 API Reference 자원 /resources 자원 등록 새로운 자원을 등록합니다. URL /resources Method: POST Data Paramsname=[String] - 자원명 count=[Integer] - 수량description=[String] - 자원 설명 Optional: Required: Responseid=[String] - 자원 일련번호 name=[..

Operation/Rest API 2021.12.25

대규모 서비스 - O(log n) 알고리즘을 사용하는 이유

O(log n), O(n log n) 사용을 왜하는 걸까? Google, Facebook의 경우 특정 테이블은 레코드가 몇십억, 몇백억 개가 있고, 테라 바이트, 페타 바이트 단위 이상이라고 합니다. 인덱스를 태우지 않고, 선형탐색으로 했을 때 레코드가 500만개만 있어도 요청 하나를 200초 안에도 처리하지 못합니다. O(n) 알고리즘을 사용했을 때 1000만번 계산해야 할 때, O(log n) 알고리즘을 사용할 때 수십 번만 계산해도 처리가 가능합니다. 그 차이는 데이터가 커질수록 기하급수적으로 커지겠죠. 그래서 대규모 서비스를, 아니 중규모 이상 서비스를 고려한다면 O(n) 알고리즘을 O(log n) 알고리즘을 사용하는 것이 중요합니다. 이런 이유로, Basic하게 배운 선형 탐색들을 사용하기 보다..

Language/Algorithm 2021.12.25

NodeJS - 모델매퍼(ModelMapper) 사용 [Class transformer]

모델 매퍼(ModelMapper) 스프링의 경우 DTO와 엔터티간의 변환을 할 때 ModelMapper나 Mapstruct라는 라이브러리를 많이 사용합니다. 그러면, 객체가 가질 수 있는 프로퍼티는 옮겨지게 되고, 아닌 프로퍼티는 버려지게 되죠. JS는 그러한 역할이 없어서 상당히 불편했습니다. Interface를 고집한다는 점과 Class instance와 Literal object 간 변환이 어렵다는 점이 이유입니다. 그나마 쓸만한 라이브러리가 AutoMapper인데 사용하기가 어렵고 유지보수가 중지되었죠. 그래서 최근에 나와서 핫한 라이브러리 중 하나가 class-transformer입니다. 이 라이브러리는 ModelMapper 역할을 훌륭하게 수행할 수 있고, 상당히 강력하고 간단합니다. 최근 c..

Server/Node.js 2021.12.24