TaskScheduler를 통한 동적 스케줄링
·
프로젝트/COTATO.KR
TaskScheduler를 통한 동적 스케줄링코테이토 프로젝트에서 출석 입력 기능을 개발 이후, 운영진의 출결 입력 안내가 없더라도 사용자들이 세션 시작 시간이 되면 출결 입력을 할 수 있었으면 좋겠다는 니즈가 있었다.따라서, 출석 입력이 허용되기 시작하는 시간에 사용자들에게 출결 입력 알림을 전송이란 기획이 추가되었다.해당 기능 개발을 위해 2가지에 대한 고민이 필요했다.서버가 클라이언트에게 출결 입력 시작을 알리는 방법유저가 지정한 시간에 알림을 전송하는 방법첫번째 고민에 대해서는 서버 → 클라이언트의 단방향 전송을 위한 Server Sent Event를 사용하기로 결정했다.(구체적인 이야기는 다른 글에서 다루도록 하겠다.)이 글에선 두 번째 고민인 유저가 지정한 시간에 동적으로 서버에서 스케줄링을 ..
ThreadLocalRandom을 활용한 성능 개선기
·
프로젝트/COTATO.KR
ThreadLocalRandom을 사용해 성능 개선하기문제현재 이메일 인증 랜덤 코드를 발생할때 요청 이후 인증코드 발송까지 꽤 오랜시간이 걸리는데, 클라이언트에서 인증코드 발송 요청을 보낸 후 요청이 성공했다는 서버의 응답이 오면 아래와 같은 팝업을 띄운다.문제는 서버에서 response자체가 오래걸려 인증 메일 발송 완료 팝업 이 뜨는데 오래 걸리고, 인증 메일 발송 버튼이 계속 활성화 되어 유저가 여러번의 인증 메일 발송을 요청하는 문제가 있었다.즉, 서버의 응답 시간이 늦어 유저가 여러 요청을 하게된 것이다.우선적으로 프론트엔드에서 응답이 오지 않더라도 팝업을 띄우고 버튼을 비활성화하는 방법을 마련했지만, 서버측에서도 요청시간을 줄일 필요를 느꼈다.Random 클래스 사용현재는 java.util...
지속 성장 가능한 코드: import문도 코드이다.
·
프로젝트/COTATO.KR
지속 성장 가능한 코드: import도 코드어느 덧 9기가 끝나가며 자신있게 출시(?)한 프로젝트를 운영한지도 6개월이 되어간다.그냥 박치기로 시작했던 프로젝트를 운영까지 하고 있으니 리팩토링을 하거나 새로운 기능을 짤 때 ‘변경한 코드의 파급력’을 고려하지 않을 수가 없다.그렇다고 확장을 하지 않을수도 없는데, 크고 작은 기능이 추가되며 하나의 클래스에 메서드가 증가하고 의존성이 더해지며 코드가 복잡해지는데 기수가 끝나가는 하나의 전환점인 지금 아래와 같은 고민이 생긴다. 지금 우리의 프로젝트는 새로운 개발자가 와서 읽기 좋은 구조인가? 언젠가는 누군가가, 적어도 ‘홍보’ 관련 도메인은 가져가야하는데 이게 맞나 싶은 포인트가 생겨 고민이 드는 요즘이다.이게 맞나?import 문에 와일드 카드 사용을 하..
Refresh Token Rotation
·
프로젝트/COTATO.KR
일반적으로 인증과 인가를 구현할 때, AccessToken과 RefreshToken을 사용한다. 우리 프로젝트에서도 둘을 활용한 인증을 구현했는데 이번 글에선, COTATO 프로젝트의 인증, 인가를 구현하며 고민한 RefreshToken 탈취 문제와 관련된 내용을 정리하겠다.배경 지식해당 글을 위해선 인증과 인가, 토큰 인증 방식에 대한 이해가 필요한데 공부가 급하다면 우선은 아래와 같은 내용으로 이해하자. 인증 : 너가 너가 맞는지 확인하는 것인가: 너가 자격이 있는지 확인하는 것토큰: 서버의 부담을 덜기 위해, 사용자에게 입장권을 주고 입장권이 적절한지 확인하는 방식세션: 인증된 사용자의 목록을 서버에서 관리해 인증하는 방식AccessTokenAccessToken이란, 일반적인 웹 어플리케이션에서 사..
선착순 퀴즈 프로젝트 V1 회고
·
프로젝트/COTATO.KR
지난해 10월부터 진행한 선착순 CS퀴즈 프로젝트의 버전1이 마무리되고 이제 버전2를 운영 중이다.버전2에선 해당 사이트를 동아리 홍보 사이트, 운영 과정에서 부원 필요 기능 추가 등을 목적으로 확장 중에 있는데 보다 나은 버전2 개발 진행을 위해 프로젝트를 진행하며 느낀점, 리팩토링 과정에서 느낀 아쉬움과 운영 과정에서 필요를 느낀 내용에 대해 KPT 회고를 해보고자 한다.선착순 퀴즈 프로젝트란?사전에 등록된 문제에 대해 관리자가 실시간으로 문제 풀이가 진행된다. 이 중 가장 빠른 정답자를 득점자로 인정하고 이를 통해 우승자를 결정하는 프로젝트이다.기획 의도7, 8기 교육팀으로 활동하며 교육을 진행하고 CS퀴즈를 진행했다. 기존 기수엔 카카오톡 채팅방을 통해 아래와 같이 가장 빠른 정답자를 득점자로 인..
선착순 로직 개선기 (2) - Redis 분산락
·
프로젝트/COTATO.KR
지난 글에선, 낙관적 락을 사용하기, 테이블 구조 변경을 통해 선착순 제출 로직의 동시성 문제를 해결했다. 이 글에선 테이블 구조를 별도로 변경하지 않고 Redis의 분산락을 통해 문제를 해결해본 과정을 적을 예정이다.Redis를 통한 동시성 해결동시성 문제가 발생하는, 락이 필요한 부분은 ‘정답 제출’하는 득점자를 생성하는 과정이다.제출한 요청 중 ‘정답’으로 판별된 내용을 기준으로만 득점자를 파악하면 된다.따라서, 아래 득점자 확인 및 등록 로직에 대해서만 lock을 적용하면 된다.득점자 존재 여부를 확인한다.존재한다면, 본인이 더 빠른 요청일 경우, 존재하지 않으면, 본인을 득점자로 생성한다.Lettuce 분산락redis의 setnx 명령어를 통해 분산락을 구현할 수 있다.. 특정 키에 대한 va..
선착순 로직 개선기 (1) - 낙관적 락 활용
·
프로젝트/COTATO.KR
개요CS퀴즈 프로젝트의 핵심 로직은 ‘선착순’으로 가장 빠른 정답을 제출한 득점자를 확인하는 것이다.따라서, 여러 정답자 중에 가장 빠른 정답자의 득점 기록을 바탕으로 득점자를 생성해야한다.문제풀이의 기본적인 로직은 아래와 같다.관리자가 문제 풀이를 허용한다.부원들이 문제 풀이 신호를 확인한다.정답을 제출한다.정답 요청이라면, 득점자가 존재하는지 확인한다.득점자가 존재하지 않는다면, 해당 요청을 기반으로 득점자를 생성한다.하지만, 일반적인 로직을 통한 구현은 동시성 문제를 겪기 쉬운데 이 글에선 여기서 발생하는 동시성 문제와 해결책을 담은 예제를 통해 찾아보도록 하겠다.우선, 위에서 말한 로직을 간단하게 구현하면 아래와 같다.@Transactionalpublic ReplyResponse submitAns..
Enum 그룹화를 통한 MemberRole 관리
·
프로젝트/COTATO.KR
현재 CS 퀴즈 프로젝트에서는 회원 역할을 통해 권한을 부여하고 있다.Ver1에선 대표적으로 아래와 같이 권한을 구분한다.현재 활동중인 부원(MEMBER) : 문제 풀이 가능교육팀원(EDUCATION) : 문제 업로드 및 풀이 진행, 결과 확인 가능운영진(ADMIN): 부원 관리 기능 및 모든 기능 가능//MemberRole.javaREFUSED("ROLE_REFUSED"),GENERAL("ROLE_GENERAL"),MEMBER("ROLE_MEMBER"),OLD_MEMBER("ROLE_OM"),ADMIN("ROLE_ADMIN"),EDUCATION("ROLE_EDUCATION");이외에도 현재 활동 중이지 않은 OM, 거절된 사용자, 승인 대기중인 부원 등 총 6가지의 역할이 존재한다.지금까진 특정 API..
정답 제출 API 멱등성 처리하기
·
프로젝트/COTATO.KR
앞선 글에서 HTTP 멱등성과 API의 멱등성을 구현하는 과정에 대한 내용을 정리했다.이번 글에서는 현재 Cotato 정규 세션 문제 풀이에서 사용하는 로직인 ‘정답 제출’ API에 멱등성 처리를 하는 과정을 글로 정리하겠다.정답 제출 API의 멱등성 처리 필요성정답 제출 API의 서비스 로직을 간단하게 정리하면 아래와 같다.정답이 아니면 제출 기록을 생성 후 저장한다.정답인 경우이미 득점처리가 되었는지 확인한다.득점자보다 해당 제출 기록이 더 빠르면 득점자로 대체한다.득점자보다 느리면 단순히 기록을 저장한다.이때 핵심은 정답 처리가 된 요청은 하나만 생성되어야한다는 점이다.하지만, 우리는 선착순으로 득점자를 정한다. 그렇기 때문에 사람들은 풀이가 허용되는 시점 이전에 무수한 요청을 보내는데 요청이 처리..
멱등성을 통한 정답 제출 API 중복 요청 방지 (이론)
·
프로젝트/COTATO.KR
지난 4월 27일 토스 서버 개발자 챌린지를 보며 결제 요청 타임아웃 처리에 관한 서술형 문제를 봤다. 💡 결제 요청간에 타임 아웃이 발생했다. 해당 요청이 성공했는지 실패했는지 사용자는 알지 못하지만, 결제 요청이 2번되어서는, 안되어서는 안된다. 어떻게 이 문제를 해결할 수 있을까?나는 이 문제에 답을 하지 못했는데, 이후 오픈카톡방의 후기를 보니 ‘멱등성’을 통해 결제 요청 처리를 한다는 이야기가 나왔고 관련된 검색을 하던 중 토스의 멱등성에 관한 글을 읽게 되어 멱등성에 대해 공부하게 되었다.읽고보니 비슷한 상황으로 인해 우리 코테이토 문제 풀이 요청 또한 결제 과정과 유사한 부분이 많다고 느껴졌고 멱등성 처리를 할 필요가 있다는 생각이 들었다.따라서, 오늘은 멱등성에 관한 내용을 정리하고, 이..
유쓰응
'프로젝트' 카테고리의 글 목록