1. Project 서버 구성

[1] AutoScaling 환경에서 API call 에 관한 고민

 프로젝트의 구성은 Gradle 기반 멀티 모듈로 구성되어 있었다. 이전 프로젝트 인프라와 다른 점은 BFF 패턴(Backend For Frontend) 으로 구성하고 있어 conference, analysis server 에 api call 을 해야 한다는 점이 가장 큰 차이였다. 프로젝트 환경을 구성하면서 가장 고민되었던 점은 Scale out 환경에서 어떻게 api call 을 할 것인가? 이다.

 API call 을 하는 가장 간단한 방법은 IP, PORT 에 관한 서버 스펙을 기반으로 요청하는 것이다. 하지만 Scale out 환경에서는 상세한 서버 스펙을 아는 것은 한계가 있다. Scale out 되는 서버 스펙을 추가하고, 반대로 Sclae in 하는 서버 스펙을 제거하는 작업을 WAS 가 담당하는데 한계가 존재한다.  또한 부하가 낮은 서버을 WAS 가 선택하는 과정과 같이 트래픽에 유연한 Scale out 환경을 위해 선택한 방법은 application load balancer 이다.

 

 

[2] AWS Load balancer 를 기반한 아키텍처 구성

 AWS application load balancer 은 규칙에 알맞는 요청을 target group 을 통해 요청을 라우팅한다. header, path, http method 정보들로 라우팅 규칙을 설정할 수 있다. 또한 AWS 는 CIDR 기반의 source IP 도 조건을 제공한다. application load balancer 는 public, private 관계없이 DNS 를 제공한다. DNS 이름을 통해 load balancer 에 요청하면 설정된 내용을 토대로 라우팅, 부하 분산을 지원한다.

 구성한 architecture 는 아래와 같다. load balancer 는 2개를 구성했고 인터넷 경계와 내부 요청을 처리하는 application load balancer 를 구성했다. HTTPS 요청은 url path 를 이용한 필터링하여 해당 target group 에게 라우팅 하도록 구성했다.

aws architecture
load balancer 에서 제공하는 DNS 이름

 

 

2. 한번 만들어 보자.

[1] launch template 구성하기

1. 애플리케이션 및 OS 이미지 : amazon linux

2. 인스턴스 유형 : t2.micro

3. 보완 그룹(inbound)

  • TCP 8080 대역 : load balancer security group 설정

 

4. 네트워크 설정(고급 네트워크 구성)

 

5. 고급 세부 정보

  • IAM 역할 > S3 FullAccess + CloudWatchAgentServerPolicy

 

6. 사용자 데이터 (부팅 후, shell 명령어 추가 설정)

#!/bin/bash

su ec2-user

sudo yum install -y amazon-cloudwatch-agent
sudo aws s3 cp s3://[s3-bucket-이름]/config.json /opt/aws/amazon-cloudwatch-agent/bin/config.json
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json

sudo yum install -y java-17-amazon-corretto
aws s3 cp s3://[s3-bucket-이름]/member-0.0.1-SNAPSHOT.jar /home/ec2-user
nohup java -jar -Dspring.profiles.active=prod /home/ec2-user/member-0.0.1-SNAPSHOT.jar 1> logs.out 2>&1  &

 

 

[2] load balancer 생성

1. 로드 밸런서 유형 비교 및 선택

  • application load balancer

2. 체계

  • 인터넷 경계 (conference, analysis 는 생성 시에는 내부로 설정)

3. 네트워크 매핑

  • VPC 설정
  • 요청 할당항 subnet 구성

 

4. 보안 그룹 (inbound)

  • [public load balancer] TCP 443 (HTTPS) : 0.0.0.0/0 (전체 대역)
  • [private load balancer] TCP 8080 : private load balancer 가 포함된 보안 그룹 (전체 대역)

5. 리스너 및 라우팅

  • protocol : HTTPS / port 443 / 대상 그룹 선택

리스너 및 라우팅 설정

 

  • 로드 밸런싱 생성 이후 path routing 설정

로드 밸런서 생성 이후 해당 위치 접속
요청 필터링할 path 설정

 

🚨 [trouble shooting] /api/members/* vs /api/members* 차이??
(1) /api/members/* : /api/members mapping (X)
(2) /api/members* : /api/members mapping (O)

 

 

6. TLS 인증서 추가

 

[3] AutoScalingGroup 생성

1. 시작 템플릿 선택

  • 시작 템플릿 구성
  • 버전 : Latest

 

 

2. 네트워크 설정

  • VPC, subnet 설정

 

3. load balancer 설정

  • 기존 로드 밸런서 설정
  • 라우팅할 대상 그룹으로 추가

 

4. 그룹 크기 및 크기 조정 구성

 

 

3. TroubleShooting

front-group 을 추가하는 과정에서의 502 error 가 발생한 이슈
  • 서버가 게이트웨이나 프록시 서버 역할을 하면서 업스트림 서버로부터 유효하지 않은 응답을 받았다는 것을 의미
  • 원인 : 대상 그룹을 변경하면서 upstream server 로 부터 응답을 받지 못한 이슈 : 서버 종료로 인한 이슈
    • 404 vs 502 vs 504
      • 404(Not Found) : 만약 load balancer 의 mapping url 이 존재하지 않을 경우 404 반환
      • 502(bad gateway) : 만약 서버가 정상 운영 중이지만 필터링 조건에 모두 통과하지 못했을 경우 반환
      • 504(Gateway Time-out) : 보안 그룹 설정 오류로 인한 이슈로 주로 추정
/api/members/* vs /api/members* 차이??
  • /api/members/* : /api/members mapping (X)
  • /api/members* : /api/members mapping (O)

 

4.  현재 구조에서 추가 개선 사항

  1. 빌드 프로세스 개선
    • AS-IS : 인스턴스 생성 시, 빌드 파일 다운로드
    • 한계 : scaling out 환경에서 코드 수정이 있을 경우, 수작업으로 각각 빌드해야 하므로 이를 개선하기 위한 배포 도입
    • TO-BE : 배포 자동화 도구 도입 (code deploy, jenkins)
  2. cloudwatch 적용
  3. /api/analysis response time 검토 및 개선
    1. AS-IS : 코드를 취미로 하는 설문 조사 API response time : 600ms
    2. TO-BE : 200ms 이하로 개선

 

Reference