시간측정 코드 기존 코드 : 태그마다 select -> insert, 총 쿼리 6번 수정 코드 : in쿼리로 한번에 select -> insert 3번, 총 쿼리 4번 키 생성 전략이 identity라 batch insert 불가능 결과 기존 코드 총 30ms대 조회는 거의 0~1ms, 저장이 1~2ms 수정 코드 총 50~80ms대 in 쿼리가 병목(3개 찾는데 20~30ms) 저장은 3번 합쳐서 2ms 결론 : 기존 코드 유지
실시간 모의면접 기능은 발표자의 영상을 얼굴만 바꿔 같은 방에 있는 다른 사용자들에게 보여줘야 하기 때문에, 초기 서비스 기획시점에는 웹소켓을 통해 비디오스트림을 서버로 보내면 서버에서 영상처리를 한 뒤 다른 사용자들에게 변형된 비디오스트림을 보내주면 될 것이라고 생각했다. 하지만 라이브 스트리밍 서비스를 구축하는 것이 생각보다 간단한 작업이 아니었고, 프로젝트 마감기한이 얼마 남지 않아 여러 시행착오 끝에 agora라는 서드파티의 sdk를 사용하여 라이브 스트리밍 및 버추얼 아바타 기능을 구현하였다. 라이브 스트리밍 서비스 라이브 스트리밍 서비스를 개발하는 과정에서 웹소켓만을 사용하려다 보니 생각하는 대로 개발이 이루어지지 않았다. 처음에는 단순하게 실시간으로 영상을 보내면 될 거라고 생각해서 전면카메라를 매 프레임마다 캡쳐해서 서버로 보내려고 했다. 하지만 클라이언트에서 원하는 대로 동작하지 않았고, 오디오를 보낼 방법이 마땅치 않아 다른 방법을 찾아보았다. 두번째
개발서버를 배포한 이후 웹소켓을 사용해서 실시간 모의면접 기능을 개발했는데, 프론트엔드쪽 작업량이 많아 급하게 플러터를 배우고 웹소켓 통신의 클라이언트측 코드를 개발하기 시작했다. 실시간 모의면접 기능은 같은 태그를 선택한 사람들을 매칭하고 서버에서 무작위로 해당 태그에 속한 질문을 뽑아주면 실시간으로 질문에 답변하는 영상을 공유하는 기능이다. 이를 구현하기 위해서는 실시간으로 서버와 클라이언트가 통신할 수 있어야 하기 때문에 웹소켓을 사용하기로 결정했다. 웹소켓 웹소켓이란 요청을 보내야만 서버로부터 응답을 받을 수 있는 HTTP의 한계를 해결하기 위해 등장한 프로토콜로, TCP채널을 통해 실시간 양방향 통신을 가능하게 해주는 Stateful한 프로토콜이다. 웹소켓에 대한 자세한 내용은 링크에 정리하였다. 설계 설계 초기에는 STOMP프로토콜을 이용하여 메세지와 비디오 스트림을 주고받으려 했지만 STOMP를 이용하여 바이너리 데이터를 주고받는것이 생각만큼 제대로
프론트엔드 개발을 맡은 팀원의 요청으로 개발 중반부에 api서버를 미리 배포하게 되었다. 지금까지 프론트엔드는 api문서를 보고 개발했기 때문에 임시 데이터만으로 개발을 진행하고 있었다. 그러다보니 데이터를 등록하는 부분이나 수정할 때 화면의 변화가 잘 동작하는지 확인하는데 한계가 있어서 임시로 개발서버를 올려달라는 요청을 받았다. 지난번 프로젝트에서는 서버를 배포할 때 로컬에서 깃허브에 코드를 푸쉬하면 서버에서 수동으로 코드를 받아와 실행하는 식으로 배포가 이루어졌는데, 이 과정이 꽤 번거로웠던 기억이 있어서, 이번에는 배포과정을 자동화하여 개발에 조금 더 신경쓸 수 있도록 배포 파이프라인을 구축하였다. CI/CD 파이프라인 구축을 위해 [스프링 부트와 AWS로 혼자 구현하는 웹 서비스]를 참고하였다. CI/CD 파이프라인 설계 나 _ @ManyToOne(fetch = FetchType.LAZY)_과 같은 부분은 Comment에서 설명한 이유와 같고, 여기에서 특징이 되는 부분은 category와 parent이다. 먼저 각 태그의 종류를 표현하기 위해 Enum타입으로 TagType을 정의하였다. 엔티티에 Enum타입의 필드를 선언하는 경우 반드시 @Enumerated(EnumType.STRING) 어노테이션을 통해 데이터베이스에 문자열의 형태로 저장될 수 있도록 설정해주어야 한다
Comment 사용자가 영상 게시판에 면접 연습 영상을 올리면 다른 사용자들이 영상을 보고 피드백을 해주는 기능이다. 일반적인 게시판의 댓글 기능과 유사하다. Domain Comment 데이터베이스의 Comment테이블에 해당하는 엔티티이다. id값은 DB에서 자동으로 생성되도록 Identity전략을 사용하여 위임하였고, jpql의 n+1문제를 방지하기 위해 모든 연관관계에 지연로딩 전략을 사용하였다. 또한 댓글에 달린 좋아요를 편리하게 확인하기 위해 CommentMemberLike테이블을 참조하는 likes필드를 만들어 매핑하였다. 또한 comment가 삭제되면 해당 comment에 좋아요를 누른 기록이 모두 삭제될 수 있도록 likes필드에 CascadeType.REMOVE옵션을 걸어두었다. 무분별한 생성과 수정을 막기 위해 Setter는 닫아두었으며 생성자를 통해서 초기값을 설정하고 update메소드를 통해서만 값을 변경할 수 있도록 구현하였다. 다만 스프
API 설계의 중요성 지난번 캡스톤 프로젝트를 진행하면서 가장 뼈아프게 느낀 점 중 하나가 바로 API였다. 제대로된 정보 없이 내 마음대로 API를 설계한 탓에 URL은 체계적이지 않고, 요청 및 응답형식 또한 정리되어있지 않아 설계 이후 개발과정에서 큰 혼란을 겪었다. 그래서 이번 프로젝트에서는 지난번 기억을 바탕으로 본격적인 개발에 들어가기 전에 최대한 구체적으로 API를 설계하고 이 문서를 바탕으로 기능을 개발하려 한다. RESTful API RESTful API에 관련된 내용은 아래 링크에 간략하게 정리 해 두었다. [엉박사] 1.10.2 Restful API API Document 이라고 함은 일반적으로 대학 고학년, 혹은 이미 졸업한 구직 활동을 하는 학생을 말한다. 기존에 다니던 회사를 그만두고 새롭게 직장을 구하려 하는 사람들 역시 포함하기도 한다. 2022년도 청년층의 취업실태를 보다 심층적으로 파악하여 고용정책 수립에 필요한 기초자료를 수립하기 위해 통계청에서 실시한 청년층 부가 조사에 따르면 2022년도 취준생 수는 70만 4천 명으로 집계되었다. 이 숫자는 전년 대비 16퍼센트 감소한 수치이지만 2021년 이전 5년 동안 계속해서 취준생 수는 증가하여 2021년에는 85만 9천 명에 달하였다. 또한 앞으로 많은 기업들이 금리 인상과 경기 침체 우려로 인해 취업 증가 폭은 2022년도 대비 대폭 감소할 것이라고 많은 전문가들이 전망하고 있다. 와는 다르게 개발을 하면서 그때그때 깨달은 점이나 새롭게 학습한 내용들을 정리할 계획이다. 프로젝트를 시작하며 지난번 캡스톤에서는 웹, API, 배포 등에 대한 기초적인 내용을 전혀 모르고 프로젝트에 들어가서 관련된 내용들을 찾는 데에 어려움이 많았다. 또한 다룰줄 아는 프레임워크 또한 유튜브 강의로 익힌 장고가 유일했기 때문에 다른 선택지 없이 장고를 통해 개발을 진행했다. 그 결과 기능구현에만 급급하여 어찌저찌 굴러는 가는 코드가 탄생했다. 그래서 이번에는 좀 더 준비된 상태에서 프로젝트를 시작하기 위해서 겨울방학동안 인프런에서 김영한 강사님의 스프링강의 로드맵을 타면서 객체지향과 JPA, 스프링 프레임워크에 대한 이해를 높였다. 또한 이전 프로젝트의