부트캠프 이야기/한화시스템 sw부트캠프 7기

17주차 후기 - 이제 최종 시작

브래드 킴 2024. 9. 7. 17:27
728x90

지난주 이야기

한주간 우리반은 devops수업을 마무리 지었다. eks기반에 msa배포까지 마무리 짓고, jenkins를 통한 빌드/배포를 진행해봤고, 남은 시간을 이용해 테라폼을 활용한 aws 자원 생성까지 실습해보았다.

 

그리고, 이전에 개발한 front, backend 소스코드를 aws에 배포를 진행하는 데브옵스 프로젝트를 이틀간 진행하게 되었다. 우리 데브옵스 프로젝트의 목표는 welcome to nginx를 보는 것이 아닌 개발한 소스코드가 온전히 배포서버환경에서 온전히 동작하는지를 확인하는 것이었다.

 

이전 중간 프로젝트에서 각 팀들이 다양한 기술들을 활용했던 만큼 이번 데브옵스 프로젝트의 난이도는 높았다. 채팅, 알림, queue대기열, 동영상처리, oauth로그인 등의 기술들이 다중화된 배포환경에서는 제대로 동작하지 않는 이슈가 발생했다. 여기서는 우리수강생들이 고생해서 해결한 이슈들을 기록을 위해 남겨보고자 한다.

 


먼저, 1팀 teenkiri의 이슈사항부터 살펴보자. 1팀은 oauth 로그인, 동영상 업로드 등 에서 문제가 발생했다.

 

1팀의 oauth로그인은 인가, 토큰발급까지 모든 oauth처리가 백엔드에서 oauth2-client 의존성을 통해 처리하도록 돼 있다. oauth처리는 크게는 2단계로 나뉘는데 먼저 인가 코드라는 것을 google, kakao등으로부터 받고 그 인가코드를 사용하여 다시 token을 받아오는 식으로 처리가 되는데, token을 받을때에는 google에서 redirect를 해줘서 token이 나의 서버로 들어오는 방식이다. 그런데 해담팀의 oauth로그인처리 방식에서는 인가코드를 요청하는 서버와 token을 받을때 redirect되어 들어오는 서버가 일치하지 않으면 에러가 발생했다. 서버가 이중화가 되어 있다보니 redirect를 통해 들어오는 http요청이 최초 인가코드를 요청했던 서버가 아닌 다른서버로 들어가 버리곤 했기 때문이다. 이를 해결하기 위해 ingress에 sticky 옵션을 통해 최초 요청을 맺은 서버가 이후 지속적으로 http요청을 주고 받을 수 있도록 LB 설정을 했고, 해당 이슈를 해결할 수 있었다.

 

더불어, 동영상 업로드과정에서 local에서는 문제가 없었는데, 컨테이너를 통한 서버 배포후에는 문제가 발생했다. 일단 먼저 ingress-controller인 nginx에서 용량제한이 발생했고 이를 별도 설정으로 용량을 올려줘야했고, 그 이후 pod로 라우팅 된 이후에도 spring에서 용량제한 이슈가 발생했다. 그래서 결과적으로 ingress와 yml에서 용량을 상향시키는 설정을 해줘야만 했다.

 

 

2팀 noexxit는 채팅에서 이슈가 발생하였다.

 

2팀은 채팅서비스를 도입하였고, 멀티 파드 환경에서 채팅이 제대로 동작하게 하기 위해 redis의 pub/sub을 활용하였다. n명의 사용자가 한 채팅방에서 채팅을 하기 위해 각 사용자들은 /topic/room/{roomId} endpoint를 subscribe한다. 그런데 이 room에 대한 구독이 서버의존적이기 때문에 redis pub/sub을 통해 각 서버에 전파해줘야 했다. 큰 틀에서는 방향을 잘 잡고 코딩하였지만, 지엽적인 코드 이슈와 로컬환경세팅 및 서버테스팅 등이 쉽지가 않았다.

 

 

 

3팀 wodify 또한 많은 어려움을 적절한 기술을 통해 해결하였다. 먼저, 서버시간 utc에 따른 스케쥴러가 제대로 돌지 않는 문제가 발생하였다. DB에는 사용자로부터 입력받은 시간을 kst(한국시간) 그대로 저장하였지만, 스케쥴러가 돌아가는 배포서버의 시간대는 utc였기에 LocalDateTime.now()가 원하는 기준시간이 되지 못하는 원인을 찾아내고 이를 해결하였다.

 

또한 스케쥴러 n개씩 돌아가는 문제를 해결하기 위해 shedlock 의존성을 추가하여 lock을 걸어 2대의 서버중 1대의 서버만 스케쥴러가 돌도록 매우 간편하고 적절하게 해결해냈다. 이외에도, queue관련 컨슘문제 해결이 인상적이었는데, rabbitmq의 queue를 소모하는 n대의 서버가 있을때 이 서버들이 재시작되거나 서버가 중단되었을때에도 consumer connection들이 여전히 좀비처럼 남아서 mq를 listen하고 있는 바람에 큐가 해당 유령컨슈머에게 listen 됨으로서 큐자체가 영구 유실되는 문제가 발생하였다. 이를 해결하기 위해 이슈관련하여 서버가 내려갈때 connection을 끊고 ack모드를 통해 서버가 queue를 확실히 수신하였음을 mq가 확인했을때 mq에서 queue를 삭제 하는 식으로 queue유실문제를 해결할 수 있었다.

 

 

4팀 flint 또한 redis/pubsub 등을 알림목적으로 도입하였고, mq를 사용하였기에 대기열 queue관련한 문제들을 해결하였다. 특히 그 과정에서 hpa를 적용하여 pod가 자동증설되도록 하여 예약이 몰렸을때 대기열의 queue를 빠른 속도로 처리할 수 있도록 아키텍처를 구성하였다.

 

5팀 want의 특이사항으로는 구글에서 개발한 JIB 도구를 사용하여 재빌드 상황에서 빌드 속도의 획기적인 향상을 만들어냈다. 또한 hpa를 적용함으로서 종종 발생하는 메모리 leak에 따른 서버 중단 이슈를 메모리가 부족해기전에 자동으로 autoscaleout을 진행시킴으로서 서버가 중단되지 않도록 하여 서버 운영의 안정성을 향상 시켰다. DB커넥션 관련하여 db자원 부족 문제를 해결하기 위해 open-in-view를 false를 놓음으로서 jpa가 빠르게 자원을 반납하도록 설정하였다. 다만 이부분은 jpa의 lazy loading 상황에서 DB 커넥션이 지속적으로 필요할수도 있기에, 문제가 생기지 않을지는 좀 더 많은 스터디와 테스트가 필요할것 같다.

 

 

6팀 devjeans 또한 앞서 말한 팀들이 가지고 있는 이슈들 뿐만 아니라, 그외 문제사항을 몇가지를 발견해냈고 적절하게 해결하였다. 특이할만한 점으로는 먼저 프론트엔드에서 웹팩빌드이슈를 발견했다는 점이다. 우리가 프론트엔드를 로컬에서 테스트 목적으로 실행할때에는 npm run serve를 하게 되는데, 이는 npm run build를 통한 빌드 방식과 약간의 차이가 발생한다. npm run build의 경우 배포를 위해 용량 최적화된 방식으로 소스코드를 빌드하다 보니, css의 불필요한 부분들이 제거되고 순서가 조정되는 과정에서 로컬환경과는 다른 css적용결과가 나타나기도 했다. 어떤 부분에서 적용 문제가 발생하는지는 정해진 rule을 찾긴 어렵다보니 배포전에 로컬에서 웹팩빌드를 실행해본 뒤에 원인을 적절히 해결하고 배포하는 것이 현재로서는 대안으로 생각된다.

 

더불어, 해당팀의 백엔드 배포에서는 크게는 2가지 정도의 문제를 발견하고 해결하였다. 먼저, 개발용도의 docker-compose를 통한 배포에서는 nginx를 reverse proxy 목적으로 사용하였는데, nginx가 http버전문제로 인해 실시간통신을 제대로 지원하지 않아 알림이 오지 않는 문제를 발견해냈다. 그래서 순수 nginx를 떼어내고, aws에서 지원하는 alb를 붙임으로서 문제를 간단하게 해결하였다. 또한 redis pub/sub관련한 특이점을 발견한것도 상당히 참신하였다. redis bean을 만듦에 있어 qualifier를 통한 db정보 주입을 할때에 pub/sub관련한 bean생성시에 오류가 발생하는 것을 알게 되었고, redis pub/sub 기능은 redis안에 있는 16개 db 어디에도 종속되지 않는다는 사실을 알게되었고, 공식문서를 통해 정확히 확인 또한 해주었다.

 

 

수강생들이 이번 프로젝트를 배웠으면 하는 점

 7기 수강생들은 이번 데브옵스 프로젝트를 치열하게 수행하는 과정에서 향후 동기들 또는 또다른 개발자들이 참고할만한 좋은 레퍼런스들을 많이 만들어냈다고 생각한다. 이것은 누군가의 수고를 덜어주는 좋은 일임에 틀림 없을 것이다.

 

얻게된 지식을 제외하고 우리가 이번 프로젝트를 통해 무엇을 배웠으면 좋을까를 생각해봤다.

 

실무에서도 항상 하게 되는 표현중 하나는, "아 이거 로컬에서는 잘되는데 왜 서버에서 안되지?"라는 의문이다. 그리고 그 원인을 해결하는것이 항상 알수 없는 안개를 헤메는 기분이라 쉽게 해결되지가 않는다.

 

개발자로서 앞으로 이런 식의 상황을 수없이 맞닥뜨리게 될 텐데, 우리는 어떤 자세로 이런 상황에 임해야 하는 것일까? 

 

이러한 상황에서 결국 문제를 해결할 수 있다는 낙관론을 우리 수강생들이 갖을 수 있게 된다면 참 좋겠다. 항상 그래왔듯 이거 안될것 같은데? 하는 상황에서도 우리는 결국은 어떤식으로든 답을 찾을 수 있다. 그 답이 정답이 아니라 할지라도 우리가 포기하지만 않는다면 우리는 문제를 어떤식으로든 해결해낸다. 이번 기수 모든 팀들이 나름의 답을 찾아냈듯이.

 

우리가 낙관론을 기본 자세로 가질수만 있다면, 문제를 해결하기 위한 그 과정도 오히려 조금 더 쉬워질수 있다. 당황해서 문제의 근본원인이 아닌 곳을 짚느라 잘못된 몇시간을 허비하는 것이 아니라, 차분히 논리적인 해결책을 고민하고 테스트 환경을 갖춰놓고 문제를 원점에서부터 다시 분석할수가 있다. 급할수록 돌아가야 하는 것이다.

 

물론 이러한 낙관론이나 자신감은 충분한 성공경험이 쌓여야 진정으로 갖게 될수 있는 것도 사실이다. 그럼에도, 지금 수강생들이 좋은 성공의 경험을 쌓아가고 있기에 "우리가 결국 해내겠지, 내가 결국 문제를 찾아낼것이다."라는 근거있는 자신감을 의도적으로 애써 가지려 노력하면 좋을것 같다. 

향후 계획

이제 최종 프로젝트가 다음주부터 시작된다.

 

최종때에는 수강생들이 좋은 포트폴리오를 만들어내는 것외에 3가지 상황을 염두에 두었으면 좋겠다.

 

먼저 짧은 최종프로젝트 기간동안 강의나 누군가를 통해 배우는 것이 아닌, 새로운 것을 스스로 길을 찾아가며 학습하고 적용해보는 역량을 길러보겠다고 다짐해야만 한다. 경험해본적은 없지만 도입해보고 싶었던 기술을 빠른 스터디, 그리고 즉시 프로젝트에 적용. 이런식의 패턴으로 배움과 성과를 동시에 만들어내야만 한다. 이 과정에서 진정한 개발자로 거듭날수 있다.

 

더불어, 역시나 매순간마다 문제해결 역량을 길러야만 한다. 먼저, 기획회의에서부터 의견이 충돌되거나 합의점을 찾지 못할수 있다.(당연히 그래야만한다. 항상 의견이 일치하는 것은 그것또한 뭔가 잘못된 길로 가는 것일수 있다.) 이때에 빠르게 의견을 조율하고 문제를 해결하며 앞으로 나가야 한다. 그리고 본격적으로 개발하는 매순간마다 문제에 부딪치게 된다. 스스로 치열하게 리서치를 하든, 주변에 도움을 청하든 어떻게든 빠른 시간안에 문제를 해결하면서 또한 앞으로 나아가야 한다. 이후의 치열한 테스트 과정과 발표준비 과정 모든 순간에 우리는 문제를 맞닥뜨리게 될것이다. 역시나 그것을 치열하게 해결하는 과정에서 모든 수강생들이 몇단계 성장해 낼수 있으면 좋겠다. 

 

마지막으로 나만 그럴지도 모르겠으나, 항상 급격한 성장은 벼랑끝에 내몰린 상황에서 만들어졌던 같다. 여유롭고 평온한 상황에서는 빠른 성장을 만들어낼순 없다. 그저 꾸준하고 느린 성장일 뿐이다. 그렇다면 우리가 최종때에 해야할일은 과부하가 될수 있을정도로 다소 일을 크게 벌이는 것이다. 언제든지 충분히 해낼수 있을만한 일을 기획하는 것이아니라, 목표자체가 챌린징 해야만 한다. "기간내에 해낼수 있을까?" 하는 약간의 두려움이 느껴질정도의 과업이 필요하다. 우리 수강생 개개인 모두가 두려움을 느낄만한 일을 기꺼이 감당해냈으면 좋겠고, 2달뒤에는 지금보다 훨씬 성장해내는 성취감도 맛보게 될수 있으면 좋겠다.

 

 

 

 

 

728x90

'부트캠프 이야기 > 한화시스템 sw부트캠프 7기' 카테고리의 다른 글

마지막 후기  (2) 2024.11.08
16주차 후기  (0) 2024.08.31
15주차(7기 중간프로젝트 완료)  (0) 2024.08.24
14주차 회고  (1) 2024.08.18
13주차 회고  (0) 2024.08.10