Giter Club home page Giter Club logo

42partner-backend's Introduction

42partner-backend's People

Contributors

xogml123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

42partner-backend's Issues

[Refactor] Multi module 구조로 변경.

1. 기존 코드 문제점

  • spring batch 기능을 추가할때 module을 분리하여 따로 빌드할 필요가 있음.

2. 리팩토링 내용

  • api, core, common, batch 등으로 모듈을 불리할예정.

[Enhancement] randomMatch batch에서 redis transaction 하나로 모으고 db commit바로 직적으로 옮김.

1. 기존 상태

  • random match batch 에서 redis 트랜잭션이 적용되어 있지 않음.
  • redis에 상태 변경 쿼리를 날리고 커밋하는 트랜잭션을 하나로 묶어야함.
  • 마찬가지로 mysql에 날리는 commit도 하나로 묶어야함.
  • mysql commit바로 이전 시점에 redis commit을 하여 둘중 하나만 commit되는 것을 최대한 방지
  • 원래는 둘 모두 commit 되게 하거나 rollback되도록 해야하지만 2 Phase commit을 redis가 지원하지 않고
  • event Queue등을 활용하기에는 시간이 부족하여 이렇게 임시방편으로 활용.

2. 성능 개선 지점

  • 트랜잭션을 한번에 진행하기 때문에 성능이 향상됨.
  • 데이터 정합성이 (redis, mysql간의) 떨어지는 경우가 발생할 수 있지만 실질적으로는 거의 발생하지 않게 됨.

3. 예상 결과

[Enhancement] Redis 분산 캐시 Article 조회 시 적용.

1. 기존 상태

  • 성능 테스트결과 DB병목 확인
  • 캐시 없음.

2. 성능 개선 지점

  • article 조회 시 Throughput상승
  • article 조회 시 Response Time 상승.
  • DB부하 줄이기 위해 분산 캐시 활용, local cache는 데이터 정합성을 맞추기 힘들고 SSEmitter in-memory 저장 및 현재 heap memory 용량상 예상치 못한 메모리 관련 에러 발생 가능성 때문에 분산캐시 활용. DB부하를 줄이기 위한 목적이 크기 때문에 분산캐시로도 충분하다고 판단.
  • Write Through
  • 적정한 TTL만료시간 설정(현재는 10초 예상.)

3. 예상 결과

  • db 조회 부하 완화로 같은 조건 시나리오의 부하 테스트 시 DB 부하 개선. 및 RDS CPU 사용률 감소.
  • Throughput상승 및 Response Time정상화(현재는 병목 지점에서 5초까지 상승.).

[Enhancement] 오프셋 기반 Select 쿼리, 커서 기반 Select 쿼리로 변경 및 부하 테스트

1. 기존 상태

  • 목록을 받아오는 API의 경우 오프셋 기반으로 요청을 하게됨.(Slice라서 Count를 하지는 않음.)
  • 현재 Frontend API의 스펙을 변경시킬 수는 없기때문에 Version 2 API 로서 구현할 계획.
  • RDBMS의 성능 개선을 보기위해 Redis 캐싱 기능 배제하여야함.

2. 성능 개선 지점

  • 테이블의 레코드가 많은 경우 OffSet기반일 때 Offset적용을 위해 스토리지 엔진으로 부터 읽어와야 하는 레코드가 많아지기 때문에 이부분을
    커서 기반으로 변경할 경우 I/O감소로 성능 향상이 기대됨.
  • RDS의 메모리 , I/O를 주로 보고, CPU성능 부하도 볼 계획.

3. 예상 결과

  • 동일 시스템 스펙에서 전반적인 조회 TPS, 응답속도 향상이 기대됨.
  • RDS의 메모리 사용량, I/O등이 감소할 것으로 예상됨, CPU사용률의 경우 감소한다는 보장은 없을듯함.

[Feature] RandomApply API구현

1. 기능 상세

  • 랜덤매칭 참여

    • 참여 가능 여부 판단
      • 이미 매칭에 참여 중인지
      • 매칭이 맺어진지 얼마나 되었는지
        • 매칭 맺어지고 3시간 동안은 사용 불가
  • 랜덤매칭 참여 취소

    • 매칭 참여 하고 있는지 판단
      • 참여 하고 있다면 제거
  • 매칭 맺어진 후 취소

    • 기본적으로 불가하게 하는게 나을거 같음.
    • 일방적으로 안나온 사람에 대해서 어떻게 패널티?
    • 후기 시스템으로 처리.
      • Match에 상태는 항상 완료로 하는게 맞음.
  • 랜덤매칭 매칭 맺어주기

    • 매칭 완료 시 알림
  • 랜덤매칭 매칭 현황 보기. //일단 구현안함.

    • 매칭현황 보여주기 위해서는 복잡한 로직 필요.
  • 매칭 조건 입력 시 각 조건을 기준으로 경우의 수로 등록.

  • time out 30분

  • Redis SortedSet활용

    • 키 값
      • 밥 : place(20, padding’.’)&WayOfEating(20)&createdAt(먼저 들어온 게 먼저 매칭되기 위해서)&member:id
    • value 는 항상 0
    • 정렬된 상태로 조회하여 해당 사람수 만큼 매칭 가능한지 점검
    • 매칭 가능하면 매칭 맺어주고
    • 매칭 불가능 하면 해당 인원수 묶어서 데이터로 저장.
    • 방의 개념으로 하는게 나을지

2. 수정, 리팩토링, 버그발생 예상 지점

[Enhancement] JMeter 부하테스트 DBCP, Thread Pool 조정

1. 기존 상태

DBCP, Thread Pool 이 기본으로 설정되어있음.

2. 성능 개선 지점

DBCP가 적게 되어있어서 병목이 발생함.
Thread pool이 무한정 증가하는 것을 막을 수 있음.

3. 예상 결과

병목 제거 및 하드웨어 자원 활용.

[Refactor] 배치에서 주기적으로 수행하던 랜덤 매칭 조회 및 매칭 맺어주는 로직 랜덤 매칭 신청 api에서 event produce하는 식으로 변경

1. 기존 코드 문제점

  • scheduling 작업을 통해 랜덤매칭을 주기적(10초)으로 조회하고 매칭 조건을 맞는 대상을 맺어줌.
  • polling으로 인해 불필요한 조회가 지속됨.
  • 배치 서버가 따로 필요함.
  • 기존에는 해당 코드를 랜덤 매칭 신청 시 수행할 경우 동시에 요청이 들어오거나 할 때 매칭이 맺어질 수 있음에도 맺어질 수 없는 경우(거의 동시에 요청이 발생한 경우)가 발생할 수 있었음.

2. 리팩토링 내용

  • 해당 코드를 매칭 신청 시 이벤트큐에 produce하는 형태로 변경
  • 혹시나 이벤트 consume(랜덤 매칭을 맺어주는 작업을 수행)가 실패하더라도 ack를 통해 재실행을 보장하고 매칭이 맺어질 수 있는 환경에서 무조건 맺어지도록 할 수 있음.
  • event queue를 활용하여 비동기적으로 하나의 api 요청자체와 무관하게 동작시킬 수 있음.

[Refactor] RandomMatch에서 Redis제거

1. 원래 Redis를 사용한 이유

  • SortedSet 자료구조로 해주기 때문에 저장 해서 매칭 기록을 관리하는 것 만으로도 매칭 로직을 간접적으로 구현할 수 있음.
    • SortedSet의 key값을 매칭 조건을 조합해 만든 문자열로 만들면 매칭 채널을 분리할 수 있음
    • SortedSet 내에서 score와 Value를 기준으로 정렬되어 저장됨.(Tree구조)
    • 원래는 Score값을 기준으로 정렬 하지만 Score값이 같으면 value를 기준으로 정렬이 이루어지고 value값에 매칭 신청 시간 + memberId 값의 구조로 만들면 매칭 신청 시간을 기준으로 정렬됨.
    • appliaction Server에서는 SortedSet들을 조회해 SortedSet내부의 요소개수가 매칭 인원을 충족하는지만 검사하면됨.
  • 매칭 신청 데이터는 schema가 변동 가능성이 크고 데이터가 오래 잘 유지 될 필요는 없는 데이터라고 판단 했음.
  • In memory이기 때문에 RDB에 I/O 속도 측면에서 더 빠르고 RDB로 구현 할 경우 application Server에서 신청 기록을 분류하고 정렬하는 작업을 매 batch program이 수행해야함(Redis는 저장하는 것 만으로 이작업이 처리됨).
  • RDB의 부하를 줄여줄 수 있음.
  • 공부 목적.

2. 개발 과정에서 생긴 여러 문제점으로 Redis포기

  • 분산된 여러 DataSource를 사용하게 되면서 각각의 노드간에 데이터 정합성 불일치의 문제가 생길 수 있고 이를 관리하는 것이 매우 힘들다는 것을 알게됨.
    • 대표적으로, Batch server가 Redis를 조회하여 매칭이 가능한것을 확인하였을 때 먼저, Redis에서 신청 기록을 제거하고 매칭이 맺어진 결과를 RDB의 Match table에도 저장해야함. 이 과정이 하나로 atomic 함이 보장 되지 않으면 데이터 일관성 손상될 수 있음. 매칭이 한번 이미 맺어졌지만 Redis에서 신청기록이 제거되지않아 Batch server가 실행될 때마다 무한하게 매칭이 맺어질 수 있음.
    • 이를 해결하기 위해서는 2 Phase Commit을 활용하거나 메세지 큐 같은 것을 추가로 활용하여 Redis, RDB 모두 Rollback하거나 Commit해야함.
    • 문제는 Redis가 2 Phase Commit을 지원하지 않고 지원하더라도 2 Phase Commit은 트랜잭션을 자신의 데이터를 처리하지 않는 시간에도 오래 지속해야하기 때문에 성능적인 낭비가 있음.
    • 메세지 Queue를 추가로 도입하기에는 학습을 해야할 뿐만 아니라 배보다 배꼽이 커지고 있다는 생각이 듬.
  • Redis를 활용해 매칭 batch application에서 최초 매칭 신청 현황을 보고 매칭 결과를 exec하는 구간에서 데이터 변경을 막기가 매우 힘듬.
    • Batch server에서 매칭을 맺어주는 것과 매칭 취소 신청은 Serializable 하게 이루어 져야 하고 이를 Redis로 구현할 경우 transaction을 사용하여 해결 할 수 있을 것으로 생각함.
    • 문제는 Spring 에서 사용하는 RedisTemplate의 경우 Transaction사용 시 조회 할 때 항상 null을 return 함. (Redis 트랜잭션을 한 단위의 네트워크 통신하는것으로 생각하기 때문에 트랜잭션 내에서 조회를 하더라도 조회가 되지않고 트랜잭션)
    • 다른 방법으로 Watch를 활용해 락을 걸고 조회는 외부에서 하는 방법이 있는데 낙관적 락임에도 매칭 신청, 취소 요청과 batch 프로그램 매칭을 맺어주는 로직 사이에 충돌이 빈번하여 문제가 될 수 있음. 이를 처리하기 위한 로직을 추가로 굉장히 많이 작성해야함.
  • RDB로 데이터를 작성하여 비지니스로직을 작성했을 때와 달리 코드가 매우 복잡하고 관리하기 힘들어짐.
    • 매칭 저장 SortedSet의 경우 <String, String>의 형태를 가지고 있을 뿐인데 여기에 비지니스 로직을 작성했을 때 알아보기도 힘들고 객체 지향적인 코드도 아니면서 테스트하기 힘든 코드가 작성되었음.

[Enhancement] TTL 만료를 방지 목적 Probabilistic Early Recomputation 사용및 부하 테스트

1. 기존 상태

  • Redis cache 만료 시간 TTL이 5초로 되어있음.

2. 성능 개선 지점

  • TTL 만료시 HotKey인 경우 Cache Stampede현상이 발생할 수 있음.
  • 이를 대비하기 위해 Probabilistic Early Recomputation을 도입. -> 자주 참조되는 키는 확률적으로 만료 전에 갱신됨.

3. 예상 결과

  • TTL만료 시 RDBMS로 부하가 쏟아지는 Cache Stampede 현상을 줄일 수 있을 것으로 예상됨.

4.먼저 해결해야하는 부분

  • JMeter를 Local 에서 실행하고 있는데 Thread 생성 개수 제한이 있고 부하 테스트 제한이 있기 때문에 분산환경으로 올려야할 필요가 있음.

[Fix] 로그인 실패시에도 frontend로 Redirection, 랜덤 매칭 참여자수 버그

1. 수정 이유

  • 로그인 실패시 api 페이지가 그대로 보이며 프론트엔드로 리다이렉션 되지 않는 문제가 있음.

2. 수정 내용

  • 로그인 실패시 frontend 루트로 Redirection하고 쿼리 파라미터로 login_success=fail을 보냄.
  • 랜덤 매칭 참여자가 조건 개수만큼으로 계산되는 버그 쿼리를 수정해야함.

[Feature] RandomMatch, Redis 기본 설정 및 API prototype

1. 기능 상세

  • Redis Client 설정
  • RandomMatch 신청
  • RandomMatch 취소
  • RandomMatch 상태 조회(api 조회 형식으로 할 지, 서버에서 배치서버가 주기적으로 응답주도록 할지, 아예 안할지) - 매칭 여부는 알수있어야함 DB에서 Match에서 Random + createdAt이전에 된걸로 조회해서 확인.
  • Spring batch 매칭 or scheduling
    • RandomMatch전체 조회
    • transaction start
    • RandomMatch 매칭 맺어질 사람 있는지 확인
    • Random Match매칭 맺어지면 RandomMatch 정보 삭제
    • Match table에 등록
    • transaction end
    • Async로 slack알림 주기.

2. 수정, 리팩토링, 버그발생 예상 지점

[Enhancement] ArticleService에서 OptimisticLockException AOP로 처리

1. 기존 상태

  • @Version annotation으로 인해 OptimisticLockException 발생 가능

2. 성능 개선 지점

  • 낙관적 록으로 인한 충돌이 발생하면 재시도 하는 기능을 추가한다.
  • AOP를 통해 핵심기능에서 벗어난 재시도 보조기능을 공통관심사로 관리할 수 있게 된다.

3. 예상 결과

[Enhancement] JWT Refresh token 부여로 보안성 강화

1. 기존 상태

  • access token만을 인증에 활용하여 만료기간을 길게 두었기 때문에 보안상 취약점이 있었음.

2. 성능 개선 지점

  • access token의 만료 시간을 5분으로 두고 refresh_token의 만료 시간을 2주로 두어 보안성 강화

3. 예상 결과

  • 전반적인 보안성이 강화됨.
  • refresh token을 어디에 보관할 지 고민해야봐야함. 현재로서는 브라우저의 cookie에 저장하는 방식 고려중.

[Fix] 알림 기능 구조 변경

1. 수정 이유

  • kafka를 통해 알림을 생성하는 것과 sse알림을 보내는 기능이 하나의 consumer이 수행함.
  • 트랜잭션 내에서 kafka 이벤트를 발행하기 때문에 롤백 되어도 이벤트가 발행될 수 있음.

2. 수정 내용

  • 알림을 생성하는 것과 sse알림을 보내는 것을 같은 이벤트에 대해서 다르게 처리하는 Consumer group두개로 분리 및 Kafka Consumer Config변경
  • 트랜잭션 외부에서 이벤트 발행

[Feature] 알림 기능 추가(SSE)

1. 기능 상세

  • sse를 활용하여 백엔드에서 프론트로 알림 제공.
  • 내가 참여한 글이 확정 된 경우.
    • 식사인지 공부인지, 글 제목, 확정자 수
    • 자세한 매칭 내역 링크
  • 랜덤매칭이 잡힌 경우.
    • 매칭 인원들, 식사 인지 공부인지
    • 자세한 매칭 내역 링크
  • 내가 작성한 글에 누군가 참여한 경우.
    • 참여한 사람 + 현재 인원수
    • 글 링크
  • 내가 작성한 글에 누군가 참여를 취소한 경우.
    • 취소한 사람 + 현재 인원수

2. 수정, 리팩토링, 버그발생 예상 지점

  • 알림을 주는 시간과 대상 내용이 달라질 수 있음.

[Feature] CICD dev서버에 dev브랜치로 적용.

1. 기능 상세

  • EC2단독으로 되어있는 dev서버에 dev 브랜치 push시 자동적으로 빌드 및 배포 되도록 CICD파이프라인 구성
  • 실제 운영 서버는 Main 브랜치에 push시 CICD시 적용되도록 따로 설정
  • ASG를 사용중이기 때문에 이 부분에서 더 학습해서 추가해야함.
  • appspec.yml, github action의 deploy.yml, ec2내에 code-deploy-agent 설치 및 실행

2. 수정, 리팩토링, 버그발생 예상 지점

[Feature] 식사동료 방 게시글(Article) API

1. 기능 상세

  • 제목
  • 항목별 선택(방 전체 목록에서 보여주기 위해서)
  • 본문

2. 수정, 리팩토링, 버그발생 예상 지점

  • 댓글 -> Opinion에서 다시 만들것.
  • 댓글은 대댓글로 변경될 수 있음.

[Feature] OAUTH 42Seoul Intra SignUp, login InMemory에 Session저장하는 방식.

1. 기능 상세

  • 처음 OAUTH로그인 실행시 회원가입 진행
  • Access Token은 바로 폐기 (분실 시 authorization server 까지 계정정보가 털릴 우려가 있으며, 로그인 된 상태에서 다시 자원을 요청할 일이없음.)
  • Session을 통해 로그인 시간 관리.

2. 수정, 리팩토링, 버그발생 예상 지점

  • Session Redis에 관리.

[Feature] spring batch 랜덤 매칭 서버 구현.

1. 기능 상세

  • 주기(10초~20초)적으로 랜덤 매칭을 맺어줌.
    • 모든 방 조회(Set으로 가져오기, 정렬된 set).
    • 모든 방 스캔하면서 생성된지 30분이 넘은 데이터 collection에서 제거하고 따로 id값 기입.
    • 각 방 조회 순서 랜덤으로 정함(여러 매칭 조건이 가능한 경우 평등하게 매칭이 되게 하기 위해서).
    • 매칭인원(4명 예상)이 되면 생성 시간 기준 빠른 사람 부터(queue)4명씩 짝지음.
      • 짝 지어진 경우 collection 에서 바로 제거하고 따로 id값 저장.
      • 모든 매칭이 끝 난경우 매칭이 끝나거나, 만료된 사용자 redis에서 지우고 DB에서 isCanceled = true로 바꿈.
      • 매칭 된 사용자 로 Match table db생성, random 신청 내역과 연결하는 것은 생각해 봐야할 것 같음.
      • Activity점수 부여
      • 알림(비동기)
  • quertz로 이 행동을 주기적으로 실행시킴
  • 배포 시 spring batch서버를 따로 띄움.- stand by로 ec2하나 더 있으면 좋을 것 같음.

2. 수정, 리팩토링, 버그발생 예상 지점

  • isCanceled라는 이름보다 만료 되었다 정도의 의미가 더 나을 것 같음.
  • 트랜잭션 구간을 어떻게 설정할지(중간에 예외 발생 시 어떻게 처리할지), 비동기 기능 어떻게 db랑 분리할지.
  • redis의 트랜잭션에 대한 이해,

[Feature] 프로젝트 구조 설정

1. 기능 상세

  • 프로젝트 구조 설정
  • 디렉토리 구조
  • swagger, BaseEntity,

2. 수정, 리팩토링, 버그발생 예상 지점

  • 없음

[Enhancement] RandomMatch Table 매칭 조건 멀티 키 인덱스 수정 및 옵티마이저 실행 계획 확인

1. 기존 상태

  • 멀티 키 인덱스의 경우 컬럼 순서에 따라 인덱스 적용이 달라질 수 있다는 것을 알게됨
  • 기존의 방식의 경우 쿼리문을 통해 인덱스가 잘 적용되지 않는 경우였음.
  • ConditionCategory,

2. 성능 개선 지점

  • 멀티 키 인덱스가 where 조건절 사용 시 인덱스 레인지 스캔을 할 수 없는 방향으로 작성되어 있었음.
  • 반정규화된 테이블 이기 때문에 각각 멀티 키 인덱스를 적용해야함.

3. 예상 결과

  • index full scan -> index range scan
  • 옵티마이저 실행 계획을 공부해서 분석해볼 계획.

[Refactor] Article, Match, Activity구조 개선.

1. 기존 코드 문제점

  • Article, Match, Activity에서 연관관계가 달라지는 경우에만 상속으로 Inheritance활용하는 것으로 결론.
  • MatchCondition 활용 할때 외래키 둘 필요 없음.
    • Match, Activity만 수정

2. 리팩토링 내용

  • 공부, 밥의 경우 enum필드로,
  • Match만 랜덤, 방에 따라서 나누어 주면 됨.
  • Activity의 경우 점수 부여 이유를 어떻게 줄까 Match와 연관 관계 맺기 (만약 향후 댓글 등록 시에도 점수가 부여된다고 하면 이것도 추가 하면 될것.)

[Refactor] test 코드 리팩토링 및 production code를 test하기 적합한 코드로 리팩토링

1. 기존 코드 문제점

  • test code 에서 불필요한 객체를 생성하거나 테스트 메서드 명이 불 명확하거나 하나의 메서드에서 여러 케이스의 테스트를 진행하는등의 문제가 있음.
  • 프로덕션 코드가 테스트 하기 부적합한 경우가 있음.
  • Service Layer및 통합 테스트가 적절히 수행되지 않은 경우가 있음.

2. 리팩토링 내용

  • test code 메서드 명과 given영역을 복잡하지 않게 리팩토링
  • 프로덕션 service 코드에서 entity 생성, 수정 시 id 값만 반환하는 경우가 있는데 전체 entity를 반환하도록 수정.
  • 전반적인 테스트 코드 더 다양하게 수정.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.