풀스택 개발환경에 대한 선택

[왜 스칼라를 비롯한 잡종/순수 함수형 언어가 메이져가 될수 없는가..] 를 보다가 문득 느낀다. 언어적인 관점은 뭐 스칼라가 좋다 자바가 좋다 이런 종교싸움은 별로 껴들고 싶지 않고, 개인적으로는 각각 장/단점이 있다고 생각하며 나는 그냥 실무에서는 자바를 선호하고, 이리저리 테스트 하기에는 스칼라와 Play를 선호하는 편이다. 뭐 그런 상황보다는 댓글을 보다 Concurrency나 Race Condition등이 등장하는 걸 보니 문득 느끼기로는 점차 개발자들 수준이 이론적 수준까지 높아졌다고 느껴진다.

서론이 사실 좀 이상하게 흘러갔는데, 결국 오늘 쓰고자 하는 내용은 저번 글에 이어 내 정체성에 대한 해법이다. 풀스택 기술에 대한 나 스스로의 전반적인 개발환경에 대한 정의. 개인적으로는 미국에 오긴 했지만 아직 뭐 딱히 실무에 투입된 것도 아니고, 그냥 본래 생각했던 것처럼 스타트업을(작게) 해보려고 한다. 뭐 시민권이고 뭐고 없는 상황에서 어떻게 사업을 하냐, 는 사실 크게 문제가 아니다. 사업이라기 보다는 일단, 내 머릿속에 아이디어를 끌어낼 프로토타입을 만들고 싶을 뿐이니깐. 그래서일까, 풀스택 개발환경이 더욱이나 중요하게 생각되는 시점이다.

 

Frontend

지난 글에서도 밝혔듯 나는 프론트엔드 단의 개발환경에 상당히 놀랐고, 때문에 많은 고민을 했다. 아니, 반성을 했다. 내가 풀스택 프로그래머를 자청하면서도, 워낙 백엔드 개발에만 충실한 나머지(아, 좋은 핑계다.) 솔직히 프론트 엔드가 하는게 뭐 html+css+jquery라고만 단순히 생각했지, 소프트웨어 공학론 처럼 요구분석-설계-개발-테스트-배포 의 과정이 필요한지는 얼마전까지도 몰랐다. 자바스크립트용 단위테스트 프로그램이 있는지도 몰랐고, 왜 의존성 관리가 필요한지 조차 몰랐다. 그러다 문득 [Why can't we find Front End developers?] 를 보게 되었는데, 참으로 프론트 기술 많이 발전했더라.. 여기서 언급한 좋은 프론트앤드 개발자가 갖춰야할 소양이 아래처럼 나와있다.

What experienced Front End Engineers need to know and do on top of good Front End Engineers ** (hint: this are the ones you want to hire)**:

  1. DNS Resolution, usage of Content Delivery Networks (CDN), and performance on multiple Hostnames as part of resources requests.
  2. HTTP Headers (Expires, Cache-Control, If-Modified-Since)
  3. All rules from Steve Souders (High Performance Websites)
  4. How to solve all problems showd by PageSpeed, YSlow, Chrome Dev Tools Audit, Chrome Dev Tools Timeline.
  5. When to leverage tasks to the server and when to the client.
  6. Usage of cache, pre-fetching and post-load techniques
  7. Native Javascript, knowing when to do something from scratch and when to look up for someone else code, and at the same time being able to evaluate the pros and cons of doing so.
  8. Knowledge and usage of modern MVC Javascript libraries (e.g. AngularJS, EmberJS, ReactJS), graphic libraries (e.g. D3, SnapSVG), DOM manipulation libraries (e.g. jQuery, Zepto), lazy loading or package management libraries (e.g. RequireJS, CommonJS), task managers (e.g. Grunt, Gulp), package managers (e.g. Bower, Componentjs) and testing (e.g. Protractor, Selenium).
  9. Image Formats, benefits, when to use which one and how, Image Optimisation techniques, and loading strategies (sprites, lazy loading techniques, cache flushing, PNG interlaced)
  10. Knowledge and usage of CSS Standards, modern conventions and strategies (e.g. BEM, SMACSS, OOCSS)
  11. The Computer Science of Javascript (memory management, single threaded nature, garbage collector algorithms, timeouts, scoping, hoisting, patterns)

(Source: Why can't we find Front End developers? )

이 정도는 알아야지 올바른 프론트 앤드 개발이 가능하다는 것이다. CDN이나 헤더 조정부터 해서, 고사양 웹이 갖춰야 할 것을 다양하게 다루는 기술. 솔직히 여기까지는 알았다. 에릭 마이어니 그런 책도 많고, 관심이야 있었다. 귀찮아서 안했을 뿐이지.. 허나 자바스크립트의 MVC환경, lazy loading, 의존성 관리, 테스크 매니지먼트, 패키지 매니지먼트, 테스팅 등에 대해서는 솔직히 알아야 하지 않을까. 최소한 소프트웨어 공학을 들은 CS학부생이라면. 그래야 전통적인 막써먹는(?) 자바스크립트에서의 어떤 체계적인 개발이 가능할 것이니 말이다.

이런 마음에 엊그제부터 계속 CodeSchool의 AngularJS 강의를 듣고, 어느정도 요즘의 Front-end 개발 트랜드에 대한 감을 잡았다. DOM과의 완전한 분리가 아닌, DOM자체에 DI를, 스크립트 단에서 주입해놓는 그런 관계랄까. 뭔가 스프링 같은 느낌이 들어서 상당히 마음에 들더라. 원래 Play! F/W의 예제로 들어있던 Backborn.js이 워낙 땡겨서 사용하려 했는데 뭔가 모델에만 집중하는 느낌이고, 뭔가 모듈화가 되어 있지 않은 느낌이라(사실 뭐가 좋은건지는 잘 모르겠다.) AngularJS로 프론트엔드를 개발하기로 결심했다. 테스크 관리로는 Gulp를 사용하고, 의존성 관리 및 lazy loading은 RequireJS, 패키지 매니저는 Bower, 코드 검증 도구는 JsHint, 테스팅은 Mocha, 테스트 러너는 Karma, 자동화는 Selenium을 사용한다(사실 이건 잘 모르겠다). 그리고 중요한 것은, AngularJS를 사용할 때 Coffeescript로 컴파일 하고, UglifyJS와 UglifyCSS로 compressed한다. (이 과정은 Gradle로 작업하도록 한다.)

사실 위의 대부분의 과정을 Yeoman이 처리해줄 수 있다. (참 좋은 세상이다..) 그리고 위를 선택할 때 참조할 만한 내용을 아래 Slideshare에서 잘 정리해 두었다.

 

Backend

백엔드는 아무리 Spring-Boot나 Node.js가 발전하고, 또한 트랜드라고는 하지만 나는 기존에 배워왔던 Spring MVC에 대한 적용을 지우고 싶지 않더라. 다만, 기존에는 Apache Tomcat 을 설치하고 이 안에 deploy하는 방식으로 보통 개발을 진행했는데 조금 생각이 바뀌어서 Jetty같은 Embedded WAS를 도입하고자 한다. 의존성 관리 및 빌드 등은 Maven에서 Gradle로 변경했다. 상당히 강력하더라.. 게다가 AngularJS + Spring MVC 환경에서는 IDEA를 두개 띄우고 사용했었는데 Gradle설정으로 하나로 통합하고, 각각 빌드를 따로할 수 있어서 얼마나 좋은지 모르겠다. (이렇게 보면 나도 참 툴 의존적이지만..)

어쨌든 백엔드는 RestFul을 통해 DB와의 훌륭한 연동만 지원하면 된다. 요즘 참 성능좋은 NoSQL이 쏟아지고 있지만 쿼리에 대한 욕심은 버리고 싶지 않다. 그래서 MEAN개발("MongoDB Express.js AngularJS Node.js") 은 별로 선호하고 싶지 않다. 다만, 원래 한국에서는 MyBatis을 주로 사용해 왔읐는데, 여기 미국에서는 Hibernate를 주로 사용하더라. DB자체는 MySQL 5.5 에서 바꾸지 않되, Hibernate를 사용하기로 했다. 나중에 기회가 되면 Apache HBASE를 베이스로 하는 Google Cloud BigTable을 사용해보리..

또한 언어에 대해서, 당연히 주력인 Java를 사용하되 조금 더 나아가서 자바8을 공부하고, 한번 사용해 볼까 한다. 람다식은 Scala에서도 많이 사용했었고, 사실 자바7까지의 문법이야 너무나도 익숙한게 사실이다. 그러니깐 공부하면서 한번, 자바8을 사용해 보려고 한다. 한편으론, Spring과 Redis를 부분적으로 사용해 캐싱까지도 집어넣어 보려 한다. (아따 공부할 것 많네) 보안적 측면에서 단순 커스톰 세션 관리가 아닌 Spring-Security를 도입해 보려 한다. 전반적인 JSON은 GSON으로 변경하고, 도메인과의 맵핑 처리를 한다. 

 

CI / VCS

CI는 더 말할 것도 없이 당연히 기존에 구축된 Jenkins를 사용하고, VCS역시 Gitlab을. 다만, 기존에 Maven베이스로 Test/Deploy되어 있는 부분을 Deploy_for_Real작업을 새로 신설하여, 마침 GCE와 Jenkins와의 플러그인 도 있으므로 배포부분은 Gradle로 수정하여 작업하도록 한다.

VCS는 사실 소스 자체를 통합적으로 관리하고 싶었지만, 추후 프론트와 백엔드의 각기 다른 WAS에서의 관리를 위해 프론트와 백단을 따로 나누는 게 좋다고 판단하였다. CI또한 따로 작업을 관리하고, 통합 Gradle파일만 별도로 두도록 한다. 

 

Agile/Issue Tracker/Architecture Design

JIRA On Demand를 구입해 두었으므로 사용하도록 한다. 전반적인 아키텍쳐 설계는 엑셀과 키노트로..

 

Data Science

현재 GCE에서 지원하는 Prediction API나 Apache Spark를 사용해 보려 한다. 근데 이건 추후 문제..

 

Deployment/Server

Deploy 목표는 WAR파일이 아닌, JAR파일 혹은 BIN으로 서버에 배포해서, 컨테이너 단위로 Docker에 배포하여 Scalable한 서버를 구축하고 싶은 것. 개인적으로 AWS보다는 Google Cloud를 사용하고 있고, GCE에서 자체적으로 Kubernate를 지원하고 있어서 하나의 컨테이너 파일만 만들면 Scalable하게 관리가 쉽게 될 것으로 보인다. 다만 아직까지 내가 헷갈리는 것은 리소스 관리를 위한 HTTP서버와 RestFul을 기본으로 한 백엔드가 따로 존재해야 하는지에 대해서이다. 예전에는 Apache HTTP서버에서는 프론트단 자원 관리를(HTML, CSS, JS등) Apache Tomcat에서는 Servlet을 동작시켜서 분리하곤 했는데, 아마 이 방식대로 가는게 전반적인 프론트/백엔드의 분리를 위해서는 올바른 선택일 것이다.

거기다 최근 Git서버가 상당히 꼬여있음을 알게 되었는데, 솔직히 자원 낭비랄까.. Jenkins와 Gitlab이 함께 올라가 있으니 그럴 만도 하다. Tomcat과 node.js 가 함께 돌아가고, 거기다 프록시를 위한 nginx까지 겹쳐 있다. 이 역시 docker로 분리해서 사용할 필요성을 느낀다. JIRA도 마찬가지.

즉, CI/VCS/Agile 환경에서의 세 개의 컨테이너와, 운영에서의 프론트(Node.js) 와 백엔드(Embedded WAS) 이렇게 총 네 개의 컨테이너를 우선 사용하고 추후 추가적인 사항이 발생시에 따로 또 컨테이너를 분산시키고자 한다. 뭐 CDN과 같은..

 

향후 커리어를 위한 대비책

얼추 위에까지 설계하니 드디어(!) 전반적인 업무 Flow가 나왔다. 물론 도식화를 해 봐야 어느정도 감이 잡히긴 하겠지만.. 어쨌든, 미국에 온 만큼 보다 더 글로벌한 기술에 집중하기 위해 커리어를 어느정도 부분 변경할 필요가 있다.

우선 개인 프로젝트인 urhyme에서는 play! framework와 Scala를 도입한다. 예전엔 뭐 시기가 아니니 뭐니 하며 별로 하기 싫었지만, 작년에 한번 WebSocket서버를 만들어 본 결과, Akka와 함께 동작하는 부분이 마음에 들었다. 즉, Actor기반으로 무언가 Concurrency를 해결하고자 하는 부분이 말이다. 물론 솔직히 아직 액터방식에 대해서 크게 잘 모른다. 그래도 새로운 패러다임인 만큼, 공부해서 나쁠 것은 없다고 본다.

어차피 백엔드 작업이다. 물론 Play!에도 마치 Velocity처럼 View영역 작업이 scala언어를 통해 가능하지만, 그렇게 되면 또 다시 백엔드와 프론트가 묘하게 연결되어 버린다. 분산시켜야 한다. 백엔드는 RestFul API로써의 동작만 할 뿐이다.

또한, DB자체도 MongoDB나 Google BigTable류의 NoSQL종류로 바꿔보고자 한다. 솔직히 RDB설계가 재밌긴 하지만, 최근의 그런 웹서비스 설계에는 무언가 한계가 있지 않나 싶다. 이 부분도 연구해 봐야 할 문제.. 

한편으론 데이터 사이언스를 공부하며, 머신러닝과 데이터 마이닝 기술을 익혀야 할 것 같다. 통계학적 접근이 아닌, AI로의 접근으로..

 

결국 공부할 것들

뭐 최근에 Kubernete도 공부하고, 도커도 약간은 개념이 잡혔다. 하지만 공부할 께 아직도 많다. 가장 중요한 것은 리눅스를 다시금 공부해야 한다. 또한 스프링 4.2도 공부해야 하고, 가장 중요한 것은 jUnit과 Mocha에서 이뤄지는 테스팅에 대해, TDD중심의 개발로 변경하고자 하니 또한 TDD도 공부하며, SOA중심적으로 아키텍쳐 하는 방법론과, Agile환경에서의 적용. 결국 요구분석-설계-개발-QA-배포 의 과정, 즉 Software Engineering을 다시금 복습해야 하며, O/S와 Programming Language도 한번 다시 복습해야 할 필요가 있다. 프론트는 말할 것도 없고..

데이터 사이언스 또한 익혀야 할 것 같다. 머신러닝과 데이터 마이닝 기술을 익히고, 이 전반적인 과정을 내가 배웠던 AI를 통해 익히도록 노력해야겠다.

 

Conclusion

이렇게 한 2주 정도 고민하고 공부하다가 글을 쓰고 나니 솔직히 매우 시원하지만, 더 솔직히 말하면 다 때려치고 그냥 쉬운 개발을 하고싶다. 예전 JSP같은 한 페이지에 냅다 때려박는, 그런 개발이 편했다는 느낌이 물씬 들긴 하지만.. 결국, 모든 것은 개발론의 중심으로 돌아오는 구나 싶다. 그래도, 이런 개발환경을 구체화 함으로써 풀스택 개발자로써의 그 영역도 보다 더 프론트와 배포로써 더 깊게 나아간 것 같다. 중요한 것은, 공부는 공부대로 개발은 개발대로 서로가 조화롭게 진행되어야 한다는 점이다. 마치, 지금의 내가 학교를 다니면서 개발을 병행하는 것처럼.. 이론만 빠삭해봐야 실무를 안해보면 그건 전혀 소용이 없다고 본다. 개발 70 : 이론 30 정도의 비중으로, 꾸준히 나아가야 할 필요성을 느낀다.. 그래도 어느정도 마스터 플랜이 나왔으니, 공부와 개발 계획을 잘 세워보고 조금씩 나아가 보겠다. 🙂