계층형 댓글 파일럿 프로젝트

3개월의 수습기간 동안 진행한 프로젝트

개발을 시작함과 동시에 점점 시간이 빛과 같은 속도로 흘러감을 느끼게 되었…하…..


1. 계층형 댓글을 구현한 간단한 게시판 만들기
(웹 개발자에겐 누워서 떡먹기?? 아..아닌데..)

게시판을 만들기위해 필요한 조건을 PPT로 만들어 주셨고, 필수 스펙은 다음과 같았습니다.

선택기술은 다음과 같았습니다.

필수 사항은 반드시 사용해야하는 기술이였고, 선택사항은 추가적인 기술스펙이였습니다.
필수 스펙을 보면 아시겠지만, java8, Spring 4.*버전, SpringBoot 등 최신 버전(제가 쫌 올드한 것 같다는 느낌이 많이 들었습니다.)으로 개발을 진행하였습니다.

이전에 3.0 버전과 전자정부프레임워크, Maven만을 사용해봐서 SpringBoot, Gradle을 사용하며 신세계를 맛(쓰면 쓸수록 스프링개발이 편한 맛??)보았습니다.

그 밖에 처음 사용해 보았던 hibernate(책만 사놓고 안써봄, 결국 처음엔 개발에 급급해서 myBatis, iBatis처럼 개발), MySQL(오라클만 써보았습니다.), Git(뭔지 궁금해서 한번해보고 SVN만 써봄), Security(한번 써봤습니다.) ,Log4j(로그찍는 것은 실서비스에서 꼭 필요한 기능임을 알게 됬습니다..로그 레벨도 있습니다.) 등을 사용하였습니다.

**굵은 글씨**는 제가 선택했던 선택기술입니다.(나머지는? 잘 모르는 것들..)

Freemarker는 처음 들어 봤는데(알고 보니.. JSP탬플릿은 몇 해 전 부터 개발이 중단되었고, 그 뒤를 이어가는 자바진영의 서버 탬플릿 -그 밖에 대표적인 서버 탬플릿 Velocity, Thymeleaf) 이란 것을 알게 되었습니다.

Node나 Backbone, grunt, npm와 같은 프론트 기술들을 잘 사용해 보지 않은 저 였기에 2주라는 기간 동안에 개발이 힘들 것이라 판단하고 과감히 포기하였습니다..(기술 스펙트럼이 좁다는 것을 다시 한번 느끼게 되었습니다.)

망한건가?

필수 구현 기능

필수 구현해야 했던 기능들 입니다.

회원 기능

기본 게시판(요약)

이상으로 필수 기능과 필수 기능을 구현하기 위해, 사용했던 기술 설명을 추가로 붙여 보았습니다.(궁금.. 하셧죠?)



1차 프로젝트 어려웠던 점.

학원이나 스터디에서 오로지 기능완성만을 위해서 개발을 진행했습니다.. 회사에서 서비스 관점에서도 본다면 훠~~~얼씬 고려해 봐야 할 것이 많다는 것을 알게 되었습니다.

코드리뷰를 하며, 가장 많이 수정해야할 부분이 네이밍 규칙이였습니다.
습관 처럼 마음대로 변수 이름을 정하고, 테이블을 만들어 내고 있었습니다..

*팀내에서 DB는 snake 표기법을 준수하고, 코드는 camelCase를 따릅니다.

그 밖에..

*의미없는 String str; 같은 변수명은 피합니다.
*1,2,3 과 같은 매직넘버는 절대 피해야 합니다. (final, enum을 활용)
*클래스명은 명사이고 대문자로 시작합니다.
*패키지명은 소문자로 씁니다.
*메소드명은 동사이고 소문자로 시작합니다.
*변수명은 소문자로 시작합니다.
등.. 많습니다.

개발을 시작한지 3일만에 git을 잘 못 사용해서 프로젝트를 날려먹고 다시 처음부터 개발했습니다.
그 만큼 저에게는 친숙하지 못했는데 쓰면 쓸수록 개발자에겐 필수 tool이라는 것을 느꼈습니다.

1차 프로젝트를 마치며 느낀점.

*노다지 [명사]
1. <광업>캐내려 하는 광물이 많이 묻혀 있는 광맥.
2. 손쉽게 많은 이익을 얻을 수 있는 일감을 비유적으로 이르는 말.

다음엔 더 잘 할 수 있을거야..
다음엔 더 잘 할거야..


2. 이글루스(php)를 자바로 포팅하기.

실서비스를 포팅해본다는 엄청난 경험이 나에게??

두근두근?

진행할 작업

위 페이지를 자바로 포팅하는 작업.

작업 진행순서

실 서비스되고 있는 이글루스 로직과 사용 데이터를 분석합니다.
php의 기본 문법을 찾아 보는 수준이여서 이글루스 분석을 진행하면서, phpschool에서 php를 어느정도(아주 조금?) 공부하였습니다. 로직상에 연결된 테이블과 배치성 데이터를 확인하고 분석하였습니다.
(파악하고 나니.. 이미.. 1주일이란 시간이 지난 간 후 였습니다..)

이글루스 개발서버에서 사용되고 있는 배치성 파일들과 개발 DB를 활용하여 구조를 설계하였습니다.
(보안 상 파일럿프로젝트 부분만 공개합니다!)

시스템 구조도
구조

배치성 파일 parsing 로직
배치성파일 parsing 로직

간략 설명
Spring 스케줄러가 배치성파일(인기글(테마별), 전체 인기글, 인기테마 등)을 파싱하고, 이를 EHcache에 담아 사용합니다. 또한, 내부 API를 호출하여, 실시간 검색 랭킹 데이터를 활용하였습니다.

*배포 순서
war 파일 생성 -> 개발 서버로 복사 -> nohup을 이용한 백그라운드 실행 -> NginX 리로드(NginX 설정 파일을 생성은 미리) (위 배포 방법은 실제 서비스 배포와 전혀 무관한 방식입니다.)


부딪혔던 문제

많은 문제가 있었지만, 기억에 남는 일부입니다.

문제는 아니였지만, 지금까지 생각해 보지 않았던 것이여서 추가해 보았습니다.(저에게는 신선한 충격..)

이미지를 LazyLoding하는 이유는 숨겨진 이미지를 미리 로딩하지 않고 이벤트가 발생했을 때, 이미지를 로딩하여 페이지 로딩 속도를 높이기 위해서 입니다.(저만 몰랐던것이죠..)

처음에 제가 눈여겨 본것(당연히 구글링)은 jquery의 lazyload플러그인 이였습니다. 이벤트 발생했을 때 lazyload함수를 통해서 이미지를 로딩하는 방식입니다. 하지만, 페이지가 로딩될 때 jquery.load 플러그인을 추가로 로딩하기 보다는 아래와 같이 구현 하였습니다.(선임 님의 힌트를 덥석 받아 먹었습니다.)

data-src에 이미지url를 저장

이벤트가 발생했을 때, data-src의 주소를 src로 변경해주는 방법만으로 간단하게 구현 할 수 있었습니다.

1) static Util - 변함없는 단순 메소드로 사용할 경우 - JDK당? 하나를 만들어 공유할 경우

2) @Component(default : singleton)
- 초기화가 필요한 경우(ex-@PostConstruct) - DB 관련 작업이 있는 경우(@Autowired를 사용할 때) - lazy 생성이 필요한 경우 - 좀 더 객체지향 구현을 원하는 경우 - IOC(스프링컨테이너) 당 하나를 공유할 경우

성능상 차이는 거의 없다고 합니다. 또한, 둘다 스레드 safe 입니다. static Util은 사용자가 객체를 생성하고, @Component는 IOC에 객체생성을 위임합니다(제어의 역전).

@PostConstruct를 여러 곳에서 사용하고, 서로를 참조했더니 IOC 빈 초기화 과정에서 의존성문제가 발생했습니다.
처음에 접근 했던 방식은 순서를 지정해줘서 의존성 문제를 풀기 위해 노력했습니다.

제가 찾아낸 방법은 ‘@DependsOn’을 사용해 먼저 초기화 되야 하는 Bean을 명시해주는 방식이였습니다.

하지만, 이렇게 명시적으로 순서를 정해주는 것을 남용하게 되면 또다시 의존성문제에 부딪힐 수 밖에 없기 때문에, 되도록이면 자연스러운 초기화 과정을 지키는 것이 좋다는 것을 알게 되었습니다.
(결론적으로, 로직을 수정하여서 해결하였습니다.)

*@DependsOn : 해당 Bean 이전에 초기화되어야 하는 하나 이상의 Bean을 명시적으로 강제하기 위해서 사용.


마치며.

처음 시작하면서 말씀드린 것과 같이 3개월 동안 프로젝트를 진행하면서 저에겐 시간이 빛에 속도로 지나간 것 처럼 빠르게 지나갔습니다.

프로젝트를 진행하면서 가장 크게 느낀점은 스스로 문제를 판단 할 수 있는 능력이 부족하다는 것이였습니다.
앞으로 해나갈 프로젝트(삽질?)에서도 항상 왜? 라는 물음을 잊지 않고, 이를 통해 더 나은 개발자로 성장해 나가고 싶습니다.

프로젝트 기간동안 소중한 시간(매우 소중한 2시간? 저 때문에 야근까지..)을 내어 코드를 리뷰해주시고 지도해주신 선임, 팀장 님께 감사드립니다.