분류 전체보기

    상품 목록 조회 시, 페이징 처리 성능 개선

    현재 굿즈포유 프로젝트에서는, 다음과 같이 등록된 상품의 목록을 조회할 수 있는 기능이 있습니다. 굿즈포유 서비스의 메인이 되는 화면이기에 메인 기능이라고 볼 수 있습니다. (페이징 처리 관련한 코드를 확인하고 싶으신 분들은 링크를 참고해주세요) 이러한 상품 목록을 조회기능을 구현할 때, 단순히 아래와 같은 쿼리를 이용해 구현할 수도 있습니다. SELECT * FROM PRODUCT; 만약, 해당 서비스에 등록된 상품의 수가 적은 경우에는 별다른 문제점이 없을 것 입니다. 하지만 적재된 데이터가 10만 건, 100만건.. 많은 양의 데이터가 존재한다면 테이블 전체를 스캔하는 쿼리의 작업 시간은 매우 오래 걸릴 것 입니다. 위 그림은 실제로 약 102만건의 데이터를 조회하는데 걸린 시간입니다. 실행 시간은..

    JMeter를 통한 부하테스트

    현재 진행중인 굿즈 포유 프로젝트의 서버 성능과 가용성을 테스트 하기 위해 JMeter를 통해, 로그인 요청에 대한 부하 테스트를 진행했습니다. 위 그림과 같이로그인 요청에 대해, 토큰을 저장하는 레디스 서버와 웹 서버가 단일 인스턴스에 존재하는 형태에서의 테스트 결과 입니다. 테스트 시, user 수(Number of Threads)는 100명으로, 초당 요청(Ramp-up period)은 1번으로, 반복 횟수(Loop Count)는 1로 설정 했습니다. 즉, 100명의 사용자가 1초에 1개씩 요청을 보내는 상황을 가정했습니다. 단일 서버 환경에서의 굿즈 포유 서버의 처리량은 6.3TPS입니다. 단일 서버 환경에서 웹 서버 - 캐시 서버 - 데이터베이스 서버를 각각 분리한 후 처리량은 5.8TPS 입니..

    Spring Data Common 모듈 에서의 디자인 패턴

    Spring Data Common 개요 Spring Data Common 에서 Repository를 추상화해서 통해 얻고자 하는 목표는 다양한 영속성 저장소(RDBMS, NoSQL 등등..)에 대한 데이터 접근 계층을 구현할 때 필요한 상용구 코드의 양을 크게 줄이는 것 입니다.(Connection과 관련된 코드 등등..) Repository Spring Data Common 에서 Repository 추상화의 핵심 인터페이스는 Repository 입니다. 이 인터페이스는 관리할 도메인 클래스와 도메인 클래스의 ID 유형을 type arguments(Repository 와 같은 형식)로 받습니다. Repository 인터페이스는 주로 작업할 유형을 캡쳐하고, 이 인터페이스를 확장하는 인터페이스를 찾을 수 ..

    테스트 시, Redis Session 으로 인해 생긴 문제 해결

    문제 상황 현재 진행 중인 프로젝트에서, Redis를 세션 서버로 사용해 세션을 관리하고 있습니다. 테스트시에는 Redis를 이용한 세션관리가 아닌, spring 에서 기본으로 제공해주는 세션 관리 방법을 통해 세션 관리를 진행하려 했으나, 지속적으로 세션 관리 시, Redis가 사용되는 문제가 발생했습니다. org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis at 그로 인해 위와 같은 예외가 발생하게 되었습니다. 해당 예외는 레디스 연결에 실패했다는 예외 입니다.(테스트 시에는, 레디스가 구동중이지 않기 때문에 예외가 발생하는게 당연합니다.) 원인 분석 테스트 시에, 레디스 커넥션 관련 예외가..

    SOLID 원칙

    단 하나의 책임 원칙(SRP) 어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이여야 한다. 예시로 작성한 Employee 클래스 입니다. 이 클래스는 너무 많은 것을 알고 있습니다. Tax와 Pay를 계산하는 방법도 알고, 데이터베이스에 데이터를 저장하는 방법도 알고, XML로 만드는 방법도 알고 있습니다. 위와 같은 경우에 XML에서 JSON으로 파일 포맷 형식을 변경하게 되면, Employee 클래스가 변경되어야 하고, 데이터베이스를 MySQL 에서 Oracle 로 변경한다 하더라도, Employee 클래스가 변경되어야 합니다. 또한 Tax와 Pay의 계산 방식이 변경되면, Employee 클래스가 변경되어야 합니다. 따라서 각각의 책임을 다른 클래스로 분리하여, 클래스마다 변경해야 할 이유가 한가지..

    함수형 프로그래밍

    함수형 프로그래밍은 함수를 사용하여 문제를 해결하는 것을 강조하는 프로그래밍 패러다임 중 하나 입니다. 함수형 프로그래밍의 주요 특징으로는 다음과 같습니다. 특징 불변성 : 함수형 프로그래밍에서 데이터는 불변입니다. 한번 생성되면 변경할 수 없습니다. 이렇게 함으로써 불변성을 가진 데이터를 사용하는 함수에 부작용(Side-Effect)가 없게 되어 프로그램이 동작하는 방식에 대해 좀 더 쉽게 추론할 수 있습니다. 또한 불변성의 또 다른 이점으로 동시성 프로그래밍 시에, 데이터의 불일치 문제를 해소할 수 있습니다. 불변성을 가진 데이터는 여러 스레드가 공유되는 한 데이터에 접근하더라도 변경이 불가능하기에, 동시성 상황에서 자주 일어날 수 있는 문제인 데이터 정합성 문제를 방지할 수 있습니다. 변경이 가능한..

    SQL Injection

    개요 현재 진행중인 개인 프로젝트에서, mybatis를 이용해 쿼리문을 작성하고 있습니다. @Insert("insert into TRADE (buyer_id, seller_id, product_id,transaction_date,transaction_status,transaction_product_quantity) VALUES (#{buyerId}, #{sellerId}, #{productId}, #{transactionDate},#{transactionStatus}, #{transactionProductQuantity})") 위와 같이 직접 sql 문을 작성하고 있지만, #{buyerId} 와 같이 입력 값을 설정하게 된다면, SQL injection 공격에 더 안전한 PreparedStatement를..

    Builder 패턴?

    현재 진행중인 프로젝트에서, 유저의 거래 기능을 담당하는 도메인 객체인 Trade 객체를 생성시에, 파라미터로 5개의 변수를 받아야 하는 상황이 생겼습니다. 그에 따라 생성자 코드가 다음과 같이 public Trade(Long buyerId, Long sellerId, Long productId, LocalDateTime tradeDate, int tradeProductQuantity) { this.buyerId = buyerId; this.sellerId = sellerId; this.productId = productId; this.tradeDate = tradeDate; this.tradeStatus = TradeStatus.BEFORE_TRADE; this.tradeProductQuantity =..