본문 바로가기

AWS

AWS Elastic Beanstalk + Java SE환경 API 서버 구축기 (3)

AWS Elastic Beanstalk에 Java SE 플랫폼 기반으로 API 서버를 구축한 기록입니다

(2022.08.13 -Xms 관련 명령서 순서 변경을 확인해서 해당글에서 수정했습니다.)

 

아래와 같이 총 3가지 상황에 따른 구축 방법과 주의할 점에 대한 글로 나누어 작성할 예정입니다.

1편 실행 가능한 단일 JAR

2편 Procfile 기반

3편 Procfile 기반 다수 JAR + Arguments + ebextentions NGINX Reverse Proxy 설정

 

 

이번 포스팅에서 다룰 내용은

여러 JAR를 하나의 인스턴스에 배포해서 내부에서 location 기반으로 proxy 하는 방법을 소개할까 합니다.

 

이전 글에서 Procfile로 foo.jar를 실행하는 방법을 말씀드렸는데

Beanstalk에서 실행 할 JAR를 명시하는 Procfile

 

이번 글에서는 foo.jar와 bar.jar 2개를 실행해 보겠습니다.

 

먼저 Procfile입니다.

이전 글의 foo.jar에서 bar.jar를 추가해서 적어줍니다

 

Procfile

foo: java -Xms256m -jar foo.jar
bar: java -jar bar.jar

 

그리고 실행할 foo.jar와 bar.jar를 Procfile과 함께 압축합니다.

foo.jar, bar.jar와 Procfile을 압축

압축한 파일을 Elastic Beanstalk에 배포하면 

 

2편에서 말씀드린 것 과 마찬가지로 /var/app/current에 파일들이 위치하고

foo.jar와 bar.jar가 Procfile에 명시한 대로 실행 중인 것을 확인할 수 있습니다.

하지만...

 

SERVER_PORT 설정

 

1편에서 소개드린 대로 설정을 하셨다면 SERVER_PORT가 5000으로 고정되어 있어서 foo.jar와 bar.jar 모두 5000번 포트로 실행하게 됩니다.

 

foo.jar와 bar.jar 모두 동일하게 5000번으로 설정된다.

당연히 둘 중 하나는 중복 포트로 인해 실행되지 않기 때문에 이를 해결하기 위해서는 환경 속성에 있는 SERVER_PORT설정을 삭제하고 Procfile에 각각의 포트를 명시해 주어야 합니다.

 

위에 있는 Procfile을 수정해 보겠습니다.

 

Procfile

foo: java -Dserver.port=8080 -Xms256m -jar foo.jar
bar: java -Dserver.port=8081 -jar bar.jar

foo.jar와 bar.jar를 실행하는 명령어에 -Dserver.port를 명시해서 각각 8080과 8081로 실행해 보겠습니다.

 

수정한 Procfile, foo.jar와 bar.jar를 다시 zip으로 묶어 Elastic Beanstalk에 배포하게 되면

 

 

/var/log/foo-1.log의 로그

 

/var/log/bar-1.log의 로그

 

foo는 8080으로 bar는 8081 내부에서 실행된 것을 확인할 수 있습니다.

 

하지만 여기서 끝이 아니라 외부의 beanstalk url로 호출하려면 프록시 설정도 같이 해줘야 내부의 foo와 bar에 request가 정상적으로 전달되게 됩니다.

 

아마존 document에서는 

https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/java-se-nginx.html

 

다음과 같이 2가지 방법으로 proxy를 구성할 수 있게 지원해 주는데

1. 기본으로 설정된 conf에 확장

myconf.conf를 기본 설정된 conf에 추가한다.

이 방법은 1편에서 설명드렸던 5000번을 기본으로 프록시 하는 설정에 추가적인 설정을 conf파일로 정의해서 하는 방식입니다.

 

2. nginx 설정 재정의

nginx.conf를 전체 재정의 한다

보이는 바와 같이 nginx에 있는 전체 conf를 완전 재정의 하는 방법입니다.

 

저는 1번으로 location만 foo와 bar로 proxy 해주려고 했으나 동작하지 않아서 2번 완전 재정의를 선택했습니다.

 

완전 재정의 한 nginx.conf파일

# Elastic Beanstalk Nginx Configuration File

user                    nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    32725;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    include       conf.d/*.conf;

    map $http_upgrade $connection_upgrade {
        default     "upgrade";
    }

    server {
        listen        80 default_server;
        access_log    /var/log/nginx/access.log main;

      location /foo {
          proxy_pass          http://127.0.0.1:8080;
          proxy_http_version  1.1;

          proxy_set_header    Connection          $connection_upgrade;
          proxy_set_header    Upgrade             $http_upgrade;
          proxy_set_header    Host                $host;
          proxy_set_header    X-Real-IP           $remote_addr;
          proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
      }
	  
      location /bar {
          proxy_pass          http://127.0.0.1:8081;
          proxy_http_version  1.1;

          proxy_set_header    Connection          $connection_upgrade;
          proxy_set_header    Upgrade             $http_upgrade;
          proxy_set_header    Host                $host;
          proxy_set_header    X-Real-IP           $remote_addr;
          proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
      }

        client_header_timeout 60;
        client_body_timeout   60;
        keepalive_timeout     60;
        gzip                  off;
        gzip_comp_level       4;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        # Include the Elastic Beanstalk generated locations
        include conf.d/elasticbeanstalk/healthd.conf;
    }
}

1편에서 기본 재정의 된 nginx.conf파일과 차이점은

 

1. location /foo {...} 추가

2. location /bar {...} 추가

3. include conf.d/elasticbeanstalk/*.conf; > include conf.d/elasticbeanstalk/healthd.conf;

 

입니다.

 

첫 번째와 두 번째 수정사항은 포트를 8080과 8081로 설정해 주는 것인데 마지막 세 번째는 기본 location / 로 되어있는 설정을 포함하지 않고 health 체크하는 conf만 포함시켰습니다.

 

해방 부분은 적절히 상황에 맞게 재정의 하시면 될 것 같습니다.

이렇게 새로 정의한 nginx.conf파일을 .ebextentions/nginx 경로에 위치시켜 기존 압축 파일에 추가해주시면 됩니다.

 

최종적인 압축파일은 다음과 같습니다.

압축파일 최상단에는

1. .ebextentions폴더

2. bar.jar

3. foo.jar

4. Procfile

 

그리고. ebextentions/nginx에 재정의한 nginx.conf를 위치시켜 zip으로 압축하시면 됩니다.

 

마지막으로 압축한 파일을 Elastic Beanstalk에 배포하시면 Beanstalk의 url에서 설정한 foo와 bar에 request가 전달되는 것을 확인할 수 있습니다.

 

 

확인과 이해를 위해서 직접 Beanstalk에 있는 인스턴스에 들어가 파일과 로그를 중간중간 확인해 봤는데 사실 사용법만 잘 아신다면 확인하지 않고 사용하는 게 Elastic Beanstalk입니다.

 

실제 배포해보면서 중간중간 삽질했던 경험을 요약해서 예제로 알려드렸는데 부디 작게나마 도움이 되시길 바랍니다.