실습 - 클라이언트 배포
S3 호스팅 튜토리얼
배포 완료 확인
서버 배포가 완료되었을 때 확인 방법
EC2 인스턴스를 통해서 서버를 실행한 뒤 Postman을 이용해 테스트를 진행합니다.
서버 배포 성공 시 'Hello Spring World!' 응답을 받습니다.
클라이언트 배포가 완료되었을 때 확인 방법
생성한 버킷의 엔드포인트 주소에 접속하여 아래와 같은 화면이 보이는지 확인합니다.
실습 - 데이터베이스 연결
RDS 인스턴스 연결 튜토리얼
데이터에 접근할 수 있는 사용자 이름과 DB 비밀번호는 외부에 노출되지 않도록 주의 바랍니다.
서버 환경 설정
EC2 인스턴스에서 실행되고 있는 서버는, 그 자체로는 작동하고 있지만, 아직 데이터베이스와 클라이언트에 연결하지는 않았습니다.
서버의 환경 설정을 통해 지난 실습에서 생성한 RDS 인스턴스에 접속하고, 클라우드 데이터베이스를 사용할 수 있게 해 봅시다.
1. 서버 코드에 저장된 application.properties 파일에 환경 변수 설정하기
EC2 인스턴스에서 실행하고 있는 서버를 종료합니다. 로컬이 아닌 EC2 인스턴스의 터미널에서 다음 단계를 진행합니다.
- java를 이용해 프로세스로 실행 중인 경우 Command + C
- 백그라운드에서 실행 중인 경우 실행 중인 프로세스를 종료합니다.
이제 환경 설정 파일을 수정해 봅시다. application.properties 파일을 nano 에디터를 사용하여 수정합니다.
$ cd be-sprint-deployment/DeployServer/
$ nano src/main/resources/application.properties
application.properties 파일에서 변경해야 할 환경변수는
- spring.datasource.url 변수에서 {} 부분에는 AWS RDS '엔드포인트 주소:포트'가 들어가야 합니다.
- spring.datasource.username 변수에는 AWS RDS Mysql 마스터 사용자 이름을 넣습니다.
- 생성된 RDS 인스턴스의 마스터 사용자 이름은 admin으로 설정되어 있습니다.
- spring.datasource.password 변수에는 AWS RDS Mysql 마스터 암호를 넣습니다.
- config.domain 에는 AWS S3 Endpoint 주소를 넣습니다. 해당 부분에는 꼭 앞에 http:// 가 포함되어야 합니다.
- CORS 설정을 위해 통신할 클라이언트의 도메인 입력이 필요합니다.
위 스크린샷에 보이는 것처럼 환경 변수를 할당하는 과정이 끝나면, Ctrl + X 키를 입력하여 변경 내용을 저장합니다.
위와 같은 화면이 보이면 y를 입력하고 Enter 키를 통해 파일을 저장합니다.
application.properties 파일을 통한 환경 설정이 완료되면, 이전 빌드를 삭제하고, 다시 빌드를 진행한 이후에, 서버를 다시 실행합니다.
$ ./gradlew clean
명령어를 사용하여, 이전 빌드를 모두 삭제한 이후,
$ ./gradlew build
명령어를 사용하여 수정된 환경변수가 적용하여 다시 빌드를 진행합니다.
2. 서버 실행
- java -jar build/libs/DeployServer-0.0.1-SNAPSHOT.jar 명령어를 입력하여 서버를 재실행합니다.
- Shell script를 이용해서 프로세스로 실행할 수도 있습니다.
- ./restart.sh명령어를 이용하여 서버를 다시 실행합니다.
서버를 실행하고 다시 s3 버킷의 엔드포인트 주소로 접속해서 연결 테스트를 진행합니다. 이름에 김코딩을, 비밀번호에 1234를 입력합니다.
아래와 같은 메시지가 화면에 보인다면 데이터베이스 연결에 성공한 것입니다.
뭔가 제대로 되고 있지 않아요!
위 메시지가 보이지 않고 다른 메시지가 화면에 출력된다면 아래 사항을 체크해 보세요.
- DB 인스턴스가 정상적으로 실행되고 있나요?
- 환경변수에 제대로 된 값을 할당했는지 확인합니다.
- DB 인스턴스의 엔드포인트 값을 환경 변수에 넣을 때, 앞에 http://를 붙이면 안 되고, 포트 번호는 반드시 입력해야 합니다. 위 스크린샷의 예시를 참고해 주세요.
- S3 주소를 입력할 때 다른 엔드포인트가 붙어있진 않은지 확인해 주세요.
- RDS 엔드포인트를 사용해서 MySQL에 접속을 시도하지만, 타임오류로 접속이 되지 않아요!
- AWS RDS 페이지에 접속한 후, 사용 중인 인스턴스를 클릭, 이후 연결/보안탭에서 VPN 보안그룹 정보를 클릭합니다.
우측 하단에 Edit inbound rules 버튼 클릭
- 규칙 추가 클릭 후, 유형에 모든 TCP, 소스에 모든 IP-V4를 클릭한 후 해당 규칙을 추가한 이후에, 저장 후 다시 확인하면 접속이 가능합니다.
- 크롬 개발자 도구의 Network 탭에 들어가서 요청, 응답 과정에서 어떤 오류가 발생하는지 확인합니다.
자주 하는 질문(FAQ)
Q. 실습 코드의 구조가 그동안 실습할 때 사용한 프로젝트와 다른 것 같아요!
A. 그동안의 실습 코드는 하나의 Spring Boot 프로젝트였습니다. 반면에 Cloud 유닛에서 사용할 실습 코드는 Full Stack Application 즉, 프론트엔드와 백엔드 코드가 하나의 Repository에 존재하는 구조입니다.
- DeployClient 디렉토리 : HTML, JS, CSS로 구성된 Front-End 코드
- DeployServer 디렉토리 : Spring Boot 기반의 Back-End 코드
Q. EC2 인스턴스에 실습 Repository가 권한 문제(permission denied)로 Clone 되지 않아요!
A. EC2 인스턴스에서 실습 Repository를 git clone 하는 위치를 확인하시기를 바랍니다. 인스턴스에 연결하여 bash 셸로 변경하면 현재 위치를 확인할 수 있습니다. 시작 시 기본 위치는 다음과 같습니다. /var/snap/amazon-ssm-agent/숫자
[이미지] git clone시 발생하는 Permission denied 에러
리눅스 시스템의 /var 디렉토리는 로그 데이터, 임시 파일과 같은 가변 데이터 파일이 저장되고 하위 몇몇 디렉토리는 외부 시스템에 공유가 불가능합니다. 따라서 위와 같은 기본 위치에서는 실습 Repository가 clone 되지 않으므로 콘텐츠에 안내된 대로 홈 경로(~)로 이동하여 진행하시기를 바랍니다.
Q. EC2 인스턴스를 재부팅할 수 있나요?
A. 인스턴스를 선택한 후 인스턴스 상태를 클릭하여 인스턴스 재부팅 버튼을 클릭하거나 인스턴스 중지 - 인스턴스 시작 버튼을 차례로 클릭합니다. 단, 재시작 직후엔 세션 매니저 재연결까지 시간이 일부 소요될 수 있습니다. (최대 약 15분) 인스턴스 종료는 인스턴스 삭제와 같습니다. 컴퓨터 종료와 다르니 주의하시기 바랍니다.
[이미지] 인스턴스
Q. 리소스가 없어요! / 리소스가 사라졌어요!
A. EC2 인스턴스, RDS 인스턴스 등 리소스가 보이지 않는다면 리전을 확인하시기 바랍니다. Cloud 전체 유닛의 실습은 서울 리전(ap-northeast-2)에서만 진행합니다.
[이미지] 버지니아 북부 리전의 EC2 인스턴스 대시보드
리전을 변경하지 않았어도 서비스를 이동하며 자동으로 버지니아 북부, 오하이오 등 다른 리전으로 변경되는 경우가 있습니다. 특히 글로벌 환경(e.g. S3, IAM 등)에서 이동하는 경우 종종 발생합니다. 위와 같이 리소스가 보이지 않는 경우엔 리전을 아시아 태평양(서울)ap-northeast-2로 변경하시기를 바랍니다.
[이미지] 서울 리전의 EC2 인스턴스 대시보드
Q. 세션 매니저 연결이 안 돼요!
A. 인스턴스에 오류가 발생하면 연결이 불안정해집니다. 대부분 잠시 기다리면 자동으로 연결되지만 기다려도 자동 연결이 안 되는 경우엔 인스턴스를 재시작하시기를 바랍니다.
Q. RDS 인스턴스 연결이 안 돼요!
A. 터미널에서 RDS 인스턴스 연결 확인 시, 비밀번호 작성 내용이 보이지 않아 비밀번호 입력 시 오타가 나더라도 알아차리기가 어렵습니다. 비밀번호 대소문자, 공백까지 재확인한 후 다시 시도하시기를 바랍니다.
Q. 3-Tier Architecture 배포 진행 중인데 로그인이 되지 않아요!
A. 3-Tier Architecture 배포는 서버 배포, 클라이언트 배포, 데이터베이스 연결을 모두 진행한 후 환경 변수 설정까지 완료되어야 로그인에 성공할 수 있습니다. S3, EC2, RDS를 이용해 각각 배포 환경을 만들고 클라이언트와 서버의 환경 변수 설정을 이용해 서로가 연결되어 있는지 확인이 필요합니다.
- EC2 인스턴스에 서버가 실행 중인지 확인합니다. (Hello Spring World! 확인)
- S3를 이용해 배포한 클라이언트에서 개발자 모드를 켜고(개발자 모드의 콘솔 탭 혹은 네트워크 탭) 로그인을 시도합니다.
- 클라이언트에서 요청 보내는 서버 주소와 EC2 인스턴스 서버 주소와 같은지 확인합니다.
- 주소가 다른 경우 로컬 환경에서 index.js의 url 값을 변경한 후 다시 S3에 업로드합니다.
- 서버 주소에 http:// 와 **포트는 포함되어 있어야 하며 끝엔 / 가 없어야 합니다. 이에 따른 값을 확인합니다.
- 콘솔탭에 요청 보내는 주소가 EC2 인스턴스가 아닌 S3 엔드포인트로 표시된 경우, 아래 5번 케이스를 참고하여 변수값에 공백과 같은 다른 문자가 추가되어 있진 않은지 확인합니다.
- EC2 인스턴스 환경에서 application.properties 파일에 값이 적절하게 포함되어 있는지 확인합니다.
- RDS 인스턴스의 포트(13306)까지 작성되어 있는지 확인합니다.
- username에 들어갈 값은 admin입니다. AWS IAM Username(e.g. be-0-seyun)이 작성되어 있진 않은지 확인합니다.
- domain 값에 S3 엔드포인트 주소가 정확하게 들어가 있는지 확인합니다. 마찬가지로 http:// 가 포함되어 있어야 하고 끝에 / 는 없어야 합니다.
- 모든 값이 정확하게 작성되었지만 로그인이 되지 않는다면, 환경 변수 값에 공백이 포함되어 있진 않은지 확인합니다.
- 공백이 문자로 인식되어 환경 변수 값에 적용되는 경우가 있습니다. 공백을 제거하여 저장합니다.
- e.g.) domain= <http://test.com> 와 같이 값을 저장한 경우 공백을 포함해 <http://test.com> 가 저장됨
- 공백이 문자로 인식되어 환경 변수 값에 적용되는 경우가 있습니다. 공백을 제거하여 저장합니다.
Q. EC2 인스턴스의 주소가 바뀌었어요!
A. EC2 인스턴스는 재시작될 때마다 Public IP 주소가 변경됩니다.
주소 변경으로 인해 실습 애플리케이션에 로그인이 안 되는 경우, 클라이언트의 index.js을 수정해야 합니다. 클라이언트 코드는 로컬에서 클론 및 수정 - S3 버킷에 업로드하는 과정을 거쳤기 때문에 로컬에서 다시 값을 수정한 후 결과물을 S3 버킷에 재업로드합니다.
Q. 인스턴스에 미달 프로비저닝 상태입니다.라는 문구가 떠있어요!
A. 이 문구는 현재 사용량이 많은 상황에 보일 수 있습니다. 해당 문구가 보이더라도 실습에는 영향이 없으므로 남은 실습을 마저 진행하시기 바랍니다.
고가용성(HA : High Availability)
프록시 서버
대리라는 뜻의 Proxy에서 알 수 있듯 프록시 서버(Proxy Server)는 클라이언트가 서버와 소통할 때, 서버에 바로 접근하지 않고 자신을 통해 서버에 접근할 수 있도록 해주는 일종의 대리 서버 입니다.
보통 일반 사용자는 지역이 제한되어있는 서비스를 이용하기 위해 우회하거나, 캐시를 통해 더 빠른 이용을 하기 위해 프록시 서버를 사용합니다. 하지만 이 외에도 프록시 서버를 통해 얻을 수 있는 이점들이 있는데요, 지금부터 프록시 서버의 종류와 사용함으로써 얻을 수 있는 장점에 대해 알아보도록 하겠습니다.
프록시 서버의 종류
프록시 서버는 위치에 따라 Forward Proxy와 Reverse Proxy 두 가지로 나뉩니다. 간단하게 말하자면 프록시 서버가 클라이언트에 가까이 있는지, 서버에 가까이 있는지로 구분할 수 있습니다. 각각 다른 목적을 기대하기 때문에 상황을 고려하여 판단을 내릴 수 있습니다.
1. Forward Proxy
Forward Proxy는 위의 그림과 같이 클라이언트 가까이에 위치한 프록시 서버로 클라이언트를 대신해 서버에 요청을 전달합니다. 주로 캐싱을 제공하는 경우가 많아 사용자가 빠른 서비스 이용을 할 수 있도록 도와줍니다. Forward Proxy를 사용함으로 인해 얻을 수 있는 장점으로는 다음과 같습니다.
- 캐싱을 통해 빠른 서비스 이용 가능 클라이언트는 서비스의 서버가 아닌 프록시 서버와 소통하게 됩니다. 그러한 과정에서 여러 클라이언트가 동일한 요청을 보내는 경우 첫 응답을 하며 결과 데이터를 캐시에 저장해놓고, 이후 서버에 재 요청을 보내지 않아도 다른 클라이언트에게 빠르게 전달할 수 있습니다.
- 보안 클라이언트에서 프록시 서버를 거친 후 서버에 요청이 도착하기 때문에, 서버에서 클라이언트의 IP 추적이 필요한 경우 클라이언트의 IP가 아닌 프록시 서버의 IP가 전달됩니다. 서버가 응답받은 IP는 프록시 서버의 IP이기 때문에 서버에게 클라이언트를 숨길 수 있습니다.
2. Reverse Proxy
Reverse Proxy는 반대로 서버 가까이에 위치한 프록시 서버로 서버를 대신해서 클라이언트에 응답을 제공합니다. 이후 로드밸런서 챕터에서 자세히 배울 분산처리를 목적으로 하거나 보안을 위해 프록시 서버를 이용합니다. Reverse Proxy를 사용함으로 인해 얻을 수 있는 장점으로는 다음과 같습니다.
- 분산처리 클라이언트 - 서버 구조에서 사용자가 많아져 서버에 과부하가 올 경우를 위해 부하를 분산할 수 있습니다. Reverse Proxy 구조에서 프록시 서버로 요청이 들어오면 여러대의 서버로 요청을 나누어 전달 후 처리합니다. 자세한 내용은 로드밸런서 챕터에서 학습할 수 있습니다.
- 보안 Forward Proxy와 반대로 Reverse Proxy는 클라이언트에게 서버를 숨길 수 있습니다. 클라이언트 입장에서의 요청보내는 서버가 프록시 서버가 되므로 실제 서버의 IP주소가 노출되지 않습니다.
로드 밸런서
우리는 그동안 웹 개발을 학습하며 클라이언트와 서버가 어떻게 소통하는지에 대해 알게되었습니다. 그런데 만약 서비스에 너무 많은 사용자(클라이언트)가 접속하면 어떻게 될까요? 하나의 서버에 너무 많은, 혹은 너무 잦은 요청을 보낸다면 서버에는 과부하가 오게 됩니다.
과부하로 인해 서버가 원활한 서비스를 제공하지 못하는 경우를 해결하기 위해 크게 서버의 하드웨어를 업그레이드하는 방법과 서버의 갯수를 늘리는 방법, 두가지 선택을 할 수 있습니다.
1. Scale-Up
Scale-Up은 물리적으로 서버의 사양을 높이는 하드웨어적인 방법입니다. 서버의 수를 늘리지 않고 프로그램 구현에 있어 변화가 필요없다는 장점이 있습니다. 하지만 서버의 사양을 높이는데엔 굉장히 높은 비용이 들고, 하드웨어의 업그레이드엔 한계있다는 큰 단점이 있습니다. 또한 사양을 늘린만큼 클라이언트의 요청이 더욱 많아진다면, 서버에 발생하는 부하는 여전히 해결하지 못한 상황이 됩니다.
2. Scale-Out
Scale-Out은 서버의 갯수를 늘려 하나의 서버에 줄 부하를 분산시키는 방법입니다. 많은 요청이 오더라도 여러대의 서버가 나눠서 처리를 하기 때문에 서버의 사양을 높이지 않고도 비교적 저렴한 방법으로 부하를 처리할 수 있습니다.
Scale-Out방법으로 여러대의 서버로 부하를 처리하는 경우, 클라이언트로부터 온 요청을 여러 서버 중 어느 서버에 보내서 처리해야할까요? 요청을 여러 서버에 나눠 처리할 수 있도록 교통정리를 해줄 역할이 필요합니다. 이 역할을 하는게 바로 로드 밸런서이고, 여러 서버에 교통정리를 해주는 기술 혹은 프로그램을 로드 밸런싱이라고 부릅니다.
로드 밸런서의 종류
로드 밸런서는 클라이언트의 요청을 어떤 것을 기준으로 분산시키냐에 따라 네 가지의 종류로 나뉩니다.
오토 스케일링
오토 스케일링 개요
오토 스케일링은 클라우드 컴퓨팅에서 자동으로 서버 리소스를 확장 또는 축소하여 서버 인프라의 유지 관리를 최소화하는 기능입니다. 일반적으로, 서버 부하가 증가하면 오토 스케일링은 자동으로 추가 리소스를 할당하여 서버가 부하를 처리할 수 있도록 합니다. 서버 부하가 감소하면 오토 스케일링은 자동으로 리소스를 줄여 불필요한 리소스 사용을 방지합니다.
오토 스케일링은 클라우드 컴퓨팅의 핵심 기능 중 하나이며, 서버 부하를 신속하게 처리하고 서버의 성능을 유지하는 데 매우 유용합니다.
자동으로 스케일 아웃과 스케일 인을 할 수 있는 방식
스케일 아웃
서버가 부하를 감당할 수 없을 정도로 많은 사용자들이 서비스를 이용하고 있을 때, 서버가 더 많은 리소스를 사용할 수 있도록 하는 것을 '스케일 아웃'이라고 합니다. 이를 통해 사용자들이 서비스를 계속 사용할 수 있도록 서버의 성능을 유지할 수 있습니다. 스케일 아웃은 수동으로 진행할 수도 있지만, 오토 스케일링을 사용하면 자동으로 리소스를 확장 또는 축소할 수 있어 효율적으로 서버 인프라를 관리할 수 있습니다.
스케일 인
스케일 인은 서버 부하가 감소할 때 사용되며, 리소스 사용량을 줄여 불필요한 리소스 사용을 방지합니다. 이를 통해 서버 인프라의 비용을 절감할 수 있습니다. 예를 들어, 서버 부하가 적을 때는 더 이상 필요하지 않은 서버를 종료하여 비용을 절감할 수 있습니다. 스케일 인은 수동으로 진행할 수도 있지만, 오토 스케일링을 사용하면 자동으로 리소스를 확장 또는 축소할 수 있어 효율적으로 서버 인프라를 관리할 수 있습니다.
오토 스케일링 구성 요소
스케일링 그룹
오토 스케일링 그룹은 서버 인스턴스의 집합입니다. 이 그룹 안의 인스턴스들은 동일한 크기의 이미지를 사용하며, 동일한 네트워크 구성과 보안 그룹 구성을 가지고 있습니다. 또한, 오토 스케일링 그룹 안의 인스턴스들은 동일한 자동 스케일링 정책을 공유합니다.
자동 스케일링 정책
자동 스케일링 정책은 리소스를 자동으로 확장하거나 축소하는 데 사용되는 규칙입니다. 이 규칙은 다음과 같은 요소로 구성됩니다.
- 조건: 자동 스케일링이 발생하는 조건입니다. 예를 들어, CPU 사용률이 80% 이상인 경우 자동 스케일링이 발생합니다.
- 동작: 자동 스케일링이 발생했을 때 취해지는 동작입니다. 예를 들어, 인스턴스를 2개 추가하는 것입니다.
로드 밸런서
로드 밸런서는 서버 인스턴스 간의 트래픽을 분산시키는 데 사용됩니다. 로드 밸런서는 클라이언트의 요청을 여러 서버 인스턴스로 분배하여 부하를 분산시킵니다. 이를 통해 애플리케이션의 가용성을 높일 수 있습니다.
CloudWatch
CloudWatch는 AWS에서 제공하는 모니터링 서비스입니다. CloudWatch를 사용하여 리소스 사용률을 모니터링하고, 자동 스케일링 정책의 조건으로 사용할 수 있습니다.
오토 스케일링 동작 원리와 이점
다음과 같은 시나리오를 가정해봅니다.
- EC2 인스턴스 클러스터가 있고 10개의 인스턴스가 필요한 상황입니다.
- 구성에 문제가 발생했습니다. (인스턴스와 같은 서버나 동작하는 소프트웨어의 문제)
- Cloud Watch에서 문제를 감지하고 오토스케일링됩니다.
- 오토 스케일링 조건 설정값(시작 구성이라고 얘기합니다)에 맞는 인스턴스를 생성하고 오토 스케일링 클러스터에 넣습니다.
이처럼 자동으로 리소스가 관리되도록 하는것이 수동으로 리소스를 관리할때 보다 뚜렷한 이점이 있습니다. 오토 스케일링은 다음과 같은 이점을 제공합니다.
- 자동화된 리소스 관리: 서버 부하가 증가하면 자동으로 리소스를 제공하여 애플리케이션 성능을 유지하고, 서버 부하가 감소하면 자동으로 리소스를 해제하여 비용을 절감합니다.
- 높은 가용성: 서버 부하가 증가하더라도 자동으로 리소스를 확장하기 때문에, 서버가 다운되는 것을 방지하고 애플리케이션이 항상 사용 가능하도록 합니다.
- 비용 절감: 필요한 리소스만 사용하여 비용을 절감할 수 있습니다.
- 유연성: 서버 인프라를 즉시 확장하거나 축소하여 더욱 빠르게 대응할 수 있습니다.