이번주는 시험기간이어서 원하는 강의를 들을 수 있었다.
평소 대용량 트래픽 처리에 관심을 두고 있었는데, 감사하게도 선택 강의 옵션 중에 있었다.
강의 소개
패스트캠퍼스 - [스페셜] 백엔드 개발자를 위한 한 번에 끝내는 대용량 데이터 & 트래픽 처리 초격차 패키지 Online
MySQL, Spring, JdbcTemplate, EasyRandom을 이용하여 SNS 프로젝트를 만든다.
source : https://github.com/koogk7/fastcampus-mysql
강의 정리
서버 개발자의 핵심의 데이터이다.
=> 어떻게 많은 양의 데이터를 안정적으로 삽입, 갱신, 조회할 것이냐?
=> 정규화, 인덱스, 트랜잭션, 동시성 제어에 대해 배운다.
강의를 들은 후
- 원하는 기술 스택을 이용하거나 리팩토링 하여 다시 이 프로젝트 만들어보기
- 부하 테스트 해보기 feat. ngrinder, jmeter
- MSA로 발전시켜 보기
부하 테스트
시스템의 부하를 증가시켜 테스트하는 것
- 부하를 발생시키는 도구: ngrinder, jmeter
- 부하 모니터링 도구: APM - 제니퍼, Elastic APM
- 중요한 점: 적절한 부하를 선택하여 테스트하기
출처: https://scshim.tistory.com/442
MSA(Microservice Architecture)
- 소규모 프로젝트 개발 배포 형식인 Monolithic Architecture과 다르게, 중간~대규모 프로젝트에서 사용된다.
- API를 통해서만 상호작용이 가능하다. 실질적인 부분은 모두 추상화한다.
- 장점: 서비스 모듈화, 서비스별 배포 가능
실습 환경 구축하기
⚡️ mysql 설치하기
brew install mysql@8.0
🫧 mysql 실행하기
brew services start mysql
🫧 mysql 상태 확인
brew services list
✔️ mysql 콘솔 접속
mysql -uroot
✔️ 비밀번호 설정하기
⚡️ 초기 비밀번호는 공백이다.
✔️ database 만들고 확인하기
intellij DB 설정하기
드라이버 설치 안 했다면 설치해 주기!
Test Connection
만약 db에서 root에 대한 비밀번호를 설정하지 않으면 연결 오류가 발생할 수 있다.
application.properties
Cause: error: invalid source release: 16 에러 해결
프로젝트 자바 버전과 현재 사용 중인 버전이 맞지 않아 발생되는 오류이다.
=> build.gradle의 sourceCompatibility를 현재 자신이 사용하는 버전으로 변경하자.
버그 해결 과정
같은 오류를 해결한 블로그를 찾았다.
나의 경우 현재 java 11을 사용하므로 JDK1.8을 따로 설치하였다.
https://velog.io/@dlalscjf94/MacOS-JDK-1.8-%EC%84%A4%EC%B9%98with-brew
설치된 java 버전 확인 방법 (리스트로 확인 가능)
/usr/libexec/java_home -V
Project Structure에서 SDK를 1.8로, Language level을 8로 설정하기
이 정도에서 오류가 해결된다고 하는데, 자꾸 같은 에러가 떠서 sourceCompatibility를 바꿔줬다.
프로젝트의 sourceCompatibility를 8로 바꿔주자.
톰캣 8080으로 잘 뜨는 것을 볼 수 있다.
어디 부분에서 에러가 났을까 생각해 보다가, 인터넷에서 발견한 해결책을 내가 잘못 이해했다는 것을 깨달았다. 🥲
깃클론한 프로젝트는 자바 버전 16을 사용하고 있고, 현재 나의 자바 버전은 11이다.
인터넷에서 본 해결책은 project structure의 JAVA8 (JAVA1.8)과 Language level을 8로 바꿔주라는 것이었는데,
나의 경우 JAVA8은 설치되어있지 않아서 그것까지 설치했었다.
그러나 굳이 JAVA8을 설치하지 말고, 그냥 sourceCompatibillity만 11로 바꿔주면 될 문제였다.
허허..
sourceCompatibility란?
컴파일에서 사용하는 JDK 버전, 더 높은 버전의 Java를 사용하는 것을 방지한다.
비슷한 것으로 targetCompatibility도 있는데, 이것은 더 낮은 버전의 Java를 사용하는 것을 방지한다.
프로젝트 클론시에 설치된 버전과 프로젝트 버전이 맞지 않아 이러한 오류가 자주 발생한다고 한다. 🧐
Swagger 접속하기
http://localhost:8080/swagger-ui/index.html
/hello로 쿼리 보내기
Swagger란?
- 애플리케이션의 RESTful API 문서를 자동으로 구성하는 특수 도구
- endpoint에 대한 요청과 응답을 즉시 확인할 수 있다.
출처: https://appmaster.io/university/ko/tutorials/endpoints/swagger-ran-mueosimyeo-sayong-bangbeob
대용량 시스템 이해하기
웹의 기본 아키텍처
웹의 복잡도가 증가함에 따라 서버가 웹서버와 웹 애플리케이션 서버로 분리되었다.
- 웹 서버는 정적 데이터를 처리한다. -html/css/js
- 웹 애플리케이션 서버는 db처럼 동적으로 변하는 데이터를 처리한다.
강점 : 관심사의 분리 / 관측가능한 시스템 / 효율적인 리소스 사용
관심사의 분리 - 컴포넌트를 관심사나 역할에 맞게 분리
- 역할에 맞는 다양한 최적화 기법을 사용할 수 있다.
- 문제의 범위를 줄일 수 있다.
- 시스템의 복잡도가 증가하는 단점
왜 데이터베이스는 병목일까?
서버의 스케일 업 / 스케일 아웃
스케일 업: 하나의 서버의 사양을 높여서 더 많은 요청을 처리할 수 있도록 하는 것, 슈퍼 서버
스케일 아웃: 서버의 개수를 늘려서 부하 분산시키기
스케일 업 | 스케일 아웃 | |
유지보수 및 관리 | 쉬움 | 여러 노드에 적절히 부하분산 필요 |
확장성 | 제약 존재 | 스케일업에 비해 자유로움 (서버만 추가하면 됨) |
장애복구 | 서버가 1대, 다운타임 존재 | 장애 탄력성 존재 (장애 발생하면 나머지 서버로 돌리기 가능) |
스케일 아웃은 여러 개의 서버가 동일한 데이터베이스를 접근한다. (서버마다 같은 결과를 반환해야 하므로)
데이터베이스 스케일 아웃
데이터베이스를 여러 개 사용한다면 어떻게 될까?
- 데이터베이스는 데이터라는 상태를 관리하고 있어 스케일 아웃 서버보다 훨씬 많은 비용이 필요하다.
- 또한 서버의 스케일아웃은 메모리를 이용하여 상태관리를 하지만 데이터베이스는 디스크에서 데이터를 접근하므로 훨씬 처리속도가 느리다.
- 서버와 데이터베이스사이에는 네트워크 구간이 존재하므로 언제든지 느려질 수 있다.
그러므로 현대 서버 아키텍처는 상태관리를 데이터베이스에 위임하고, 서버는 상태관리를 하지 않는 방향으로 발전한다.
여기서 상태란 데이터이다.
위의 말이 이해가 되지 않아서 chatgpt한테 물어봤다.
요약하자면,
현대 서버 아키텍처에서는 데이터베이스에 상태(데이터)를 저장하고, 서버는 상태를 조회하거나 변경하는 API 역할만 한다.
이렇게 하면 서버는 상태를 처리하는 것이 아니라, 단순히 API를 호출하고, 데이터베이스에서 데이터를 가져오거나 변경하는 역할만 수행하므로, 서버에서 처리할 수 있는 API 요청 수는 많아질 수 있다.
또한, 여러 대의 서버를 추가하더라도 데이터베이스에서 상태를 관리하므로 서버 간의 상태 동기화가 필요 없어서 복잡도가 낮아진다.
=> 즉, 데이터베이스는 스케일아웃 시 많은 비용이 필요하고 느리므로 서버에서 스케일 아웃을 한다.
=> 데이터베이스의 스케일아웃이 어렵다는 점은 데이터베이스에서 병목이 발생하는 이유를 설명해준다.
대용량 트래픽 / 데이터 처리는 왜 어려울까?
- 하나의 서버 또는 데이터베이스로 감당하기 힘든 부하
- 다수의 서버와 데이터베이스를 마치 하나인 것처럼 동작시켜야 함
- 웹 서비스들은 24시간 무중단
- 잘못된 코드 한 줄이 미치는 영향의 범위가 크다
- 여러 마이크로 서비스들이 복잡한 의존 관계를 가진다. => 시스템의 복잡도 ⬆
대용량 시스템의 특징
1. 고가용성 : 언제든 서비스 이용가능
2. 확장성 : 증가하는 데이터와 트래픽에 대응 가능
3. 관측가능성 : 문제 발생 시 빠르게 인지할 수 있고 문제의 범위를 최소화할 수 있어야 함
대용량 시스템 아키텍처
1. 로드밸런서 : 여러 개의 서버에 적절하게 부하를 분산시킨다.
2. 캐시 : 데이터베이스 응답속도를 빠르게 만든다. - 글로벌 캐시(여러 서버들이 캐시 공유)/ 로컬 캐시(각 서버 메모리에 캐시) 정하기, 캐시 주기 정하기, 만료 정책 정하기
3. 비동기큐 : 대외기관으로부터의 연동으로 응답속도가 느려지는 것을 막는다. - 카프카, RabbitMQ 또는 하나의 서버 내에서 스레드 풀 이용
=> 비동기 큐는 클라이언트 요청에서 대외기관 연동 부분만 처리. 대외기관이 받는 적절 tps에 따라 보내는 요청량 제어 가능
카프카(Kafka) vs RabbitMQ
카프카(kafka) : pub/sub 방식, 생성자가 각 메시지를 게시할 수 있도록 하는 메세지 배포 형태
=> 방대한 양의 데이터 처리에 강점
RabbitMQ : 중개인 중심적인 설계, 보장되는 메시지 전달에 초점
=> 관리 측면 (Manage UI 제공), 다양한 기능을 위한 서비스 구축 시 장점
출처: https://velog.io/@cho876/%EC%B9%B4%ED%94%84%EC%B9%B4kafka-vs-RabbitMQ
전체 시스템 확장
위와 같은 시스템 집단으로 구성되어 있다.
'Spring > 카테캠 - TIL' 카테고리의 다른 글
TIL [0511- 0514] : Spring Basic + Spring MVC 1 (2) | 2023.05.14 |
---|---|
TIL [0504-0505] : 객체지향 프로그래밍(예외처리, 로그, IO 스트림, 직렬화) (0) | 2023.05.06 |
TIL [0503-0504] : 객체지향 프로그래밍(내부클래스, 람다식, 스트림) (0) | 2023.05.05 |
TIL (0424 - 0429) : 객체지향 프로그래밍 (0) | 2023.04.29 |
TIL (230410 - 230416) (2) | 2023.04.22 |