발표 자료
<피드백>
1. 현재의 아키텍처를 구성하게된 근거들 또한 조금 더 추가되면 좋겠습니다. -대본수정
2. Redis는 어디에 위치해있는것인지 잘 보이지 않습니다. 또한, 현재의 아키텍처를 가졌을 때 발생할 수 있는 문제점들은 어떤것들이 있을지 그리고 그 해결방법은 무엇인지 생각해 보셨을까요? -
3. 발표 자료에서 조금 더 기술적인 부분들로 내용들이 채워지면 좋겠습니다. -
<아키텍처 문제점>
1.
단일 실패 지점 (Single Point of Failure, SPOF): EC2 인스턴스가 단일 노드로 보이는데, 이 경우 하나의 EC2 인스턴스에 장애가 발생하면 전체 서비스가 다운될 수 있어. 고가용성을 위해 여러 인스턴스와 함께 로드 밸런서 뒤에 애플리케이션을 배치하거나, 자동 복구 및 스케일링을 가능하게 하는 서비스 (예: AWS Auto Scaling, Elastic Load Balancing)를 사용하는 것이 좋아.
2.
데이터베이스 백업 및 복구: 아키텍처에는 데이터베이스 백업 및 복구 전략이 명시되어 있지 않아. Amazon RDS는 자동 백업을 제공하지만, 재해 복구를 위한 전략(예: 다중 AZ 배포, 스냅샷, 복제)을 구현하는 것이 중요해.
3.
스케일링 전략: 사용자의 수가 증가함에 따라 시스템이 어떻게 수평적으로 확장될 수 있는지에 대한 정보가 없어. 트래픽 증가에 따른 자동 스케일링을 지원하기 위한 전략이 필요해.
1.
데이터베이스 보안: RDS 인스턴스가 VPC 내에 존재하는지, 적절한 보안 그룹과 네트워크 ACL로 보호되고 있는지 확인해야 해. 또한, 데이터베이스를 공개 인터넷에 노출하지 않도록 주의해야 해.
2.
트래픽 암호화: 다이어그램에서는 사용자와 NGINX 사이의 HTTPS 연결만 표시되어 있어. EC2 인스턴스 내부와 RDS, Redis, S3 버킷 간의 통신도 암호화되어야 하는데, 이 부분이 명확하지 않아.
3.
모니터링 및 로깅: 시스템의 상태를 실시간으로 모니터링하고 로그를 수집하는 시스템의 부재는 장애 발생 시 빠른 대응을 어렵게 만들어. AWS CloudWatch 또는 ELK 스택 같은 도구를 사용해 모니터링과 로깅을 강화해야 해.
<원본>
안녕하십니까
Spring 3기 B-7조 사뿐 발표 시작하겠습니다.
발표는 다음과 같은 순서로 진행하겠습니다.
먼저 프로젝트 소개입니다.
언제 어디서나 걷는 동안 아름다운 풍경을 감상하고 마음을 정화할 수 있는 산책은 폭넓은 연령대에서 인기있는 취미입니다.
저희는 이러한 점을 바탕으로 '나만의 산책로를 공유하고 소통할 수 있는 사이트'를 만들고자 했으며, 프로젝트 이름을 몸과 마음을 가볍게 산책하자는 의미에서 ‘사뿐’으로 정했습니다.
먼저 프로젝트 소개입니다.
언제 어디서나 걷는 동안 아름다운 풍경을 감상하고 마음을 정화할 수 있는 산책은 폭넓은 연령대에서 인기있는 취미입니다.
저희는 이러한 점을 바탕으로 '나만의 산책로를 공유하고 소통할 수 있는 사이트'를 만들고자 했으며, 프로젝트 이름을 몸과 마음을 가볍게 산책하자는 의미에서 ‘사뿐’으로 정했습니다.
다음으로 서비스 아키텍처를 설명하겠습니다.
저희는 스프링 프레임워크와 통합되어 있어 모델과 뷰 사이의 상호작용을 쉽게 구현할 수 있는 타임리프를 사용하였습니다.
이를 통해 서버측에서 동적으로 데이터를 렌더링하여 페이지를 빠르게 표시할 수 있도록 하였습니다.
사용자는 HTTPS를 통해 Nginx로 요청을 보내고,
Nginx는 포트 번호가 다른 두 개의 스프링 부트 컨테이너에 번갈아 가며 연결합니다.
이는 무중단 배포를 가능하게 합니다.
docker-compose를 통해
각 스프링 부트 컨테이너가
돌아갈 때 토큰 관리를 위한
redis 컨테이너가 함께 시작되도록 환경을 설정하였습니다.
또한 Amazon RDS에 호스팅된 MySQL DB,
그리고 파일 저장을 위해
S3 버킷을 사용하였습니다.
개발자는 IntelliJ와 MySQL을 사용하여 코드를 작성하고, GitHub에 Push합니다.
이렇게 Push된 코드는
GitHub Actions를 통해
CI/CD 과정을 거쳐 AWS EC2 인스턴스에 자동 배포됩니다.
다음으로 저희 팀원을 소개하겠습니다.
리더이신 홍정욱님,
부리더이신 김재한님과
김진환님, 박상율님, 이예진님으로 구성되어있으며
각자 맡은 역할은 다음과 같습니다.
저희는 약 5주간의 프로젝트를 다음과 같이 진행하였습니다.
1주차에는 주제 선정 및 ERD,
API 명세서, 유스케이스, 와이어프레임을 작성하여 프로젝트를 기획하였고
팀 컨벤션을 바탕으로 기능을 구현하였습니다.
2주차에는 백엔드 기능 구현을 마무리하고 프론트 코드 작성을 시작하였습니다.
3주차에는 중간 발표 진행 후, 무중단 배포를 적용하였으며, 유저테스트를 시작하였습니다.
4주차에는 유저 피드백을 수렴 및 반영하였습니다.
또한 queryDsl을 적용하고 N+1문제를 해결하는 등 코드 리팩토링의 시간을 가졌습니다.
5주차에는 팀원 전원이 수동 배포를 진행해보고 최종 발표를 준비하였습니다.
다음은 배포된 사이트에 접속하여 MVP 기능을 시연하겠습니다.
(서브모니터 75% 비율)
메인페이지입니다. 좋아요순으로 3개의 게시글을 표시합니다.
그리고 메뉴를 통해 전체게시글과 지역별 게시글 조회가 가능합니다
(전체)게시글 목록은 좋아요순과 최신순으로 정렬이 가능하며 페이징 처리가 되어있습니다.
로그인으로는 로컬로그인과 카카오 네이버 소셜로그인이 가능합니다.
네이버 소셜로그인을 진행하겠습니다.
글쓰기 버튼을 통해 게시글을 작성할 수 있습니다.
지역을 선택하면 해당 지역으로 지도가 이동되고
현재 위치 찾기를 통해 자신의 주변 위치를 찾을 수 있습니다.
(확대 6번)
산책로 그리기를 통해 산책로를 지도에 도식한 후
지도를 캡쳐를 하면 캡쳐된 지도가 아래에 표시됩니다.
출발지와 경유지 목적지를 작성후 내용과 이미지를 넣고 완료버튼을 누르면 게시글이 작성됩니다.
(게시글 누르며 컨트롤 스크롤 1번 안으로)
작성된 게시글을 확인할 수 있으며
게시글 작성자 프로필도 확인 가능합니다.
게시글의 댓글은 이미지를 추가하여 작성이 가능하고
좋아요 수정 삭제 기능 또한 가능 합니다.
프로필 사진을 누르게 되면 자신의 좋아요와 게시글 및 프로필 정보를 관리할 수 있습니다.
또한 본인의 활동에 따라 랭크 등급을 확인 할 수 있습니다.
(시연끝).
다음은 기술적 의사결정에 대해 발표하겠습니다.
먼저, Refresh Token 사용 및 로그아웃 처리에 대한 의사결정 내용입니다.
저희는 서버 간의 데이터 동기화 문제를 해결하기에 좋고 확장성이 좋은 토큰 인증 방식을 사용하였는데
이때 access token의 보안성을 높이고자 유효기한을 1시간으로 설정하였습니다.
하지만 이 경우 사용자가 1시간마다 로그인해야 한다는 문제점이 발생하여
refresh token도 함께 발급하기로 결정하였습니다.
토큰을 관리하기 위해서 Redis를 사용한 이유는
Redis가 인메모리 DB로
빠른 응답이 가능하며
TTL을 지원하여 토큰의 만료 시간을 지정하고 관리하는데 유용하기 때문입니다.
또한 Key-Value 구조로 refresh token을 쉽게 저장하고 검색할 수 있습니다.
저희가 구현한 토큰 작동 방식은 다음과 같습니다.
이 중에서도 로그아웃 기능을 어떻게 구현할지 고민하였는데
저희는 사용자가 로그아웃하는 경우 access token을 남은 유효 기간만큼 TTL을 설정하여 redis에 저장하고 refresh token을 redis에서 삭제하기로 하였습니다.
이때 access token을 서버에 저장한다면 토큰 인증 방식의 이점이 사라지는 것은 아닌지 고민하였습니다.
그렇지만 서버에 저장하는 데이터의 양이 적고,
로그아웃 시에 쿠키만 삭제하는 것보다 보안성을 높일 수 있기 때문에 다음과 같이 구현하기로 결정하였습니다.
다음은, Nginx를 이용한 무중단 배포 및 https 적용 결정입니다.
첫째로, GitHub Action을 통해 자동 배포를 구성했지만, 수정사항을 적용하는 과정에서 서버의 downtime이 발생하는 문제가 있었고,
둘째로, Google Maps API에서 현재 위치를 가져올때 위치권한이 필요한데 HTTP에서는 제한되어 현재 위치를 가져올 수 없는 문제가 발생했습니다.
위 두가지 문제를 해결하기 위해 고민하던 중
Nginx라는 리버스 프록시 서버는 적은 메모리 사용량으로 높은 성능과 효율을 내고
정적 파일 처리에 적합한 기능을 갖추고 있다는 것을 알게 되어 도입했습니다.
downtime이 발생하는 문제를 해결하기 위해 Nginx를 통한 Blue-Green 배포를 활용했습니다.
이는 포트가 다른 두 개의 배포 환경을 병렬로 구성하여,
새로운 업데이트를 준비하면 기존 환경에서 새로운 환경으로 트래픽을 전환하는 방식입니다.
이를 통해 안정적이고 리스크가 낮은 배포가 가능했습니다.
그리고 Nginx의 플러그인을 활용하여 빠르게 SSL 인증서를 발급받아
HTTPS 환경을 구성하여 두 문제를 해결 했습니다.
다음으로 트러블 슈팅에 대해 발표하겠습니다.
저희는 redis를 사용하는 과정에서 두 가지 문제를 마주하였습니다.
첫 번째로
Refresh token을 통해 자동 로그인하는 과정에서 문제가 발생하였습니다.
Refresh token을 redis에 저장할 때 userId를 String으로 변환하여 value 값으로 저장하는데
redis에서 userId 값을 가져올 때 다음과 같은 문자열로 반환되었기 때문입니다.
따라서 매서드에
userId에 “가 있으면 제거하는 로직을 추가하였습니다.
두 번째로,
Redis에 저장된 refresh token이 삭제되고 키 값을 조회하였을 때 “backup”이라는 단어가 같이 조회되는 현상이 있었습니다.
이 문제를 해결하기 위해
redis 로그를 확인해본 결과
외부에서 타 용도로 사용되고 있었다는 것을 알게 되었습니다.
따라서 저희는
Redis 컨테이너에 비밀번호를 설정하였고
yml 파일 및 RedisConfig 코드를 수정하였습니다.
그 결과 redis에 더 이상 "backup"이라는 단어가 나타나지 않았고 데이터가 삭제되는 현상도 발생하지 않았습니다.
두 번째 트러블 슈팅으로는
이미지 업로드에 관련 문제를 해결했습니다.
용량이 큰 파일을 업로드하면 속도가 현저히 느려지는 문제가 발생했습니다.
이를 개선하기 위해, 이미지 리사이징을 통해 용량을 줄이는 방식을 선택하였습니다.
이미지 리사이징은 FileReader와 Canvas API 사용했습니다.
이 과정은 브라우저에서 직접 수행되므로 서버의 부담을 줄일 수 있었습니다.
이 방법을 통해 용량이 9MB였던 이미지를 150KB로 줄어든 이미지로 서버에 전송할 수 있었고,
응답 처리 속도가 크게 향상되었습니다.
앞에서 해결한 이슈에 대한 TEST 결과를 보겠습니다.
테스트 환경으로는
약 9MB의 동일한 이미지 4장을 사용하였고
크롬 브라우저의 개발자도구를 통해 응답시간을 측정하였습니다.
게시글 작성 부분에서
리사이징 전의 평균 응답 시간은
약 4초,
리사이징 후에는 약 0.67초가 나왔으며,
게시글 조회에서도 큰 차이를 확인할 수 있었습니다.
테스트 결과 자료는 다음과 같았습니다.
결과적으로 서버응답시간은 평균 약 6배이상개선되었고
이미지 로딩시간은 평균 약 30배 이상 개선되었습니다.
다음으로 추후 도전 계획에 대해 말씀드리겠습니다.
크게 기능 추가, 부하 분산 처리, UI/UX 개선이 있습니다.
추가기능으로 고려하고 있는 사항으로는
실시간 채팅, 팔로우 및 검색 기능,
지도 검색 및 경유지 연동 등이 있습니다.
부하 분산 처리에 대한 경험을 쌓고자 스케일아웃 및 로드밸런싱
도입을 고려하고 있습니다.
마지막으로 이용자를 늘리기 위해 중요하다고 생각되는 UI/UX 를 개선하고자 합니다.
마지막으로 자체 평가입니다.
저희 팀의 아쉬운 점으로
Redis 해킹 문제를 일찍 개선하지 못했다는 점과
FE 부분의 업무 배분이 미흡했다라는 점을 꼽았습니다.
좋았던 점으로는
적극적인 유저 피드백 수렴 및 반영과
각자 최선을 다해 역할을 수행하여 높은 수준의 프로젝트 완성도를 달성할 수 있었다 는 점을 골랐습니다.
저희는 유저 테스트를 진행하면서 받은 피드백을 적극적으로 반영하였습니다.
원래 사용자가 첨부해야 했던 지도 캡처 파일이
자동으로 첨부되도록 수정하였으며
게시글에 이미지를 각 20MB, 4장까지 첨부할 수 있도록 기능을 추가하였습니다.
또한 마이페이지에 내가 좋아요 한 글과 나의 글을 조회할 수 있는 페이지를 추가하였으며,
게시글과 댓글의 작성자 프로필을 모달창을 통해 조회할 수 있도록 구현하였습니다.
이상으로 발표를 마치겠습니다.
감사합니다.
<GPT4 대답>
안녕하십니까, 여러분. Spring 3기 B-7조의 '사뿐' 프로젝트 발표를 시작하겠습니다.
먼저, 저희 프로젝트 '사뿐'은 아름다운 풍경과 함께 마음의 정화를 얻을 수 있는 산책 경험을 공유하는 웹사이트입니다. 모든 연령대가 즐길 수 있는 산책의 매력을 발견하고, 사용자들이 자신만의 산책로를 공유하며 소통할 수 있는 공간을 제공합니다.
프로젝트의 서비스 아키텍처는 스프링 프레임워크와 타임리프를 활용하여 모델과 뷰 간의 상호작용을 간편하게 구현했습니다. 서버측에서 데이터를 동적으로 렌더링하여 사용자 경험을 향상시켰습니다. 사용자 요청은 HTTPS를 통해 Nginx로 전달되며, Nginx는 두 개의 스프링 부트 컨테이너로 요청을 분산시킵니다. 이는 무중단 배포를 가능하게 합니다. 도커 컴포즈를 통해 스프링 부트와 레디스 컨테이너가 함께 작동하며, Amazon RDS의 MySQL DB와 S3 버킷을 사용합니다.
개발 과정은 IntelliJ와 MySQL을 통해 진행되었으며, GitHub을 통해 코드를 관리하고 GitHub Actions를 사용하여 AWS EC2 인스턴스에 자동 배포합니다.
저희 팀원 소개를 드리겠습니다. 리더 홍정욱님, 부리더 김재한님과 김진환님, 박상율님, 이예진님으로 구성되어 있으며 각자의 역할은 프로젝트 기획, 백엔드 및 프론트엔드 개발, 데이터베이스 관리 등 다양합니다.
프로젝트는 5주간 진행되었습니다. 첫 주에는 주제 선정과 프로젝트 기획을, 둘째 주에는 백엔드 개발을 마무리하고 프론트엔드 개발을 시작했습니다. 셋째 주에는 중간 발표와 유저 테스트를 시작했으며, 넷째 주에는 유저 피드백을 반영하고 코드 리팩토링을 진행했습니다. 마지막 주에는 수동 배포와 최종 발표 준비를 마쳤습니다.
이제 배포된 사이트의 MVP 기능을 시연하겠습니다. 메인 페이지는 좋아요순으로 정렬된 게시글을 3개 표시하며, 전체 게시글과 지역별 게시글 조회가 가능합니다. 로그인은 로컬 및 카카오, 네이버 소셜로그인으로 진행됩니다. 게시글 작성 시 지역 선택, 현재 위치 찾기, 산책로 그리기 기능을 통해 사용자 경험이 풍부해집니다. 게시글과 댓글 작성, 프로필 관리, 좋아요 및 수정 삭제 기능도 포함됩니다.
기술적 의사결정 부분에서는 Refresh Token 사용 및 로그아웃 처리, Nginx를 이용한 무중단 배포 및 HTTPS 적용에 중점을 두었습니다. Refresh Token 관리를 위해 Redis를 사용하였으며, 로그아웃 시 access token을 Redis에 저장하는 방식을 채택했습니다. 무중단 배포는 Blue-Green 방식으로 진행했으며, Nginx를 통해 HTTPS 환경을 구축했습니다.
트러블 슈팅에서는 Redis 관련 문제와 이미지 업로드 속도 문제를 해결했습니다. Redis 문제는 보안 강화 및 구성 변경을 통해 해결했으며, 이미지 업로드 속도는 FileReader와 Canvas API를 사용한 리사이징으로 개선했습니다.
추후 도전 계획으로는 기능 추가, 부하 분산 처리, UI/UX 개선을 들 수 있습니다. 실시간 채팅, 팔로우 및 검색 기능, 지도 검색 및 경유지 연동 등이 포함됩니다.
자체 평가에서는 Redis 해킹 문제를 일찍 해결하지 못한 점과 FE 부분의 업무 배분 미흡을 아쉬운 점으로, 유저 피드백 수렴 및 반영, 팀원들의 열정과 노력을 좋았던 점으로 꼽았습니다.
이상으로 저희 '사뿐' 프로젝트 발표를 마치겠습니다. 여러분의 많은 관심과 지지 부탁드립니다. 감사합니다.