목록전체 글 (316)
ecsimsw
0. 배경 개인 개발 블로그를 운영 중이다. 페이지를 구성하는 정적 파일은 Nginx 에서 직접 응답, DB 처리가 필요한 API는 WAS에서 처리하고 있다. 모니터링은 Spring boot actuator 로 메트릭 관련 API 를 열어두고, Prometheus 가 이를 일정한 간격으로 polling 해서 수집한다. CPU, 메모리 사용량, GC 처리 간격, 요청 수, 응답 시간을 모니터링을 쉽게 모니터링할 수 있었다. 이번에는 Nginx 의 메트릭을 모니터링하려고 한다. WAS 의 응답 시간, 요청 수뿐만 아니라, Nginx가 전면에서 처리하는 응답 시간, 요청 수, 리다이렉트 수가 궁금했다. 1. nginxlog-exporter 처음에는 Nginx가 기본적으로 제공하는 exporter 를 사용했었다..
파일 삭제 롤백 불가 문제 앨범을 삭제하면 그 안에 있는 모든 사진 정보, 파일이 삭제된다. 사진 파일 다중 제거하는 시간은 오래 걸리기에 이를 비동기 처리하여 DB 정보 삭제, 사진 파일 다중 삭제 이벤트 발행만 완료하고 그 즉시 앨범 삭제 처리 완료를 응답한다. @Transactional public void deleteAlbum(Long userId, Long albumId) { var pictures = pictureRepository.findAllByAlbumId(albumId); fileService.deleteAllAsync(pictures); albumRepository.delete(album); pictureRepository.deleteAll(pictures); // 후처리 } 코드의 ..
소개 이 글은 PIC-UP 프로젝트에 데이터가 쌓였을 때 조회 성능이 어떻게 되고, 어떤 개선 포인트가 있을지 확인했던 과정을 적어보았다. DB 쿼리 빈도를 줄여 조회 성능을 개선하는 캐싱이나 DB 부하 분산은 다루지 않는다. 대신 데이터를 만드는 방법부터 DB 엔진에 넣는 데 걸리는 시간, 인덱스나 쿼리 수정 고민 과정을 적어볼 생각이다. 다루는 내용은 아래와 같다. 1. 데이터를 삽입하는 방법 / 배치 삽입과 파일 삽입 2. 쿼리 조회 성능 확인 3. 인덱스 추가 / 인덱스와 커버링 인덱스 4. 실행 계획 확인 5. OFFSET 기반 페이지네이션 문제 확인과 개선 더미 데이터 추가 유저 정보를 담는 테이블로 더미 데이터를 먼저 넣어봤다. 컬럼은 ID:BIGINT, USERNAME:VARCHAR(20)..
소개 내 첫 번째 보물은 가족사진, 두 번째는 일기장, 그리고 세 번째 보물은 티스토리 블로그이다. 자유로운 글 관리부터 백업까지, 언젠가 직접 블로그 서버를 운영하길 꿈꿨었다. 이 프로젝트에선 티스토리 글을 백업하고, 그 데이터로 직접 블로그 서버를 운영한다. 저장소 : https://github.com/ecsimsw/blog.me 배포 링크 : https://www.ecsimsw.com 기능 1. 블로그 글을 수집할 수 있다. 2. 카테고리 별 글을 확인할 수 있다. 3. 게시물 별 조회수를 확인할 수 있다. 4. 전체 혹은 날짜 별 최다 조회수 게시물을 집계 할 수 있다. 기록 1. 조회수 캐시 조회수를 메모리에 기록해 두었다가, 10초에 한번 그 기간 발생한 수를 DB에 기록한다. 게시물 별 조회..
미리 보기 핸들러의 요청 처리 속도를 제한한다. 아래 핸들러는 0.1초에 한 번으로 처리 속도가 제한되고, 5개까지 보관해 두었다가 속도에 맞춰 처리한다. 10 개의 요청을 동시에 전송했을 때 5개만 처리되고 나머지는 429 (Too Many Requests) 를 응답받는 것을 확인할 수 있다. 그리고 처리되는 5개의 요청은 속도 제한에 따라 0.1초에 하나씩 처리된다. Leaky bucket algorithm 처리 속도를 일정하게 정하여 네트워크 트래픽 체증을 제어한다. bucket 크기를 미리 지정하여 순차적으로 처리하고, 버킷 크기를 넘어선 요청은 버려진다. 즉시 처리 rate는 0.1초, 사이즈는 3 인 버킷에, 5개의 패킷이 동시에 도착하고 0.2초 후에 3개의 패킷이 이어 도착했다고 가정해 보..
대기에 DB Connection 을 점유하는 비관적 락 이전 글 에서 프로젝트에서 생긴 동시성 문제가 왜 발생했는지 소개하고 이를 해결할 수 있는 락 종류를 소개했다. 추가적인 인프라와 적은 코드 수정, 그리고 확실한 동시성 문제 처리를 원했기에 비관적 락을 선택했다. 인덱스 조건을 수정하여 사용자별 로우락을 유도해 불필요한 대기를 없앴다. 그리고 얼마 후 DB 락 대기 시간 동안 커넥션을 점유하고 있음을 로그로 확인했다. 사용자 간 독립적으로 락 처리를 했지만, 한 사용자가 락으로 모든 커넥션을 물고 있으면 결국 락이 걸린 로우와 독립적인 다른 사용자는 그 사용자를 대기해야 했다. 이 글에서는 동시성 문제를 해결하기 위해 여러 락 방식을 적용하면서 발생했던 에러 사항들과 해결 과정을 소개한다. 목차는 ..
미리 보기 컨트롤러에 @ShutDown 어노테이션을 추가하고 임시 응답을 어떻게 전달할지를 지정해주는 것으로 ShutDown 조건에서 해당 컨트롤러 아래 모든 핸들러의 임시 응답을 자동으로 생성해 준다. 위 예시에서 DailyCountRepository 타입의 빈이 존재하지 않으면 /api/counts 를 GET 요청하는 경우 아래와 같이 응답한다. HTTP status : 503, SERVICE_UNAVAILABLE Content type : application/json Message : This API is currently unavailable. 아래 사용 방법이나 버전, 기능은 현재 글을 쓰는 첫 배포 시점을 기준으로 한다. 최신 변경 사항은 https://github.com/ecsimsw/ap..
Mysql InnoDB 의 RepeatableRead Mysql 의 기본 Transaction isolate 수준은 RepeatableRead 이다. RepeatableRead 는 트랜잭션이 시작된 시점 이후로 여러 번 Select Row 를 확인해도 동일한 값을 갖는다는 것이다. Mysql 은 SnapShot을 사용해서 이를 보장한다. 트랜잭션마다 별도의 스냅샷을 기록하여 다른 트랜잭션이 값을 변경하고 Commit 해도 이 스냅샷을 이용해서 동일한 값을 읽게 되는 것이다. Phantom read 문제 Repeatable Read 는 데이터의 추가, 삭제의 변경은 막지 못해 Phantom read 문제가 발생한다. 한 트랜잭션 내에서 전과 다른 조회 결과 row 수를 조회하게 된다는 것이다. InnoDB..