프로젝트/기업형SNS

프로젝트 아키텍처 설계 및 프레임웍.기술 선정하면서 하게 된 고민..

모지사바하 2015. 5. 2. 14:44

프로젝트는 아직 시작도 안했지만, (5월 6일 부터 시작)


아키텍처에 대한 고민은 이미 한달 정도 한것 같다..


프로젝트 기본 아키텍처 및 그동안 하게된 고민에 대해 간략히 작성한다.


Java 1.8

Spring Framework 4.1.6.RELEASE

Spring Boot 1.2.3.RELEASE

Spring Security 4.0.1.RELEASE

Spring Session 1.0.1.RELEASE - Redis

Spring HATEOAS 0.17.0.RELEASE

Mybatis 3.2.8


데이터베이스 MariaDB 혹은 MySQL


빌드/의존성 관리 Gradle

배포/빌드 Jenkins


현재 프레임웍 선정은 위와 같이 했고, 프로젝트 틀은 구축해놓은 상태이다..




위 프레임웍을 선정하면서, 많은 고민을 했다.


1. Data Access 계층으로 개인적인 욕심으로는 Spring Data JPA 나 Hibernate 를 쓰고 싶었다.


ORM 을 씀으로써 자바 엔티티 설계는 자연스레 많은 정성과 노력을 들여서 할 것이라 생각한다.


그런데, 사실 이러한 ORM 은 잘 모르는체로 썼을 때, 리스크가 매우 크고, 잘 알고 쓰면 생산성에 큰 도움이 되지만 잘 모르고 썼을 땐 오히려 생산성에 큰 차질을 빚을 수 있다. 내가 개발 할 수 있는 영역보다 외주업체에서 개발하는 영역이 더 클것이므로 그 분들에게 여쭤봤더니, 써보신 분이 없으셔서 패스했다.. 


그래서 다시 고민한게, 전통적인(?) 방식의 Mybatis 를 쓸 것인지, Spring JdbcTemplate 을 쓸 것인지에 대한 고민이다.


이번 프로젝트는 Java 8 로 진행되기 때문에 JDBCTemplate 을 사용할 때 람다식을 이용하여 RowMapper 선언이 매우 간결하게 처리 될 것이라 JdbcTemplate 으로 정하여 구축을 다 하였다.


Mybatis 를 안쓰고 굳이 JDBCTemplate 을 선택한 이유는 굳이 람다만의 이유는 아니였다.


내가 좋아하는 국내 개발자가 몇분 계신데 그 중 한분인 정상혁 님의 블로그 글 "Java에서 SQL없이 XML개발하기" 포스트를 보고 많은 공감을 했다.


또한 Mybatis 로 개발할 때, Mybatis 에서 정해진 다이나믹 문법이 불편했고 장황하게 느껴진 적도 많았다. 


하여 과감하게 Mybatis 를 걷어내고 JdbcTemplate 을 선택한것인데, 쿼리 스트링 보관을 어찌할지에 대해 고민을 많이 했다.


자바는 멀티라인 스트링을 지원하지 않아서 Stirng + 결합이나 StirngBuiler append 를 사용해야하는데, 둘 중 어느것도 맘에 들지 않았다.


정상혁님 블로그 글의 그루비 클래스나 @Multiline 도 쓰고 싶지 않았다 


하여, 그냥 각 dao 메소드내에서 StringBuiler append 방식으로 하려고 정하였는데,


생각해보니 이번 프로젝트에서는 쿼리가 mysql 용 쿼리 한벌, oracle 용 쿼리 한벌. 해서 총 2벌의 쿼리가 나오기 때문에 이방식이 문제가 좀 있었다..


또한 많은 개발자가 Mybatis 를 제일 많이 썼을 것이기 때문에, 결국 어쩔 수 없이 Mybatis 를 선택하게 되었다.




2. 전통적인 방식의 한 덩어리 개발을 할 것이냐. 요즘 대세인 MSA(Micro Service Architecture) 로 나눠서 개발할 것이냐..


사실 기업형 SNS 에 공룡기업들이 벌써 많이 뛰어들었다.


대표적으로 페이스북 at work, 네이버 웍스, 구글이 있고, 그 외에도 조사해본 바로는 많았다.


우리가 개발할 기업형 SNS가 이러한 공룡기업들을 상대로 내세울만한 특장점으로 생각한게, 


기본형 으로 최소 기능을 싸게 제공하고 특정 기능을 별도로 구매하면 플러그인 형태로 기존 시스템에 끼워넣는 형태를 생각하였다.


이러한 형태(특정 기능을 별도로 구매하면 플러그인 형태로 기존 시스템에 끼워넣는 형태) 를 구현하기 위해서는 MSA 가 둘도 없는 답이라는 생각이 들었다..


그리고 꼭 이러한 형태가 아니더라도, MSA 는 매우 흥미로웠고 장점이 많았다. 


예를 들어 특정 부분에 오류가 발생했을 때, 그 모듈만 수정하고 재시작하면 전체 시스템이 내려갈 일이 없다는 점이라던지.


여러 모듈로 프로젝트를 쪼개기 때문에 개발자 한명당 하나의 프로젝트를 잡고 개발을 하게 됐을 때 발생하는 생산성 향상 이라던지.


프로젝트가 너무 비대해지지 않는점. 등등 여러 메리트가 있는데,


이러한 메리트 이면에 좀 심각하고 복잡한 점이 있었다..


그게 뭐냐면 


1.각각의 모듈은 트랜잭션이 공유돼야하는 형태여야하는데 각각 별개의 프로젝트라 어렵다.

2.클라이언트가 어떤 요청을 했을 때 여러 서버로 요청이 라우팅돼야한다.

3.보안.인증도 모든 모듈에서 동일하게 적용돼야하며 구멍이 있어서는 안된다.

4.테스트가 어렵다.

등등.. 몇개 더 있는데 위에 나열한게 아마 가장 큰 해결해야될 숙제이다.


이러한 문제로 인해 MSA 앞단에 API Gateway 라는 것을 놓고 시큐리티.트랜잭션.라우팅 등을 처리하는데,


이 부분이 생각보다 복잡도가 크다..


결국 단순히 매력에 매료돼서 도입하기엔 너무 위험성이 크다는 판단을 하게 됐다. 


처음에는 MSA 로 프로젝트를 진행하려고 많이 알아봤는데, Spring Boot 는 MSA를 위한 많은 기법을 제공하고 있었다..


향후 MSA 로 확장할 수 있는 초석으로 Spring Boot 를 도입하였고, Spring Boot 위에서 한덩어리로 개발하기로

결정하였다.


Spring Boot는 MSA 를 목표로 나온 프로젝트이기 때문에, 일단 Boot 위에 올려놓으면 나중에라도 기능 확장에 용이 할 것으로 생각하였기 때문이다.





3. REST API 만으로 웹과 앱(IOS, ANDROID)에서 API를 호출하여 JSON/XML 형태로 받은 결과를 파싱해서 쓸지,

앱(IOS, ANDROID)에서는 API 를 호출하고 웹에서는 전통적인 개발방식으로 할 지 고민을 좀 했는데,


어치파 REST API 에서 결과를 제공하는데 굳이 웹에서 다시 개발할 필요가 없을 것으로 생각되어 REST API 에


웹.앱 같이 쓰기로 결정하였다.




SNS 의 가장 기본적인 글쓰기. 타임라인 아키텍처에 대해서 아주 큰 고민을 했는데 이부분이 또 내용이 한가득이라 다음에 포스팅해야겠다..