본문 바로가기

Back-End

(91)
새로운 프로젝트의 시작 안녕하세요. 이때까지 개발글을 기재하다 잠시 멈춰잇었는데요. 제가 드디어 https://www.moyo.company 하나의 사이트를 만들었습니다. 알뜰폰 요금제 추천해주는 사이트입니다!
네이버 - 콘퍼런스 참가 기능 개발기 ( 대규모 참가 서비스 개발 ) 네이버와 같이 대규모 서비스 개발기를 감사하게 공유해주어 해당글을 보고 재 작성한 블로그입니다. https://d2.naver.com/helloworld/5048491 개발에 사용한 도구 nGrinder : 성능 테스트 도구 Pinpoint: 성능 모니터링 도구 nbase-src : Redis 기반의 분산 메모리 저장소 성능 테스트는 어떻게? 어떠한 목표로? 나처럼 대규모 서비스에 있어보지 않은 사람은 성능 테스트를 피부로 느껴보지 못한다. 그렇다면 대규모 서비스에서 성능 테스트와 목표는 어떻게 잡을까? 성능 테스트하면 모호해 보이지만 항상 정확한 수치를 기반으로 목표를 가져아 한다 몇 초안에 XX,XXX 번의 요청이 들어올 수 있다고 가정하고, 1초에 X,XXX건 요청을 처리하고 서버당 XXX TPS(..
레디스와 분산락 들어가기 전에 대규모 서비스 개발에 대한 경험이 없다면, 여러 서버를 운영하는 분산환경에서 락 처리에 관한 고민을 할 필요를 느끼지 못한다. ( 물론 내가 부족한 개발 실력을 가지고 있어서도 그렇지만... ) 많은 트래픽을 받는 경우 당연히 수평적 확장이 용이해야 하고, 여러 대의 서버로 API가 분산 호출된다. 서비스 특성 상 트랜잭션이 많이 일어나는 상황이면 동기화된 처리가 필요하고, 여러 서버에 공통된 락을 적용해야 하기 때문에 레디스를 이용하여 분산락을 이용한다. 분산 락은 데이터베이스 등 공통된 저장소를 이용하여 자원이 사용 중인지를 체크한다. 그래서 전체 서버에 동기화된 처리가 가능해진다. 간단한 분산 락 구현하기 setnx 명령어를 통해 "락이 존재하지 않는다", "존재하지 않는다면 락을 획..
JPA 에러 - Deadlock found when trying to get lock; try restarting transaction Deadlock found when trying to get lock; try restarting transaction Deadlock이 발생하게 된 코드 및 상황 @Transactional(isolation = Isolation.SERIALIZABLE) override fun save(userNo: Int, productId: Int): Order { return repository.findByProductId(productId)?.let { println("[${Thread.currentThread().id}] - $productId count is increased - ${it.count}") it.count += 1 return repository.save(it) } ?: createOrder(u..
스프링 blocking vs non-blocking : R2DBC vs JDBC & WebFlux vs Web MVC 들어가기 전 해당 글은 https://technology.amis.nl/2020/04/10/spring-blocking-vs-non-blocking-r2dbc-vs-jdbc-and-webflux-vs-web-mvc/ 를 번역한 글입니다. 영어가 더 편하시다면 이 글을.... 스프링 프레임워크 버전 5는 리액티프 프로그래밍을 위한 WebFlux를 2017년 8월에 릴리즈 하였고, 2019년 12월에 리액티프 드라이브를 사용한 관계형 데이터베이스인 R2DBC를 릴리즈하였다. 해당 포스팅에서는 WebFlux와 R2DBC를 사용했을 때 더 높은 동시성에 대해 알아본다. 이 둘을 사용하면 더 빠른 응답과 더 높은 처리량을 가지고, 뿐만 아니라 메모리도 조금 사용하고 요청당 CPU도 조금 사용한다. 그리고 JAR ..
Redis란? Redis란 Remote Dictionary Server의 약자이다. Redis의 특징 - 다양한 Collection 지원 Redis는 In-memory 데이터베이스이다 디스크 접근인 RDBMS 속도 개발 편의성 이렇게만 봐서는 뭔가 와닿지가 않는다. 예를 들어, 실시간 랭킹 서버를 구현한다면? 1) RDBMS를 이용하여 구현한 경우 저장된 SCORE를 정렬하여 가져오는 과정 필요 개수 많아지면 느려짐 트랜잭션 문제도 신경 써야함 2) Redis를 이용하여 구현한 경우 Redis의 Sorted Set을 사용하기 때문에 정렬이 필요 없음 ( 다양한 Collection의 장점 ) 모든 자료구조는 Atomic 하기 때문에 데이터 정합성 보장이 쉬움 Redis Key Redis 키를 잘 설계 하는것도 중요하다...
레디스(Redis)의 다양한 활용 사례 들어가기 전에 나는 아직 실력이 부족한 개발자여서 레디스=캐시 로의 의미로만 이해하고 있었다. 대부분의 서비스에서 단순 캐시용도로만 사용하기도 한다. 레디스에 대해 정확히 이해를 하지 않으면 성능이 제대로 나오지 않을 수도 있고, 제대로 활용하지도 못할 수도 있다. 레디스를 어떻게 배치할까? 캐싱 전략? 단순 캐시용도말고 다른 용도로는 어떻게 쓸까? 그래서 나의 부족한 지식을 채우기 위해 해당 포스팅을 작성하게 되었다. 캐싱 전략 - Look Aside ( = Lazy Loading ) 캐시를 옆에 두고 필요할 때만 데이터를 캐시에 로드하는 전략이다. ( key-value 형태로 저장됨 ) 데이터 가져오는 요청 Redis에 먼저 요청 -> 있으면 반환 없으면 데이터베이스에 데이터 요청 이 데이터를 레디스..
네이버 검색의 서비스 신뢰도 높이기 - SRE 들어가기 전 나는 B2C 서비스는 조그만 회사에서 밖에 경험해 보지 못했다. 그래서 네이버나 카카오와 같은 대기업이 요구하는 신뢰성에 비하면 항상 후한(?) 신뢰성만을 지켜왔다. 그렇기 때문에, 대규모 서비스에서 신뢰성 보장을 위해서 어떠한 노력을 하는지에 대해서는 전혀 알고 있지 않다. 그래서 이번 포스팅을 통해 사이트 신뢰성을 지키기 위해 무엇을 해야하는지 어떠한 점이 어려운지를 정리해 보려한다. ( 네이버 검색 SRE 시스템 블로깅을 참고로.... ) 신뢰성이란? 365일, 24시간 언제나 서비스가 정상적으로 무중단 제공되는 특성 네이버 검색 서비스에 SRE 도입한 계기 예측 할 수 없는 상황 : 지진이 일어나 검색 요청량이 폭증 하는 경우 스케일이 커질수록 새로운 방법론 필요 16년 9월 경주에서..
Spring DeleteAllBy...In 호출시 에러 ( TransactionRequiredException ) 문제 상황 : deleteAllByIdxIn 호출 시 entitymanager가 왜 없을까? JPA OSIV라면 기본적으로 트랜잭션 범위는 서비스 단까지 있을테고, entity manager는 생성됐을 것이다. 그런데 왜 아래와 같은 에러가 났을까?? javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call @Service @AllArgsConstructor public class ItemServiceImpl implements ItemService { private final It..
토비의 스프링 6장(4) - 스프링의 프록시 팩토리 빈 스프링의 프록시 팩토리 빈 이전까지 자바를 이용하여 기존 코드 수정없이 부가기능을 추가해주었다. 이제 스프링에서는 어떠한 방식으로 추가해주는지 살펴보자. ProxyFactoryBean 자바 JDK에서 제공하는 다이나믹 프록시 외에도 편리하게 프록시를 만들 수 있도록 지원해주는 다양한 기능이 있다. 스프링은 프록시 오브젝트를 생성해주는 기술을 추상화한 팩토리 빈을 제공해준다. package com.waug.common.currency.service; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import static org.hamcrest.MatcherAssert.a..