Scalable WEB Application

Nurrung·2023년 2월 26일
0
post-thumbnail

Web-Demo
https://github.com/qyjohn/web-demo/wiki

아래의 AWS서비스를 이용하여 간단한 Scalable 웹을 만들어 보려고 한다. 해당 포스트를 통해 우리가 사용하는 서비스들이 어떻게 Scalable한 형태를 유지하는지 이해하며, 자주 사용되는 AWS 서비스들도 같이 살펴보려고 한다.

사용되는 AWS 서비스

======
Elastic Computer Cloud (EC2),
Application Load Balancer (ALB),
Relational Database Service (RDS),
ElastiCache,
Simple Storage Service (S3),
Identity and Access Management (IAM),
CloudWatch,
AutoScaling


Configuration

Demo를 진행하기전 테스트 환경을 아래와 같이 구성했다.

  • VPC
    1)Scalable-VPC 10.0.0.0/16 생성

  • Subnet
    1)ap-northeast-2a - Public1생성
    2)ap-northeast-2b - Public2 생성

  • Route tables - Scalable-rtb-public
    1) 라우트 테이블에 Intetnet gateways 추가 후 서브넷에 연결

    서울 리전 (ap-northeast-2)에 서비스를 운영할 VPC(가상 네트워크)를 생성하였다. 해당 VPC내에서 서비스를 운용할 2개의 서브넷(IP주소의 범위)을 만들어 준다. 인터넷 연결이 필요하기 때문에 해당 서브넷에 대한 라우트테이블에 인터넷 게이트웨이를 추가해준다.

======

Step 0 - Single Server

Step 0 에서는 한 개의 인스턴스를 생성한 뒤 해당 인스턴스에 Web Service + DB를 한번에 설치하여 서버 하나를 이용해 서비스 운영에 필요한 모든 요소를 설치하여 서비스를 배포하는 방법을 알아본다.

과정

  1. 인스턴스 생성하기
  • ap-northeast-2a - public 1 에 인스턴스 생성
  • Security Group에 SSH 및 Http 접속을 위한 20번 80번 포트 허용
  1. Mysql DB 설치 및 secure_installation으로 보안 설정 진행
$ sudo apt-get update
$ sudo apt-get install mysql-server
$ sudo mysql_secure_installation

(* mysql_secure_installation
https://mariadb.com/kb/en/mysql_secure_installation/)

  1. apache 및 php 설치하기
$ sudo apt-get install awscli apache2 
$ sudo apt-get install php libapache2-mod-php php-mysql php-curl php-xml php-memcached php-mbstring
  1. Git 에서 "web-demo"소스코드 clone으로 가져오기
  • PHP를 설치하면 /var/www/html 경로에 기본으로 index.html 파일이 생성된다.
$ sudo apt-get install git
$ cd /var
$ sudo chown -R ubuntu:ubuntu www
$ cd /var/www/html
$ git clone https://github.com/qyjohn/web-demo
$ cd web-demo

4-1. 아파치가 "uploads" 폴더에 접근 할 수 있게 권한을 아래와 같이 바꾸어준다.

$ sudo chown -R www-data:www-data uploads

4-2. 설치한 Mysql에 사용할 database 만들기

$ sudo mysql
mysql> CREATE DATABASE web_demo;
mysql> CREATE USER 'user.name'@'localhost' IDENTIFIED BY 'pass.word';
mysql> GRANT ALL PRIVILEGES ON web_demo.* TO 'user.name'@'localhost';
mysql> quit

4-3. Git을 이용해 가져온 "web-demo"의 소스코드에 web_demo.sql을 위에서 만든 web_demo db로 가져온다.

$ cd /var/www/html/web-demo
$ mysql -u test1 -p web_demo < web_demo.sql

4-4. config.php 파일에서 아래의 부분 올바르게 설정해주기

$ nano config.php

username / password에 앞에서 본인이 설정한대로 입력

// Database connection parameters
$db_hostname = "localhost";
$db_database = "web_demo";
$db_username = "user.name";
$db_password = "pass.word";

4-5. Single Server 접속

  • 접속
    http://public-ip-address-of-your-ec2-instance/web-demo/index.php

  • 서버의 구성 형태

    위와 같은 "서버의 구성 형태"에서는 많은 양의 트래픽 & 데이터 처리하기 적합하지 않다. 싱글 서버에서 서비스 동작에 필요한 모든 작업을 수행하기 때문이다. 또한 장애가 발생한다면 서비스 전체에 영향을 줄 수 있다. 이러한 부분을 보완하기 위해 다음 단계에서는 여러개의 인스턴스 및 구성 요소들을 분리하여 운영하는 방법을 알아본다.

====

Step 01 - Load Balanced Solution

이 단계에서는 LEVEL 0에서 만든 기본 단계의 서버를 확장하여 여러 서버에 배포할 예정입니다. 또한 EFS(NFS service)를 사용하여 여러개의 서버 노드끼리 공유 파일시스템을 형성할 것입니다.

과정

1. AWS EFS 생성하기

1-1. AWS EFS Console 접속
https://ap-northeast-2.console.aws.amazon.com/efs/home?region=ap-northeast-2#/get-started

2. EFS 생성

  • 인스턴스와 같은 VPC에 생성
  • DNS가 생성된다.

2-1. 인스턴스에서 생성한 EFS 마운트 해주기

$ sudo apt-get update
$ sudo apt-get install nfs-common
$ sudo mkdir /efs 
$ sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 dns-name-of-your-efs-file-system:/ /efs
$ sudo chown -R ubuntu:ubuntu /efs

2-2. 마운트 확인 및 파일시스템 테이블에 마운트포인트 추가

  • 마운트확인
$ df -h
$ mount

  • /etc/fstab
$ dns-name-of-your-efs-file-system:/  /efs    nfs    auto,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2    0       0

2-3. EFS에 마운트한 디렉터리에 "web-deme" 소스코드 저장하기

$ cd /efs
$ git clone https://github.com/qyjohn/web-demo
$ cd web-demo
$ sudo chown -R www-data:www-data uploads
$ cd /var/www/html
$ sudo ln -s /efs/web-demo web-demo

3. AWS RDS(MySQL) 생성 후 연결하기

3-1. AWS RDS Console에 접속 이후 MySql Database 생성

  • 인스턴스와 동일한 VPC에 생성
  • Mysql 디폴트 포트인 3306에 대한 인바운드 허용룰을 인스턴스의 SG에 설정

3-2. 인스턴스에서 생성한 Mysql에 접속 후 데이터베이스 만들기

$ mysql -h dns-name-of-rds-instance -u admin -p
mysql> CREATE DATABASE web_demo;
mysql> CREATE USER 'user.name'@'%' IDENTIFIED BY 'pass.word';
mysql> GRANT ALL PRIVILEGES ON web_demo.* TO 'user.name'@'%';
mysql> quit

3-3. 다운 받은 web_demo.sql을 web_demo DB로 import 해준다.

$ cd /var/www/html/web-demo
$ mysql -h dns-name-of-rds-instance -u username -p web_demo < web_demo.sql

3-4. /var/www/html/web-demo config.php에서 새로운 " new database server hostname, username, password, and database name" 에 대한 설정을 변경해준다.

4. AWS ElastiCache를 이용하여 Cache 서비스 만들기

4-1. AWS ElastiCache Console 접속 이후 Redis or Memcached Cluster 사용해서 cache node 만들어 주기

  • Cluster Mode Enabled
  • 위에서 생성한 리소스들이 있는 같은 VPC
  • Cluster Endpoint 확인

[+] Amazon ElastiCache 설명서
https://docs.aws.amazon.com/ko_kr/elasticache/index.html

4-2. PHP와 redis를 연동하기 위한 php-redis module 설치 및 apache2의 php.ini 파일 설정

  • Install php-redis
$ sudo apt-get install php-redis

[+] Reference
https://github.com/phpredis/phpredis

  • Configure the /etc/php/x.x/apache2/php.ini
session.save_handler = rediscluster
session.save_path = "configuration-endpoint-of-the-elasticache-redis-cluster:6379"

4-3. 웹 서비스에 정상적으로 접속 가능한지 확인 후, 해당 인스턴스를 이용하여 AMI 생성하기.

  • 접속가능 확인

  • AMI 생성 하기
  • EC2 Management Console 접속
    • Instance 선택
    • Action -> Image and tempaltes -> Create Image

[+] 인스턴스 및 AMI - https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/ec2-instances-and-amis.html

  • Images -> AMI로 이동

    • AMI의 상태가 available 인지 확인
    • 해당 AMI로 인스턴스 생성 후 동일하게 웹사이트가 접속 가능한지 확인
      - 동일한 VPC 설정
      - 동일한 SG 설정
  • 접속확인

5. ALB 생성하기

5-1. ALB를 통한 로드밸런싱 구성

  • Target group 생성하기
    • HTTP 프로토콜을 사용하는 타겟그룹 생성 후 이전 단계에서 생성한 인스턴스 2개를 추가
  • Application Load Balancer 생성하기
    • ALB 선택
    • VPC 선택
    • SG 구성 / SG에서 인바운드는 올 트래픽 / 아웃바운드는 Instance의 SG을 걸어준다.
    • 생성해놓은 Target group을 listener로 설정
  • ALB가 생성되면 아래의 주소로 들어가 새로고침을 시도

====

Step 02 - S3 연결하기

트래픽이 제한된 웹 서비스에서는 EFS 를 통한 공유 파일 시스템을 사용하면 좋지만 사이트에 트래픽이 증가하거나 불규칙 할 경우 다른 형태의 스토리지를 사용 하는 것이 좋다. AutoScail을 통해 트래픽을 여러개의 서버로 분산할 수 있지만 공유 파일 시스템을 통해 같은 스토리지를 사용하는 경우 성능에 제한이 걸릴 수 있다.

과정

1. S3 생성 및 config.php 편집

  • S3 생성
    • S3 console을 에서 생성 및 config.php에 s3 폴더에 대한 액세스 정보 설정
$storage_option = "s3";	// hd or s3
$s3_region  = "us-east-2";
$s3_bucket  = "bucket_name";
$s3_prefix  = "uploads";

====

Step 03 - AutoScaling 설정

수동으로 $latency 을 조절하여 웹 서비스에 과중한 워크로드가 걸린 상황을 만들 수 있다. 아래의 방법으로 진행해보자

과정

1. 시작 템플릿 생성 및 Autoscaling 그룹 생성

  • EC2 콘솔에서 레벨 2에서 생성한 AMI와 IAM 역할을 사용하여 시작 템플릿을 생성합니다.

    • Create launch configuration

  • 위 단계에서 만든 시작 템플릿을 사용하여 AutoScaling 그룹을 생성합니다.AutoScaling 그룹이 ALB 대상 그룹으로부터 트래픽을 수신하는지 확인하십시오.

  • Autoscaling 적용 후 타겟 그룹에서 관리되는 인스턴스의 수가 늘어난 것을 확인 가능하다. (최소값 1 최대값4 로 설정)
  • 평균 지연 시간 (응답 시간) 이 최소 1분 동안 1000ms 이상인 경우 새 CloudWatch 경보를 생성하십시오.

2. Latency를 설정하여 AutoScaling 실행

  • Config.php 에서 $latency 조절
$latency = 0; -> $latency = 10;
  • CloudWatch 에서 생성 해놓은 알람의 그래프를 보면 latency를 10 sec으로 설정해놓은 뒤 "TargetResponseTime"이에 대한 지표값이 변화한 것을 확인 가능
  • 이후 TargetGroup을 확인해보면 새로운 인스턴스 3개가 더 추가된 것을 확인할 수 있다.
    (성공적으로 AutoScaling이 되었다.)

  • 또한 AWS SNS를 통해 CloudWatch Alarm이 특정 메트릭에 대한 알람이 발생하면 아래와 같이 메일로 알림을 받을 수도 있다.


위의 작업을 통해, 간단한 웹 어플리케이션을 여러 AWS 서비스들과 어떻게 엮어 Scalable 하게 구성할 수 있는지에 대해 살펴보았다. 이렇듯 서비스하려는 어플리케이션의 특성에 맞춰 서버를 유동적으로 구성한다는 것은 Cloud Computing이 가진 강력한 장점이다. 하지만 이러한 장점을 실제 서비스에 적용하는 과정은 CSP가 제공하는 서비스에 대한 기본적인 이해도를 필요로 한다.

이번 포스팅으로 맨 앞에서 언급한 여러 서비스들을 간단히 사용해보고, 사용 목적 및 적용 방법등을 살펴 볼 수 있는 좋은 기회가 되었으면 한다.

profile
Good to see you guys

0개의 댓글