교체 배경
현재 다니고 있는 회사에서 Django + React로 개발 중이던 프로젝트를 NestJS + Angular로 대체하는 경험을 했다. 참고로 인프라도 AWS + github에서 Azure Devops로 이전했다.
사실 상 처음부터 다시 만드는 결정을 한 셈인데, 이 변경 배경엔 시니어의 교체가 있었다. 참고로 당시 회사엔 주니어 레벨 개발자 3명과 백엔드 경력직 개발자 1명, 프론트엔드 경력직 개발자 1명, 주니어 퍼블리셔 1명으로 기술 스택과 밀접한 연관이 있는 사람은 6명 정도였다. 개발자들 사이에선 상당히 큰 반발이 있었지만, 경력직 개발자들이 교체가 됐고, 기술 스택도 자연스레 교체되었다.
어쩌면 기존 경력직들을 교체하기 위한 결정이었을 수도 있고, 순전 시니어의 개인 취향이 반영된 것일지도 모른다. 확실한 건 이 제안을 새로 온 시니어가 했고, 대표는 그저 믿고 맡겼을 뿐이라는 것.
주류에서 비주류로
- Django -> NestJS
- React -> Angular
- github + AWS -> Azure Devops + GCP
Django -> NestJS
이 결정엔 내가 가장 큰 반대를 했다. 이유는 생산성과 기존에 사용되던 서비스 때문이었고, RestAPI를 만드는 것을 굳이 Real time에 강점을 갖는 Node.js로 넘길 이유가 없었기 때문이다. 내 나름대로 합리적으로 검토하고 제안을 해보았다.
'나중에 비대해질 가능성이 높고, 실시간 통신이 필요할 가능성도 높은 "번역 도구"만 Node.js로 넘기는 것이 옳아 보인다'
나름대로 말해봤지만, 그 자리에서 '그러자, 말자, 옳다, 틀리다' 등의 대답은 듣지 못했다.
문제
Angular와 NestJS의 구조가 똑같아서 호환성이 좋다고 하는데, 이 또한 기능단위로 개발하는 등, 프론트엔드 & 백엔드 코드를 구분 없이 참조하는 경우에나 실효성이 있는 얘기이다.
일단 기존 개발자들의 생산성 저하가 절대적으로 컸다. 충분히 여유가 있고, 선행학습된 상태에서 도입한 것이 아니기 때문에, 예상치 못한 버그, 문제해결, 개발 등에 시간을 소모할 수 밖에 없다. 기존 코드를 버리는 건 덤.
추가적으로 express 대신 fastify를 대체해 사용했는데, 이 또한 충분한 자료조사를 통한 결정은 아니었을 것이다. fastify는 빠르고 좋다. 하지만대중적이지 않고, 뭣보다 multipart 통신을 프레임워크레벨에서 지원하지 않는다. 자료 조사와 학습이 선행되지 않은 신기술은 전면도입하지 않는 것이 좋다. 어떤 버그가 있을지 모르기 때문이다.
그리고 확실한 "리스크 관리 계획"이 있어야 한다고 본다. 예컨대 한 달 동안 틈 날 때마다 시간을 투자해서 간단한 프로그램을 개발해 보기 정도로, 성능 및 문제점 테스트를 해보는 게 좋고, 개발 시작 후에도 무슨 문제가 생겼을 때 어떻게 대처할지에 대한 나름의 계획이 있어야 한다.
React -> Angular
이 결정엔 경력직 프론트엔드 개발자가 반대하다가 결국 퇴사하게 됐다. 경력직 나름대로 이유가 있었던 것으로 보이고, "나를 납득시키지 못한다"라고 얘기했던 기억이 난다.
나는 애당초 백엔드 개발자였고, 둘 다 한 성격하는 사람들이기에 이 싸움의 포인트를 프레임워크보다는 기싸움으로 읽었지만, 최근 Angular로 생산된 코드들을 보니, React -> Angular로 변경하는 것에 합리적인 근거가 있는 결정은 아니었을 것으로 추론된다.
문제
개발자 채용에서 많은 핸디캡을 갖는다. 개발자들은 트렌드를 중요 시하는 경우가 많고, 실제로 시장가치가 높은 기술은 React라고 생각하기 때문에 Angular를 굳이 배우려하지 않는다. 그 외에 선행학습 부족도 많은 문제를 불러 일으켰다. environment.ts
를 제대로 활용하지 않아서 코드가 불필요할 정도로 복잡해졌고, 실서비스에 배포되는 내용(JS덩어리들)이 실제로 개발 & 테스트용과 전혀 다르지 않다. 문제가 그 js 덩어리를 저장하여 본인 로컬에서 실행하면 개발모드로 실행된다는 것이다.
github + AWS -> Azure Devops + GCP
이 결정은 목적과 명분("모노리틱은 DB참조가 복잡해지고 어디서 호출하는지 모르게되어 발목을 잡는다. 그러니 MSA를 도입해야하고, docker kubernetes 사용에 유리한 GCP로 가자!"였다)은 그럴싸했지만, 실효성은 없었다고 생각하고 영리집단인 회사의 관점에서 봤을 땐 가장 멍청한 결정이 아니었나 싶다.
일단 Jenkins를 Azure pipe line과 agent로 대체하는 등 CI/CD의 재개발이 들어가야했다. 또 MSA를 위해 docker와 kubernetes를 도입했는데, 지금 생각해보면 굳이 쓸 이유가 없는 기술들이고 오히려 개발에 발목을 잡는 '오버 엔지니어링'이 돼버렸다. 설령 필요했다고 하더라도, infra를 통째로 다 옮길 필요가 있었는지도 의문이다.
문제
Data Architecture로 생긴 문제는 정확한 설계(DA업무)로 풀어야 한다. 오히려 함께 있어야할 데이터들이, 잘못된 설계로 별도로 저장되면서 동기화 코드와 추가 상태값이 늘어났다. 더불어 배포 시에 한번에 두 개의 프로젝트를 동시에 업데이트 해주어야하는 등, 프로젝트 간의 커플링이 생기기 시작했다.
MSA의 장점이라면 장애내성, 언어 다양성 등이지, "프로젝트 단순화"는 이미 설계 단계에서 결정되었어야하는 부분이다. 즉, docker와 kubernetes를 도입한다고 프로젝트가 단순해지지는 않는다. 오히려 고민이나 충분한 계획 없이 개발하는 경우 복잡해질 가능성이 더 높다.
결론
기존의 것을 바꾸거나, 이견을 제시하기 위해서는 최소한 아래와 같은 조건이 만족되어야 한다.
- 본인이 주장하고자 하는 것 자체에 정당성이 있어야한다.
- 그걸 달성하기 위한 방법이 합리적인지, 실효성이 있는지 검토해야 한다.
- 위 두 가지가 만족되지 못하는데 고집을 부린다면, 그건 숨은 의도를 달성하기 위한 행위와 대의 명분에 불과할 가능성이 높다.
'IT' 카테고리의 다른 글
스벨트에서 readable만 노출하기(Svelte - writable to readable) (0) | 2022.10.10 |
---|---|
NestJS로 쉽게 개발하는 방법 (0) | 2021.03.27 |
DB의 중복 값 지우기 (0) | 2020.02.27 |
EC2 deploy server: 프로세스를 백그라운드에서 실행시키기 (0) | 2019.10.15 |
apache2 stop, start, restart in Linux (0) | 2019.10.15 |