[네이버클라우드캠프] - Final Project Report (힐링캠프 project 회고록)

holy one·2023년 10월 31일
0
post-thumbnail
  • 프로젝트기한 : 2023년 9월 11일 ~ 10월 27일
  • '힐링캠프' 프로젝트 설명 :
    현대인들에게 웹 푸시 알림과 다국어 커뮤니케이션이 가능한 실시간 채팅 기능을 제공하는 글로벌 힐링 소셜 네트워크 시스템
  • 맡은 역할 : CI/CD 및 아키텍처 설정과 서버 구축 및 관리

1) Architecture

  • 총 구성도

  • Cloud 구성도

  1. 서버 구성: 하나의 VPC, 총 4개의 서브네팅을 통하여 총 3개의 서버구성, public 서버에서는 주로 프론트엔드 기술을 활용하여 구현하고,나머지 private 2개 서버에서는 백엔드 기술을 중점적으로 구현
    (Node 서버를 통해 I/O 중심의 서비스 구현 효과 극대화하도록 유도)

  • ACG는 172.16.x.x ip에 관하여 1-65536 포트까지 오픈
  • 총 4개의 서브넷으로 구성)
  • NCP에서는 로드벨런스 전용과 Gateway 전용 subnet이 존재
  • 특히 로드밸런스는 private 전용이 아니면 서브넷 생성이 불가했다!
    (그렇지만 로드밸런스는 공용 IP 발급이 가능했다.)
  1. 데이터베이스는 총 3개의 데이터베이스로 구성
  • 각 서버와 효율적으로 연동되어 운영
  • Mongo DB
  • Redis DB
  • MySQL DB
  1. 로드 밸런스는 하나의 로드 밸런서를 사용하여, 클라이언트의 요청을 각 서버로 적절하게 분산시켜 안정성과 효율성을 보장
  • 로드 벨런스는 private 서브넷이더라도 공인 ip를 받고 서버 접속을 통제한다는걸 알게되었다.
  • 리스너에 별 host header 규칙을 두고 연결을 시도했다.(DNS Host가 *로 모든 https 연결 안정화)
  • 443 port 는 인증서 발급 후 사용 가능 자세한 인증서 발급 방법은 아래의 링크에가서 발급 가능하다.

    Lensencrypt를 이용하여 DNS에 https 연결하기 - werybalert
    https://velog.io/@ghdlf0619/httpsconnectnginxconnect

  • HTTPS를 사용하는 이유는 데이터 보안과 외부 서비스 호환성을 확보하기 위해 필수적이었으며, 이를 위해 letsencrypt를 통한 인증서 발급 및 로드밸런싱을 도입하여 웹푸시 알림을 효과적으로 구현하였다.

port num용도
3000React
3001Node
4000spring
8080jenkins
  1. 게이트웨이는 하나의 게이트웨이를 통해 외부 통신을 안정적으로 관리하며, 내부 네트워크의 보안을 강화했다.

  • 게이트 웨이 연관 Router에는 private 서브넷이 연결된 router들이 연관되어 있음을 확인했다!(router는 서브넷 생성과 동시에 생성됨을 확인할 수 있다.)

결론) MSA를 모방 아키텍처 선정 이유

초기 1차 프로젝트 단계에서는 웹 푸시를 핵심 기능으로 구축하였다. 이후 채팅 및 번역 기능의 통합 요구가 발생함에 따라 서비스 지향 아키텍처(MSA)를 채택하여 다양한 서비스 요구사항에 유연하게 대응할 수 있도록 설계하였다. 또한, 데이터 보안과 안정성을 위해 프라이빗 존을 구축하되, 외부와의 통신이 필요한 서비스들은 NAT Gateway를 통해 프라이빗 존 내에서도 퍼블릭 역할을 수행할 수 있도록 구조를 최적화 및 서비스의 독립성, 확장성, 안정성, 그리고 배포의 유연성을 확보하기 위함에 구축하였다.

  • 아키텍처 비교
초기(1차)최종(2차)

2) Redis && Mongo DB

  • Redis와 MongoDB의 차이점
    Remote Dictionary Server(Redis)와 MongoDB는 데이터를 비정형 형식으로 저장하는 NoSQL 데이터베이스
  • Redis는 데이터를 키-값 쌍으로 저장하는 오픈 소스 인 메모리 데이터베이스
  • 고성능을 위해 RAM에 데이터를 저장하지만 추가 기능으로 온디스크 영구 스토리지를 제공
  • 이번 프로젝트에서 Redis는 인 메모리 데이터베이스로 빠른 세션 및 캐시 관리를 가능케 한다는 특징을 살려 백엔드 서버의 중앙 세션 관리에 활용했다.
  • MongoDB는 데이터를 직렬화된 JSON 형식으로 저장하는 소스 사용 가능 도큐먼트 데이터베이스 (외부 메모리에 데이터를 저장하지만 엔터프라이즈 에디션에는 인 메모리 스토리지 엔진이 포함되어 있다.)
  • 이번 프로젝트에서는 MongoDB는 도큐먼트 지향적으로 비정형 데이터를 유연히 다루는 특징을 살려 대량 채팅 데이터의 저장과 조회에 활용했다.
  • 이번 프젝의 Redis와 MongoDB 공통점
    Stand Alone role로 이중화 구성과 고가용성을 사용하지 않은 단독 서버로 구성

레디스 선정 이유

  • 빠른 응답 속도: Redis는 인메모리 데이터베이스로, 디스크 I/O에 의존하지 않기 때문에 높은 처리 속도를 보장한다.
  • 단순성 및 효율성: "Redis Simple" 모드를 선택하여 단순하면서도 필요한 기능을 효율적으로 활용할 수 있었다.
  • 구성 및 호환성: 레디스 버전 4.0.14는 안정성이 검증된 버전이며, G2 서버 세대와 함께 사용하여 높은 성능과 호환성을 보장 또한, 선택한 VPC와 서브넷 설정은 서비스의 안전성과 확장성을 고려했다.

핵심) 레디스 선정의 Issue

하지만 네이버 클라우드 플랫폼 service 요금 안내 비교에 따르면 Redis가 Mongodb의 설치 스펙 요금 효율 데비 70원 더 비싸다는걸 발견

한달 사용 요금에서 5천원 이상의 과금이 발생하였고, 따로 MySQL, Mongo DB가 존재 및 Redis의 역할은 mongo가 대체가 가능했지만 비용적 부담과 db 낭비라는 부담을 안고 사용한 이유 를 찾아야 했다.

Link : https://scalegrid.io/blog/redis-vs-mongodb-performance/

노드의 세션 토큰 관리에는 높은 조회 속도와 데이터 효율성이 필요했다. 이번 프로젝트의 핵심 채팅 기능은 노드 서버에서 이루어졌으며 노드의 대다수 워크로드에서는 읽기 작업이 주를 이룬다고 판단했다.
redis와 mongo db의 읽기 성능 비교는 Scalegrid라는 플랫폼 전문 회사의 'Percona 메모리 엔진을 사용한 Redis 및 MongoDB 성능 비교'test를 통해 redis의 성능 우수함을 판단했다.

따라서 초기에는 MongoDB를 활용하여 채팅 데이터와 세션 값을 통합하여 관리하려 했으나, MongoDB의 과부하 문제를 고려하면, 추가적인 서버 확장 비용, 장애 처리 비용, 그리고 유지보수 비용이 증가할 수 있었다고 판단헀다.
또한, Redis는 초기 비용은 높지만 성능과 안정성 면에서 우수하다는 여러 자료를 바탕으로 볼 때, 장기적으로 보면 성능 저하의 위험을 줄이는 데에 더 효과적일 것으로 서버 관리자로 판단했다.
따라서, Redis의 시간당 추가 요금 70원을 감수하면서도 Redis를 선택하는 것이 바람직하다고 결론 지었고, 비용 희생을 통한 서비스 안정화를 이뤄낼수 있었다.

3) CI/CD 전략

CICD 구성

  • Docker 컨테이너 기반의 Jenkins 환경을 구축하여 웹 페이지에 성공적으로 통합했다. 로드밸런싱을 통해서 모든 서버의 리스너가 원활히 연결될 수 있도록 최적화하였으며, 안정적인 서버 간의 통신을 위해 ssh-keygen을 활용하여 보안 연결을 마련했다.

  • "Publish Over SSH" 플러그인은 이러한 통신 구조를 더욱 강화하고,
    빌드 프로세스 측면에서는 Gradle Plugin (버전 2.8.2)과 NodeJS Plugin (버전 1.6.1)을 활용하여 Jenkins 내에서의 빌드 환경을 세밀하게 구성하였다.

  • 그리고 이를 바탕으로, 각 서버로의 파일 전송 전 Build Steps를 통해 필요한 배포 파일들을 준비,Publish Over SSH 플러그인의 Exec command 기능을 이용하여 각 서버에서 실행할 스크립트를 통해 서버의 실행 완성도를 극대화하였다.

  • "Send files or execute commands over SSH"의 Exec command 기능을 이용하여 각 서버에서 실행할 스크립트 성공 구축하였다.

    자세한 script는 아래의 linkdml CICD 레포에서 확인할 수 있다.
    https://github.com/NC7-1st-TeamProject-1st-Team/2nd-sns-notification-system/tree/dev/CICD

왜? jenkins Gradle,node plugin을 사용해서 배포했는가?

Jenkins에서 Gradle 및 Node plugin을 사용하여 배포를 결정한 배경에는 여러 중요한 이유가 있다. 처음에는 자체 서버 스크립트를 통해 npm과 gradle을 활용하여 배포를 진행하려고 했다.
이 방식은 초기에는 간단하고 효율적인 방법처럼 보였다. 하지만 실제 배포 과정에서 서버의 불안정 문제가 발생하다.
이러한 불안정성은 배포상황에서 큰 리스크로 다가왔고, 빠르게 이 문제를 해결하기 위한 대안을 찾아야 했다.
Jenkins의 플러그인 시스템은 이미 검증된 수많은 프로젝트에서의 사용 경험을 통해 안정성과 효율성이 입증되어 있었다. 이러한 배경 지식을 바탕으로 Jenkins의 Gradle 및 Node plugin을 도입하는 것을 결정했다.
이 플러그인들은 직접적인 빌드 과정을 Jenkins 서버 내에서 처리함으로써 외부 서버에 발생할 수 있는 여러 변수들을 줄여주며, 빌드 및 배포의 안정성을 크게 향상시켰으며,결과적으로 Jenkins의 Gradle 및 Node plugin을 사용하여 빌드 및 배포를 진행함으로써, 서버의 안정성 문제를 극복하고 배포 능률을 크게 향상시켰다.

느낀점:

이번 프로젝트에서 Kubernetes 도입과 docker의 제약에 있어선 아쉬움이 가득하지만,개발자 조원들과 열정적으로 대안을 찾아내며 창의성을 펼쳐 프로젝트를 완성했다는 점에서 뿌듯하다.
이러한 아키텍처 구축 성공과 비용 관리를 통한 프로젝트 성과로 자부심을 느끼며, 미래 도전에 자신감을 키우고 현업에서 강화된 나만의 전략과 협업 능력을 갖추도록 노력해야겠다.

profile
☁️ 좋아요!

0개의 댓글