참고로 cicd팀원분도 이 template.yaml을 기준으로 cicd코드를 코딩하셨어요.
sam cli를 추천하시나요?
sam은 일단 코드 수정후에 저장한다고 바로 환경에 적용이 안됩니다. ㅡㅡ
코드를 한 글자만 수정을 하더라도 적용시키려면 build+start api를 다시 해줘야하는데 이 과정이 5분씩 잡아먹어요
그리고 제 노트북은 5년된 간신히 숨만 붙어있는 산송장 노트북이라 리소스를 엄청 잡아먹는 sam을 돌릴때마다 팬이 아주 미친듯이 돌아갔답니다...
개발환경과 배포환경을 완벽히 분리했지만 너무 힘들었어요.
때문에 위에 명령어들 줄줄히 적어놓은게 어떻게든 sam cli를 활용해서 개발을 하려고 발버둥쳤던 흔적입니다..
환경변수도 node명령어 실행때, sam으로 컨테이너 띄웠을때, 실제 배포했을때 전부 다르게 설정해야했습니다.
지금까지 개발할때마다 control + S를 누르면 바로바로 코드가 프로세스에 적용하게 해줬던 nodemon과 live server등 개발도구들의 소중함을 너무나도 절실히 깨달은 경험이었습니다.. 진짜 여러분들 이거 진짜 체감못하실거에요.. 저 이거하고 탈모왔어요
근데 사실 sam말고 어떻게 람다환경에서의 개발 배포환경을 구분해야할지는 다른 좋은방법이 생각이 안납니다.
실제 컨테이너 이미지를 만들어서 해야할까요? 아니면 aws에 private네트워크를 만들고 거기서 lambda, api gw를 띄워야할까요? 시도는 안해봤지만 많이 어려울것 같다고 생각드네요.
암튼 너무 어렵다기보단 짜증이났던 경험이었습니다.. 구글링해도 sam cli에 대한 자료가 거의 없구 gpt도 수집할 자료가없어서인지 엄청 틀리더라구요. 하나하나 조금씩 수정하며 테스트해봐야했는데 테스트할때마다 5분씩 걸리니...하.. 암튼 결국 완성은 했지만요.
람다에 대해서
일단 이번 포스팅에서 제가 전해드리고 싶은 내용을 말씀드리기위해 개념부터 정리하는 식으로 차근차근 포스팅하겠습니다.
위에서도 말씀드렸지만 람다를 보통 함수? 라고 생각하시는데요. 람다는 정확히는 컨테이너입니다.
aws에서도 람다함수가 하나 호출되면 해당 람다함수의 컨테이너가 띄워지고 이벤트를 받고 처리후에 응답을 주는 구조랍니다.
지금부터 lambda의 특성중 제가 주목한 특성 세 가지를 먼저 소개해드릴게요.
매우 중요한 부분입니다. 성능최적화에 관련이 있는 내용입니다.
1. Lambda는 세가지 state가 있습니다. - clod start & warm state & idle state
cold start : 람다가 막 시작해서 초기화부터 이뤄져야할 상태에요. 한동안 람다에 이벤트가 없어서 컨테이너가 없는 상태라 다시 만들어야하는 상태입니다.
warm state : 이미 cold start가 이뤄진 컨테이너라 다음 이벤트를 받을때 컨테이너 초기화가 필요없는 상태에요
idle state : 한동안 람다에 요청이 없어서 삭제대기중인 상태입니다. 람다는 삭제될수 있다는걸 알려드리고 싶어서 추가했어요. 별로 중요하진않아서 그냥 이런상태가 있다~정도만 생각하시면되요.
예시를 들어드릴게요
먼저 무찌가 보낸 이벤트는 람다가 cold start상태라서 초기화가 필요해요. 컨테이너가 생성되야하죠. 그래서 이벤트가 10초나 걸려서 처리가 됐죠.
근데 이후에 도리가 이 람다에 또다시 요청을 합니다. 이때는 무찌가 이미 람다를 따뜻하게 해놨으므로 warm state상태입니다.
이벤트 처리가 5초밖에 안걸렸네요. warm state인 람다는 이벤트를 더욱 빠르게 처리해줘요. 이미 cold start때 썼던 메모리룰 기억하고있어서 재사용하면 되거든요~
중요한건 람다는 처음 요청을 받으면 cold start상태로 시작되고 초기화가 필요하기때문에 이벤트에대한 응답을 비교적 늦게줍니다는 점이에요. 이후로 오는 이벤트는 이미 한번 사용된 람다 컨테이너를 재사용할수 있으니까 warm state상태라서 더욱 빠른 응답을 주는거죠. 이 부분을 기억해주세요. 밑에 설명할 캐싱기능을 이 람다의 특성들을 고려해서 만들었거든요.
또한 람다는 여러 상태가 있는데 람다컨테이너가 사라지는 타이밍은 저희가 가늠할수 없습니다. aws만의 규칙이 있겠죠? 이 점도 중요합니다.
2. 람다의 이벤트 처리방식
그림처럼 상황을 가정해봅시다.
거의 동시에 두 이벤트를 클라이언트한테 받았다고 하면요.
람다는 먼저 들어온 이벤트를 처리하고 있겠죠? 근데 또다른 이벤트가 무찌람다에 요청을 하게되니까 람다는 이걸 동기처리하든, 비동기처리하든 해야한답니다.
결론적으로 람다는 한번에 한 이벤트만 처리합니다!! 매우 중요합니다.
만약 먼저온 이벤트를 처리중인데 다른이벤트가 오면 받질 않아요.
3. 그럼 람다에 여러 이벤트가 오면 무한히 기다려야하나요? - 람다의 오토스케일링
상황을 가정해볼게요.
한 클라이언트가 람다를 호출했어요. 그럼 람다가 클라이언트의 이벤트를 처리중이겠죠?
이벤트를 처리중에 두 클라이언트가 갑자기 이벤트를 보냈어요. 그런데 람다는 클라이언트의 이벤트를 처리중이니 이 이벤트들을 받지 못할겁니다.
이때 람다는 요청을 처리하기위해 자동으로 오토스케일링이 됩니다!! 똑같은 람다 컨테이너를 여러개 더 만드는거죠.
이렇게 람다가 여러 이벤트를 컨테이너 하나당 한 이벤트 라는 규칙을 가지고도 동시에 처리가 가능합니다. js의 비동기처럼요.
멀티프로세싱같은거라고 보시면 되요.
참고로 새로 생긴 람다는 새로 만들어지니 초기화가 이뤄져야하니 cold start일겁니다.
이 람다의 오토스케일링 특성도 매우 중요합니다.
지금 이 세가지 람다의 특징을 꼭 기억해주세요!! 밑에 설명할 캐싱기능과 매우 밀접한 관계가 있습니다.
람다의 특징을 고려한 캐싱
nurd worker는 두가지 요소에 대해서 캐싱기능을 고려했습니다.
시크릿과 디비 커넥션을 캐싱했어요. 하나씩 나눠서 설명드릴게요
Secret부터~~
위에서 말씀드렸듯이 sam cli를 사용했어서 이번 remember me 프로젝트는 환경변수를 세가지로 나눴는데요.
그럼 백엔드 인증 미들웨어에서 해당요청을 검증하고 처리한후, authResult에 새로운 access token을 담아서 보냄과 동시에
answer프로퍼티에 기존 했던 요청에 대한 데이터도 응답해주게 됩니다.
몇몇 서비스들은 로그아웃을 하게 한다거나 버벅거림이 있겠지만 nurd worker는 사용자 편의성을 중요시하므로 이렇게 사용자가 access token이 만료된걸 전혀 느끼지 못하게 인증기능을 구현을 하였습니다.
때문에 코드를 보시면 아시겠지만 따로 refresh갱신을 위한 api자체가 없습니다. 걍 미들웨어에서 다 처리해요.
토큰 로그 db 저장
람다쪽 미들웨어 코드를 보시면 아시겠지만 토큰로그를 저장해요.
보안이 더욱 좋아졌습니다.
사실 구현할생각은 없었는데 google oauth api가 access token을 검증하는 api를 보낼때
access token이 만료된거든 위조된거든 똑같은 invalid token이라는 응답을 줍니다 ㅡㅡ
제 jwt포스팅 시리즈에서도 보셨듯이 전 두가지 조건을 동시에 만족해야 새로운 acess token을 발급해줬거든요
1. refresh 토큰이 유효해야한다
2. access token이 만료되었어야한다
이 두가지 조건을 and조건으로 만족해야 준다고했는데
google oauth가 2번 조건을 명확하게 해주질 못했어요
때문에 db에 token로그라는 collection을 따로 만들어서 토큰을 기록해두고 이 기록에따라서 만료조건을 체크했습니다.
팀프로젝트 - 첫 팀장으로써 진행
휴.. 지금까지 읽어주셔서 감사합니다.
이제부터는 팀프로젝트에 대해서 짧게 설명드릴게요
저희는 노션을 사용을 주로 하였어요.
프로젝트가 급하게 시작이 되어서 노션제작을 후딱 한다음 회의하면서 사용방법을 알려드렸어요
사진에 보이는것보다 더욱 많은데, 자세한 내용은 직접 독자분과 만날 기회가 있다면 알려드리겠습니다 ^^
이렇게 캘린터로 팀원분들의 진행상황을 확인했습니다.
이 방식은 이전에 아빠 또갈까 프로젝트에서 task 방식으로 협업하는걸 보고 저도 적용했습니다 ㅎㅎ(저는 고라파덕입니다..ㅋㅋ)
이런식으로 개인마다 task를 정리해서 기록했어요.
저 혼자 작성한 task만 저 사진에 보이는 task의 다섯배정도 됩니다 ㅋㅋㅋㅋ
실제로 nurd worker가 취준할떄 면접관이셔서 증명을 원하시거나 혹은 친해지시면 자세히 노션을 보여드릴 수 있습니다~
저기에 서로 사용했던 중요데이터나 이런정보도 있어서 노션을 배포해서 블로그에 공개를 하기는 어렵네요
시연영상 촬영
제가 특별하게 요청드렸던것은 본인이 개발한 분야에대한 시연영상을 제작해달라고 말씀드렸습니다.
왜이랬냐면, 사실 저희가 프로젝트를 만들고나서는 보통 대게는 서비스를 중지하게됩니다.
깃허브에 코드만 달랑 남겨두거나 하게되죠. 실제로 demo버전은 프로젝트 종료후 바로 배포중지가 되었어요~
만약 나중에 프로젝트로 사용하려면 까먹기도하고 사용했던 툴들이 갖가지 버전문제로 에러를 일으킬수도 있어요. 실제 로컬에라도 배포가 되어야 증명이 될텐데.. 난감해지죠.
예를들어 무무티비프로젝트도 VM이 다섯개에 컨테이너만 열개이상 띄워져있는데 1년전에 프로젝트를 다시 띄우고 하려면 기억도안나고 에러도 많이 날겁니다. 그래서 nurd worker도 무무티비 포스팅에 사용된 영상 소스들을 모두 당시에 프로젝트 종료후 바로 촬영해놨던겁니다.
영상으로 기록을 남기는건 중요하다고 봅니다. 가장 좋은 방법은 실제 배포해놓는것이지만 현실적으로 어렵거든요.
취직을 목표로 하는 경우 면접관분들이 진짜 개발했다는걸 믿지 않을확률이 크거든요. (사실 저도 잘 안믿습니다 ㅋㅋ)
그래서 nurd worker 또한 프로젝트마다 영상작업을 하고있고 구현영상남기는걸 굉장히 중요하게 생각해요.
나중에 이 프로젝트를 다시 사용하실때 필요하실거라고 판단되서 오더를 드렸었습니다.
저한테 증명해서 뭐가중요한가요 전 테라폼같은 고급 스킬 볼줄도 모르는데요ㅠㅠ
팀원분들이 좀 독특한 팀장을 만나 고생을 좀 하시긴 한것같기도 하네요 ㅎㅎㅎ
프로젝트 피드백
nurd worker가 팀원분들에게 받은 피드백입니다~
이러한 평가를 받았습니다.
스터디는 많이 진행해봤었으나,
엔지니어로써 팀을 이끌기는 처음이라 많이 미숙했던점도 많았고 반성할점도 많았던것 같습니다 ^^
아키텍쳐
demo 버전 아키텍쳐
인프라 팀원분들이 그려주신 demo버전 아키텍쳐입니다. 역시 인프라팀분들 실력이 어마어마합니다 ㄷㄷ
demo 버전은 프론트서버를 s3버킷에서 정적호스팅 하였구요.
그리고 백엔드는 api gateway와 람다 구조로 이용하였구요.
데이터베이스는 몽고디비를 사용하였습니다.
기타 등등 여러가지 있답니다 ㅎㅎ 저도 잘 모르는것들이 많네요~
advanced 아키텍쳐
현재 배포된 remember me 프로젝트 advanced버전의 아키텍쳐입니다.
프론트 웹서버는 무찌 클러스터에서 운영이 되어있구요.
백엔드는 AWS의 api gateway + lambda구조로 운영되고있습니다.
또한 추가적으로 cloud watch와 SNS를 사용한 알람을 구현해놨습니다^^ (과금 무섭..)
데이터베이스는 무찌 클러스터의 mongo db를 사용하고 있답니다
Conclusion
사실 remember me 프로젝트는 acsap프로젝트의 약간 상위버전? 으로 간단하게 react와 type script를 사용한 어플리케이션으로 간단하게 준비하려고 한 개인 프로젝트였습니다.
근데 마침 너드림덱 프로젝트가 막 끝났을때 이전 네트워크 국비과정을 함께하셨던 분들이 연락이 오셨어요. 프로젝트를 같이 하자고 하시길래 얼떨결에 팀프로젝트로 변해버린 프로젝트입니다. ㅋㅋ 온라인으로 진행한 프로젝트였고 팀원한분은 프로젝트 시작하자마자 취업합격통보를 받으셨는데 책임감있게 해주셔서 감사드리네요.
암튼 하다보니 막 욕심도 나고 해서 여러가지 고려사항을 많이 녹여낸 프로젝트가 되었고 취업할때 굉장히 많은 포인트들을 어필할 수 있는 프로젝트라고 생각이 드네요. (때문에 포스팅도 토나오게 많이적었네요....)