1. 축제기간
- 2023.09.25. ~ 2023.09.26.
2. 프로젝트 기간
- 8~9월 (기획 ~ 최종배포까지)
- FE 개발기간: 4주 (8월 말 ~ 9월 중반)
- BE 개발기간: 2주 (9월 초 ~ 9월 중반)
3. 팀원: 15명
- 기획: 4명
- FE: 4명
- BE: 2명
- 디자인: 4명
- 인프라 1명
4. 기술스택
- 언어: Java(JDK 11), HTML/CSS, React
- 서버: Apache Tomcat, naver cloud platform
- 프레임워크: Spring Boot
- IDE: IntelliJ IDEA Ultimate 2023, mysql Workbench, Postman, xftp7, Visual Studio Code
- DB: MySQL8.X
- API, 라이브러리: RESTFUL API(JSON), JPA, local cache
# 프로젝트배경
개인적으로 대규모 서비스는 어떻게 만들어지는 게 좋을까?라는 고민을 한 적이 있다.
전자공학과에서 "김윤홍 교수님"의 수업을 가장 좋아했었다.
김윤홍 교수님은 과제를 내셔도 정답보다 코드의 의도, 고민의 흔적을 집중하셨습니다.
나는 정답에 연연하지 않고 확장성 있는 클린한 코드를 짜는 교수님의 모습이 멋있었고 고민하는 시간이 즐거워서 코딩을 좋아하게 됐다. 이런 점에서 나는 백엔드공부를 하면서 대규모서비스에서 일어나는 최적화 배경이 궁금했다. 유튜브에서도 "이동욱 개발자"님께서 말씀하신 (소규모, 대규모) 정산 시스템이 아키텍처가 바뀌는 모습에서도 멋있음이 뿜뿜 느껴졌다.
그러던 와중에
#동기, 친구, 멋쟁이 사자처럼
들이 축제사이트에 관해 얘기하는 모습이 보였고, 나에게도 백엔드직종을 제안하게 되며 같이 얘기하다 보며 이런 나의 생각들이 떠올랐고 같이 시작하게 됐다. 기획을 해주는 팀원이 디자인팀도 구해주고 총학생회와도 연결해 주며 무려 대규모팀(15명!!)이 결정되었다. ==> 지금 생각해 보면 이 정도 규모는 아니었는데... (처음이니까 그럴 수 있다.)
# 초반기획
총학생회가 이미 축제를 기획한 것이 있고 그거에 따라가는 느낌이 강했기 때문에 내가 크게 관여한 부분은 없다.
하지만 총학생회가 기획한 일을 백엔드 관점에서 분석하고 일어날 일들을 예측하여 미리 알려드리고, 좀 더 나은 개선사항에 관해서 의견을 나눴다. 그리고 같이 축제를 성공적으로 끝내려면 백엔드의 의견은 필수적이다(?) ㅎㅎ
내가 낸 철없던 의견 일화가 기억에 남는다. 기획과 얘기할 때는 개발경험이 없다 보니 안정적인 개발환경을 생각하기보다 재밌고 사이트를 많이 이용하는 축제이벤트를 생각했다. 예를 들어, 실시간 오후 9시에 추첨을 진행하여 사이트 이용자 중에서 축제선물을 제공하는 것이다. 지금 생각하면 대규모서비스를 기획하고 싶다는 욕심에 어려운 서비스를 했다고 생각한다. (물론, 반영되진 않았다, 개발 이외에도 총학생회에 의견이 있기에 거부되었다.) 이런 실시간 서비스는 배달의 민족 쿠폰(10,000원) 뿌리기, 코로나 유행시절 마스크 싸게 팔기, 공모주 오전 9시에 사람몰리기(주식서버)등 시간적인 이벤트를 진행하면 서버가 터지는 경우가 다반사이다. 아마도 확장성 있는 코드와 개발을 하지 않았으면 나도 서버가 위험했을 거라 생각한다. 하지만 다음에 도전하고 싶은 건 당연하다..!!
그래서 기획과 초안을 총학생회로부터 파일도 받고 회의도 진행이 되었다. 개발적인 이야기로 디자인팀과도 아이템이 어느 정도 정해져서 디자인팀이 먼저 디자인개발에 들어갔다.
# 디자인 기획
전에 멋사 해커톤에서 디자인팀과 협업을 한 적이 있지만, 디자인팀이 4명이나 붙어서 같이 협업을 한 적은 처음이다.
긴장하게 됐고, 점차 디자인의 결과물을 보며 백엔드의 책임감을 가지게 되었다.
들어가다 확인하다 보면, 가끔 이상한(?) 사진이 있다.
나중에 디자인팀원에게 물어보니 디자인하다가 멘털 나갔을 때 아무 사진을 넣는다고 한다.
코딩하다가 코딩이 너무 안될 때, printf("으아악\n");이라 적고 쉬는 거랑 비슷하다고 생각했다.
사진으로 감정이 느껴져서 마음이 아팠다.
"비상(飛上)"이라는 축제답게 메인디자인로고를 보면 비행기처럼 날아오르라는 감정을 가지게 만든다.
# 백엔드 기획과 회의
축제는 백엔드적인 면모보다 보이고 정보제공이 많기 때문에 백엔드는 2명에서 만들기로 했다.
했던일들은 아래와 같다.
1) 누적 실시간 방문자 수 (저장과 조회)
2) 관지자페이지 로그인 및 구현
3) 관리자페이지를 통한 이벤트페이지 아이템 실시간 편집(edit)
4) client가 바라보는 이벤트페이지 db조회
이다.
물론 디테일하게 보면 배운 점이 많다.(SSL인증서, DTO모듈설계, cache, spring session 등)
나는 BE팀장을 맡게 되었고 2,3,4를 하기로 하였고 팀원은 1번은 맡기로 하였다.
# 백엔드 개발
막상 개발을 하려고 보니, 실사용자가 이렇게 들어와 본 적이 없다는 사실을 깨달았다.
그러다 보니, 갑자기 할 일이 폭탄이 되었다.
원래는 고려하지 않던 트래픽 상황, 서버폭파, 보안등을 고려하게 되었다.
원래도 최적화와 확장성 높은 코드를 짜기 위해 생각이 많았다.
이번 개발에서는 이런 생각들이 모여 더 깊고 여러 가지 생각을 했다.
일단 저번 프로젝트(멋사 해커톤)에서 한번 Rest API를 사용해 봤기에, 이번에도 빠르게 API를 완성할 수 있었다.
하지만 그거와 별개로, 명세서 API를 저번에 열심히 작성하지 않았었는데,
이번에 프로젝트를 통해서 기획에 중요성과 소통의 중요성을 알게 되었다.
#DBMS
그다음에는 사용을 해봤었던 MySQL를 사용해 DB를 구축했다.
이벤트페이지에 들어가는 물품개수와 관련되는 정보였다.
그런데 관계형 DB의 관한 내용이 아니었다. Nosql인 MongoDB를 사용했어야 했는데, 최종배포 전에 공부하여 바꾸려 했지만 배포에서 시간을 너무 많이 소모해 바꾸지 못했다.(이 점이 아쉬웠고, 미리미리 공부했었으면 사용가능했을 거라는 생각이 들었다.)
#클라우드 배포
다음은 보안을 고민하게 됐다. 이 과정에서 트래픽 고민이 생기게 되었다.
배포과정에서 얼마나 많은 사용자가 들어오는지 예측이 힘들었고, 예를 들어, 10초의 몇 번에 트래픽 또는 API조회가 일어나는지를 예측을 하는 과정이 수치적으로 사용자와 관련하여 무슨 결과로 예측되는지 고민했다.
이는 지금 결과를 보고도, 아직 이해하기 힘들다.
공부했던 결과에 의하면, 쇼핑몰로 예를 들면, (오후 8시~오후 10시) 사이에 사용자가 몰리기에 load balance를 그때 달아서 서버사양을 그때 확장시켜서 서버 안정성을 높이고 사용자가 적을 때, 다시 원래대로 돌아가며 네트워크 비용을 최적화한다고 하였다.
비록 우리는 VPC를 사용하여 네트워크를 구축하지 않고 NPC의 클래식 1을 이용하여 서버를 구축하였기 때문에
load balance를 달진 못했다.
하지만 최적의 시간에 따른 이용자들을 고려한 점, 서버에 관한 생각을 하며 클라우드는 어떻게 돌아가는지 공부했으니
다음에는 이 내용을 기획할 때, 먼저 생각하고 이행할 수 있을 것 같다.
#보안
갑자기 트래픽을 생각하다 보니, 악의적인 매크로 공격에 의한 많은 API 조회공격이 일어날 수 있다고 생각했다.
사실 이런 공격이 "DDoS" 공격이었다.
DDoS(Distributed Denial of Service) 공격 서비스 중단을 목적으로 표적 서버, 서비스 또는 네트워크에 인터넷 트래픽을 대량으로 보내려고 시도하는 악의적인 사이버 공격의 형태입니다 |
이런 공격과 더불어, 관리자페이지의 보안을 어떻게 계속 강화할 수 있을지 고민했다.
일단 첫 번째 해결책은,
클라우드 서비스에서 IDS를 달아 첫 번째 보안을 챙겨가는 것이었다.
침입탐지시스템(IDS) 네트워크 트래픽에서 의심스러운 활동이 있는지 모니터링하고, 그러한 활동이 발견되면 경보를 발령하는 시스템 |
IDS는 클라우드서비스에서 3~8만 원 정도로 추가할 수 있었다.
이 프로젝트는 규모가 크기에 서버비용을 투자해야 했었다.
서버비용+IDS + 등등 계속적인 금액과 보안이 올라갔고, 이런 방식이 있다는 게 더 중요하다고 깨달았다.
최종적으로 IDS는 달지 않았다.
금액적인 부분으로 아깝다고 생각했다.
축제는 정보 제공용이기에 해킹시스템에 돈을 투자하기보다 "안정성"에 중점을 두기로 결정했다.
그래서 이런 클라우드서비스가 있다는 사실을 공부했다는데 의의를 두었다.
2번째 보안위험은
해킹기술은 전부는 모르지만, 네트워크시간에 배운 스니핑(Sniffing) 공격기술이 떠올랐다.
내가 설계할 때 그린 백엔드 아키텍처가 있다.
로그인만 관련해서 그린 초반 아키텍처이다.
이때, 로그인도 있지만 중간중간에 API 날아갈 때 스니핑 할 수 있지 않을까?라고 생각하게 되었다.
일단
스프링 <==> DB는 중간에 JPA인 ORM기술을 사용하면 중간에서 알아서 암호화해 준다는 내용을 들었다.
따라서 여기는 괜찮다고 생각했다.
그다음은 프론트 <==> 스프링에서 API가 날아다니는 부분이 문제였다.
그래서 내가 생각한 부분은 get 말고 patch를 이용해서 update 할 때는 로그인을 이용해서 update를 막는 것이다.
스프링에서 관리자페이지를 로그인을 구성할 때, 세션을 이용한다는 글이 많았다.
EventApiController는
관리자가 접근하는 정보가 담겨있는 컨트롤러다.
여기서 아이템 GET, PATCH를 진행하는데, 이 권한을 관리자가 로그인했을 때만 가능하도록 만들었다.
이때, config패키지 해서 로그인 EndPoint경로 아래에 로그인권한을 모두 설정할 수 있다.
따라서 interceptor 하는 곳을 만들었다
해당 부분에서 로그인이 되었었는지, 세션에 접근하여 로그인 ID를 확인한다.
성공 => true 반환
실패 => false 반환
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private final MemberService memberService;
@Autowired
public WebMvcConfig(MemberService memberService) {
this.memberService = memberService;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SessionInterceptor(memberService))
.addPathPatterns("/admin/festival/api/**");
// .addPathPatterns("/event/**");
}
@configuration 어노테이션을 이용하여, 관리자권한이 필요한 곳에 EndPoint를 넣어주었다.
#SSL
마지막으로, 보안에서 SSL인증서 문제가 있었다.
http로 배포하게 되면 보안상 안전하지 않는다는 사실을 알게 되었다.
인증서 인증을 통한 https로 배포하게 되었다.
< http와 https 글 올릴 예정, 이곳에 링크 걸 거임>
공부한 내용을 참고해 주기 바랍니다.
# 배포
배포 전, 총학생회와 회의가 진행됐다.
9차 안건까지 축제가 나왔다는 말을 듣게 되었다.(이를 들으면 부스페이지가 계속 바뀌어 프론트팀원들이 고생하는 게 조금은 이해될지도,, 모두 고생이 많았다.)
최종 배포 후, "Google 애널리틱스"로 client를 분석할 수 있다는 사실을 알게 되었다.
물론 NCP를 이용해서 하드웨어 이용률을 분석할 수 있었지만, 애널릭틱스르 많이 이용한다는 사실을 알게 되었다.
메인 html파일에 계정을 연동하여 추가하였다.
# 배포 그 후
축제 하루 전에 최종 배포를 하였는데, 3일 중 첫째 날에 GA를 달지 못했다.(그날이 가장 많이 들어왔는데 아쉬워요.)
총학생회 기획팀에서 멋있게 홍보해 주셨다.
# 에브리타임(학생 커뮤니티) 후기
많은 좋은 평가를 주셔서 기분 좋게 댓글을 읽었었다.
# GA
분석결과 "1,600명"의 사용자분들이 들어오셨다.
그리고 누적 이벤트 횟수 "12,000회"가 발생했다.
학교 이용자의 25%의 인원이 우리의 서비스를 이용해 주셨다.
이용자가 늘어남에 따라 다음에는 사람들에게 더 "필요한" 서비스를 만들고 싶다는 생각을 하게 되었다.
# 기술적으로 얻은 것
얻은 것은 개괄식으로 작성하겠다
- 성능테스트를 진행해야 한다. (Jmeter, ngrinder)
- SSL 인증서 사용법
- 보안 (IDS, DDoS)
- 서비스 기획 프로세스의 이해
- 여러 개의 매핑(PUT, GET, PATCH 등등)
- Connection Pool
- DNS
- cache의 이용과 이해, 스프링에서 cache
# 마무리 느낀 점
대규모 프로젝트를 여러 사람에서 진행하기 위해서는 "체계적인 프로세스"가 중요한 것 같다.
이번 프로젝트는 타임어택으로 진행되었던 것 같다.
이는 대규모 프로젝트라면, 더더욱 체계가 잡혀야 하는 게 아닌가?라는 고찰을 하게 된다.
자신이 할 수 있는 범위 내에서 최선을 다해 업무를 끝내는 일도 매우 중요하다.
1. 명세서를 당연하게 알아보게 짜는 것
2. 주기적으로 연락 또는 소통하며 업무의 현황을 공유하는 것
3. 코드리뷰를 진행하며 더 미래의 일들도 소통해 보는 것
이런 여러 가지 커뮤니케이션에서 훌륭한 프로젝트로 이어나간다고 생각하게 되었다.
결론은,
모두와 함께하는 프로젝트를 진행해 볼 수 있어서 감사하다.
같이 하신 모든 분들 수고 많으셨습니다.
축제앱 실제 사진 보여드리며 글 마치겠습니다.
긴 회고 봐주셔서 감사합니다.