항해 99를 수료하고 나서, 이 글을 작성하게 됐다.
1. 항해 99를 선택한 이유
처음 항해를 선택한 이유는, 항해 1기를 수료한 친구의 추천과 가장 먼저 무언가를 배울 수 있는, 배움의 기회가
있었기 때문이었다.
당장 시작할 수 있고, 가격적으로 커다란 부담이 없으며 이미 이곳을 거쳐 개발자로서 현업에서
일하고 있는 지인이 내가 항해를 선택하게 된 이유였다.
2. 항해 99 장단점
* 장점
항해 99의 장점이라면, 정말로 빠르게 개발이 무엇인지에 대해서 감을 잡을 수 있다는 것이다.
첫 주차에 아무것도 모르는 핏덩이들을 대리고 게시판이든 뭐든 작은 프로젝트를 진행시키는 것부터 시작해서
점진적으로 개인 블로그를 만들고, 클론코딩과 마지막 실전 프로젝트를 통해 한 사람의 개발자로서
깊이는 모르겠으나 빠르게 API를 찍어낼 수 있는 실전적인 감각을 키워 준다고 생각했다.
그리고, 매 주차마다 주어지는 과제들을 수행하면서 볼 수 있는 선배 기수의 깃헙들을 열람할 수 있다는 점이다.
사람마다 코딩을 하는 방식이 다 다르기 때문에, 누구는 어떻게 짜고 누구는 이렇게 짜는데
이렇게 개인마다 다양한 코드를 사용하는 것을 보고 배울 수 있다는 장점이 있다. 실제로 매주차마다 과제들을 수행하면서
이렇게 누군가의 깃헙을 보고 내가 사용할 기술과 기술의 사용 방식에 대해서 배울 수 있다는 점은 커다란 메리트다.
9 to 9의 관리 시스템도 한몫한다고 생각한다. 다른 부트캠프나 국비는 어떻게 수강생들을 다루는지는 모르겠지만,
항해는 그렇게 타이트하게 조이진 않는다. 대신 메타버스 세계안에서 다른 항해 수강생들과 마주치기 때문에
자연스럽게 압박감과 긴장감을 느끼게 되고, 자유롭게 지식을 공유하는 과정에서 자연스럽게 9 to 9의 시스템이 지켜지게 된다.
나중에 실전가면 개인적인 성향에 따라 갈리게 되지만, 사람들은 대부분 기존 시스템을 지키려고 노력하는 편이며
무엇보다 중요한 것은 자연스럽게 그런 분위기가 조성된다는 것이며 9 to 9이 지나고도 새벽까지 열심히 하는 사람들을 지켜보면서 나 또한 의지를 불태울 수 있었다.
* 단점
항해 99의 단점은, 깊이가 부족하다.
99일이라는 시간동안 마지막 1주일을 제외하고 대략 3달가량의 시간동안, 개발에 전념한다고 하더라도 빠르게
개발자라는 직업의 선에 서게 만들어야 하기 때문에 깊이가 부족해진다.
알고리즘은 단 일주일간 배우기 때문에 스스로 찾아서 나중에 해야하는데, 항해의 다른 과제들을 수행하면서
알고리즘까지 한다는 것은 정말이지 쉬운 일이 아니다.
그리고 CS적인 지식도, 사실상 개인의 자율에 맡기기 때문에 강제성이 적은 항해99의 과정 특성상
자연스럽게 깊이가 깊어지지 않을 수 있다.
딱히 항해99의 단점이라기보다는 짧은 시간동안 해야하는 항해의 특성이라고 생각한다.
하지만, 알고리즘을 꾸준히 병행할 수 있는 커리큘럼이 된다면 더 좋지 않을까 라는 생각을 했다.
CS스터디를 진행하는 것보다는 계속해서 알고리즘 스터디를 운영하는게 더 좋지 않았을 까라는 생각도 들었다.
또 단점이 뭔가 기술 매니저들이 수강생들의 작업물에 큰 관심이 없어보인다는 점이다.
다 보고 온다고는 하는데, 클론코딩과 실전 프로젝트 때 내가 느낀 것은 눈에 보이는 발표 결과물에 대한 지적과 조언이고
프로젝트 내적인 정말 살펴보았어야 나오는 그런 지적들은 아니었다.
발표들을 보면서 나오는 지적들도 당장 도움되는 것도 아니었고, 좀 대체로 애매한 지적들이 많았다.
조금 더 수강생들의 작업물에 관심을 가지고 피드백을 줬으면 하는 아쉬움이 남았다.
사실 기술 매니저는 돈을 받는 입장이고, 수강생들은 돈을 내고 무언가를 배우러 온 소비자라는 생각을 한다면
조금 더 디테일한 무언가가 나오지 않을까 싶었다.
또 단점이, 무언가 자꾸 시간을 할애하게 한다는 것이다.
자꾸 뭘 하는데 꼭 참여해야하고 막 이런 내용이 많은데 막상 참여해도 그렇게 큰 도움은 되지 않을 때가 많았기 때문에,
나로서는 참여하는 것에 큰 의미가 없었지만 참여하게 됐고 그 시간은 고스란히 의미없이 소비됐다.
진정 필요한 일인가와 진정 도움이 되는 정보인가에 대해서 고민해 봤으면 좋겠다.
그리고, 정보가 다르다.
여기서는 이렇게 하라고 했는데 이렇게 하니 저기서는 이게 아니라 다른 것이다. 그렇게하면 안된다.
뭐 이런식으로 전달하는 내용이 다르다보니까 누가 그렇게 하라고 해서 했는데, 지적을 받는 케이스가 생겨버렸다.
이 부분은 세션을 운영하면서 고려해야 하지 않나 싶었다.
3. 항해99 실전 프로젝트
Project renDev
Project renDev는
랑데브는 포트폴리오를 위한 협업 프로젝트를 찾는 개발자와 디자이너를 매칭해주는 서비스다. 사이드 프로젝트를 해보고 싶을 때, 비전공자나 이제 갓 개발에 입문한 사람들은 팀원을 구할 곳이 부족하다는 점을 깨달았고, 이런 개발자들을 위해 함께 프로젝트를 진행할 팀원을 구할 수 있는 서비스를 만들어보자는 생각에서 랑데브 프로젝트를 만들게 됐다.
항해99 7기 B반 2조 프로젝트 renDev - YouTube
renDev 시연영상
내가 담당한 작업은
서비스의 유저와 관련된 전반적인 API 개발
이메일 인증 기능 개발
Refresh Token을 사용한 로그인 기능 개발
마이페이지의 예약과 관련된 기능을 제외한 API 개발
서버 보안과 관련된 모듈 작업(Cors, Bcrypt, Helmet 등)
Node.js + AWS ELB + Nginx를 활용한 HTTPS 서버 구축
Artillery를 통한 스트레스 테스트 결과를 토대로 response 속도 개선
Array 함수를 이용한 필터링 형식의 검색 기능 개발
내가 담당한 작업은 위와 같은 정도가 있다.
일단 기본적으로 더 많은 기능을 담당하기에 우리 프로젝트는 각자간 분업이 확실하게 잘 되있는 편이었고,
시간적으로도 거창한 기능을 개발해 프로젝트에 접목시키기에는 어려웠기 때문에 저정도가 한계였다.
이번 프로젝트를 진행하면서 나를 제일 괴롭혔던 것은 Refresh token 작업이었다.
httpOnly로 진행하고 크로스 도메인이라는 개념에 대해서 문외한이었고, 마냥 그렇게만 작업해야 한다는
인식만 가지고 있었기 때문에 너무 많은 시간을 헤매게 됐다.
애초에 서버는 배포된 EC2 환경이고 클라이언트인 프론트 작업은 각자의 집에서 로컬로 하고 있으니 설정을
비교하기가 참 곤란한 상황이 맞았다.
Elasticsearch를 활용한 통합로그시스템을 구축하고도 싶었고, Nginx로 로드밸런싱도 대신 해보고 싶었다.
이것 말고도 소셜로그인 기능도 완전히 작동되게 만들어보고 싶었고 하고 싶었던 것은 정말 너무 많았다.
이번 프로젝트를 진행하면서 제일 아쉬웠던 것은 Typescript를 사용하지 못한 것이다.
프로젝트 초반부터 했으면... 하는 이런 가정은 시간이 지났으니 의미없어서 논외로 하고,
일단 TS를 배워보고 이번 renDev 프로젝트를 TS로 바꿔보는 작업을 시도해볼 생각이다.
서비스 아키텍쳐
서비스 아키텍쳐
FE
간단하게 설명 프론트 UI/UX 제작 라이브러리는 리액트를 사용하고 리덕스로 상태관리. https로 배포하기 위해 AWS의 CloudFront를 사용하고 S3로 배포
BE
Node.js Express 프레임을 기본으로, 따로 툴 설치가 필요 없는 Github action 및 AWS로 관리가 가능한 CodeDeploy와 CodePipeline을 이용해 CI/CD를 구축하여 배포를 자동화하고 PM2를 사용하여 무중단 서비스를 유지
서비스 내 다양한 조건 쿼리와 프로젝트와 다수의 참조관계로 인한 릴레이션의 필요성, 데이터 정합성에 대한 요구로 RDBMS 도입을 결정하고 정규화를 진행, 병목 완화를 위해 인메모리 저장소 캐싱을 검토하며 다양한 자료형을 사용할 수 있는 Redis를 사용하는 것이 합리적이라고 판단, 주요 조회 응답을 Cache - Aside 방식으로 캐싱 그리고 완전 관리형 서비스로 Azure Cache for Redis를 도입
Nginx는 외부에서 요청이나 응답이 어디에서 온 것인지 알 수 없게 들어온 정보를 nginx의 80포트 proxy서버로 먼저받아 서버가 사용하는 실제 포트를 숨겨주는 nginx의 보안기능과, http 80포트로 요청이 들어오면 https 443포트로 Redirect 해주기 때문에 https 서버를 구축, 지원하는 등의 목적으로 사용
WebRTC 기반의 영상통화 기능은, 혹시 발생할지 모를 서버 성능의 이슈를 고려하여 백엔드의 메인 node.js 서버와 별개의 인스턴스에 구현하는 것으로 결정
참고로 서비스 아키텍쳐는 내가 만들었다.
GTQ를 따고 어디다 쓸곳이 없다고 생각했는데, 막상 이럴때 사용하고나니
세상에 배워서 쓸모없는 것은 아무것도 없다는 생각이 들었다.
🔧 기술적 의사결정
CloudFront | 사용자에게 제공되는 정적 컨텐츠의 전송 속도를 높이고 https를 적용시키기 위해 사용하였습니다. |
MySQL (RDS) | 서비스 내 검색, 매칭 기능 등 다양한 조건에서의 조회 쿼리와 프로젝트와 지원자 간의 ‘지원 관계’, ‘매칭 관계’, ‘제안 관계’ 등 다수의 참조관계로 인한 릴레이션의 필요성, 데이터 무결성 - 정합성에 대한 요구로 RDBMS 도입을 결정하고 데이터베이스 정규화를 진행하였습니다. AWS RDS for MySQL을 도입함으로써 추후 단계적 스케일링 측면과 자동 백업, 복원 등 데이터 관리를 용이하게 하였습니다. |
sequelize | Node.js 환경에서 RDB 사용에 있어 자바스크립트 객체와 테이블을 매핑하는 모델을 생성하여 직관성과 재사용성을 갖추고, RAW QUERY와 sequelize 메서드를 적절하게 혼용하여 생산성을 증대했습니다. |
Redis (Azure) | Cache - Aside 정책으로 서비스 내 주요 조회 관련 비즈니스 로직 데이터를 인메모리 저장소에 캐싱함으로써, 지역성을 고려하여 파레토 법칙에 의해 최소한의 캐시 관리 비용으로 서버 - DB간 네트워크 부하 분산과 조회 성능을 크게 개선하였습니다. 완전 관리형 서비스로 Azure Cache for Redis로 Redis를 이관함으로써 추후 확장성과 클러스터링을 고려하였습니다. |
Jest - Supertest | CI / CD와 테스트 피라미드를 고려한 유닛 테스트, 통합 테스트 작성을 위해 Jest와 Supertest 라이브러리 메서드를 이용했습니다. 유닛테스트의 경우 mocking을 이용해 인프라 독립적인 테스트 환경을 조성하고, 통합테스트의 경우 테스트 스크립트 실행 시 인프라 환경을 분리 자동화하였습니다. |
CI - github action | Github 자체적으로 지원해주는 CI기능을 사용하여 pull request시 충돌을 자동으로 확인 해주는 workflow를 사용했습니다. |
CD - AWS CodeDeploy - CodePipeline | CI부분 기능이 끝난 후 AWS에 CodePipeline을 사용하여 Github 웹후크를 설정하여 main 브랜치에서 변경되는 코드가 발생 시 EC2 메인서버에 변경된 코드를 배포할 수 있게 자동화 했습니다 |
nginx | elb를 통해 전달된 트래픽이 서버 앞단에 위치한 Nginx로 들어오고, nginx가 뒤쪽의 서버에 전달시켜주는 방식으로 사용, Nginx가 서버 앞단에 위치했기 때문에 데이터를 먼저 받아주고 걸러주기 때문에 보안적으로 더 우수하고, https 통신이 아니라면 http통신으로 Redirect 해주는 장점이 있습니다. |
인터뷰 기능의 텍스트채팅 및 WebRTC 영상통화를 위한 시그널링, Room 기능을 통한 인터뷰 방 관리에 활용하였습니다. | |
WebRTC | 영상통화 기능의 구현, Kurento나 openVidu 등을 사용하지 않고 WebRTC의 기본 기능으로 해결하였습니다. |
coturn | 공개 STUN/TURN 서버들의 안정성이 낮아, coturn을 활용하여 자체적으로 TURN 서버 구축하였습니다. |
서비스 설명은 여기까지.
참 아쉽다면 아쉽고, 만족스럽다면 만족스러운 실전 6주차의 시간이었다. 미니와 클론코딩 때 못느꼈던 위기감과 협업이라는 것의 진정한 의미, 발표가 끝나고 드디어 끝났다는 성취감과 안도감 등
많은 감정을 느끼게 했고, 좋은 경험을 한 시간이었다. 더 많은 기능을 했으면 좋겠지만, 이건 내 욕심이고
앞으로 더 많은 도전과 공부를 통해서 지금보다 더 수준 높은 서비스를 만들어 보고 싶다는 욕심이 들었다.
어렵고 힘든 것들을 뒤로하고, 우리 팀정도면 나쁘지 않았다라는 오히려 그 중에는 잘한 것 같다는
뿌듯한 생각과 함께 6주간의 실전프로젝트가 마무리됐다.
항해99는 지원주차를 포함해 딱 일주일이 남았다.
처음 시작할 때는 이렇게 지능이 낮아도 괜찮은가 싶었지만, 하다보니 CRUD 머신이 되버렸고 새로운 것을
배우고 적용시키려는데 주저하던 마음이 사라졌다. 이렇게 해서 개발자가 될 수 있을까 싶던 생각들이
앞으로도 열심히만 하면 될 수 있을 것 같다는 긍정적인 방향으로
자리잡았다.
이전에 썻던 실전에 관한 소감이다. 이것만 봐도 충분,
4. 개발자 취업 후기
나같은 경우는 정말 운이 좋게도, 좋은 사람들과 일할 수 있는 기회가 부여되서 에딘트라는 회사에서 일을 시작할 수 있게 됐다.
PORT 99에서 지원을 해서 붙었는데, port99에 검색기능과 차단 기능이 있었으면 좋겠다고 느꼈다.
에딘트 전에 봤던 면접들에선 기술면접에서 쉽지 않은 경험을 했었지만
에딘트도 기술면접을 볼 줄 알고 준비해간 곳에서는 인성면접만 보게 됐다.
정말 기분좋은 면접시간이었고, 좋은 기분으로 면접을 보고 나와 집에 갔는데
점심에 본 면접결과가 저녁즈음에 발표가 나게 됐다.
내가 알기로는 내가 마지막 주자였는데, 내가 선택됐다는 사실에 무척 감격했었다.
이글을 보고 포트에 지원하는 다른 항해 수강생들이 있다면, 나도 수십개를 넣고 그중에 몇개만 서류가 붙어서
면접을 보고 취업한 것이기 때문에, 다들 힘내서 포기하지말고 계속해서 도전했으면 한다는 걸 말해주고 싶다.
5. 마무리
항해를 하는 동안 첫 주차부터 느낀건 내가 망망대해에 서 있다는 감각이었다.
넓은 바다를 작은 땟목에 의지해서 나아가고 있었는데, 바다에서 흐르는 온갖 쓰레기들과 가끔씩 흘러 들어오는 좋은 무언가로 땟목을 점점 튼튼하게 수리하고 계속해서 신대륙을 찾아 바다를 찾아 나아가고 있다는 생각을 했다.
그리고 수료를 한 후 취업을 준비하던 나는 깨달았다.
나는 넓은 바다를 항해하는 것이 아닌, 그저 지나치도록 넓은 강을 지나고 있던 것 뿐이었고, 시간이 지나 목적지에 도착하니 넓은 강줄기가 진짜 바다를 향해 모여들고 있다는 것이다.
부트캠프와 대학교 그리고 국비 등 다양한 강줄기에서 흘러나온 물줄기가 바다를 향해 모여들고
그 바다를 향해 내가 뛰어들어야 하는 구조라는걸 수료를 하고
그제서야 깨달았다.
바다에는 폭풍이 치고, 내가 예상치 못한 위험이 도사리고 있기 때문에
내 땟목을 더 수리하고 다듬어서 튼튼한 배로 만들고, 튼튼한 배를 이끌고 끝이 보이지 않는 그런 앞을 향해서
나아가야 한다고 나는 계속해서 나아가야 한다는 것을 알게 됐다.
긴 여정이겠지만 이전에 내가 했던 것들을 돌아보니 할만할 지도 모른다는 생각을 했다.
아무튼 소감은 이렇다.