Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

마로의 개발일지

Java에서 Aws AppConfig 사용하기 본문

알게된 것

Java에서 Aws AppConfig 사용하기

maro0201 2023. 4. 15. 15:06

 편의점 택배사들의 점검이나 에러 시 배송신청을 막기 위해 배송 신청 여부를 Flag 값으로 설정한 뒤, AppConfig를 통해 조절하도록 하는 작업을 진행했었다. api 호출 시 AppConfig를 직접 조회에서 쓰도록 하기 위해 Java Application에 직접 AppConfig를 조회하는 로직을 추가했었다. 이전에 아무도 해본 적이 없어 공식문서를 보면서 진행했고 그 과정을 기록했다.

 

공식 문서 읽어보기

Step 6: Retrieving the configuration - AWS AppConfig 해당 문서를 살펴보면

Your application retrieves configuration data by first establishing a configuration session using the StartConfigurationSession API action. Your session's client then makes periodic calls to GetLatestConfiguration to check for and retrieve the latest data available.

라고 되어 있다. 구성 세션을 시작하고 주기적으로 최신 구성을 조회해서 최신 데이터를 읽어 올 수 있다고 한다. 방법은 알았으니 해당 로직을 작성하기 전에 먼저 권한부터 추가해주자.

 

Role에 AppConfig 권한 추가하기

 AppConfig를 조회(호출)하는 Java Application의 IAM role에 해당 권한 두 개를 추가하면 호출할 수 있다. 의미 그대로 세션을 시작하고 데이터를 조회하는 권한을 추가한다.

  • appconfig:StartConfigurationSession
  • appconfig:GetConfiguration

Maven 설정에 dependency 추가하기

 위에 있는 StartConfigurationSession 페이지를 살펴보면 하단에 AWS SDK for Java V2 링크가 존재한다. 링크로 들어가 해당 메서드가 있는 package를 확인하면 software.amazon.awssdk.services.appconfigdata 임을 알 수 있다. 그렇다면 우리의 프로젝트에 해당 package를 추가한 뒤 사용하면 될 것이다. Gradle이 아닌 Maven을 사용하는 프로젝트였기에 pom.xml에 dependency 추가해 줬다.(version은 당시 기준 가장 최신 버전을 사용했다.)

	<dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>appconfigdata</artifactId>
            <version>2.18.24</version>
        </dependency>

호출하기 전 각 메서드 분석하기

StartConfigurationSession

 StartConfigurationSession 페이지를 보면 HTTP 호출 스펙과 응답 스펙이 나와 있다. 아래의 응답 스펙에서 우리는 해당 api로 post 요청을 보내면 InitialConfigurationToken을 발급해 주는 것을 알 수 있다. 

Request Syntax

POST /configurationsessions HTTP/1.1
Content-type: application/json

{
   "ApplicationIdentifier": "string",
   "ConfigurationProfileIdentifier": "string",
   "EnvironmentIdentifier": "string",
   "RequiredMinimumPollIntervalInSeconds": number
}

Response Syntax

HTTP/1.1 201
Content-type: application/json

{
   "InitialConfigurationToken": "string"
}

 


GetLatestConfiguration

 지금은 이게 왜 필요한지 모르겠으니 추가적으로 GetLatestConfiguration 페이지를 살펴보자. 동일하게 HTTP 호출 스펙과 응답 스펙이 나와 있는데 요청에 query string parameter로 token 값을 받는다. 그리고 응답 값으로 다음 호출 시 필요한 토큰값과 호출 주기 그리고 우리가 원하는 AppConfig 구성 정보를 전달해 주는 것 같다.

Request Syntax

GET /configuration?configuration_token=ConfigurationToken HTTP/1.1

Response Syntax

HTTP/1.1 200
Next-Poll-Configuration-Token: NextPollConfigurationToken
Next-Poll-Interval-In-Seconds: NextPollIntervalInSeconds
Content-Type: ContentType

Configuration 구성 정보

 

AWS AppConfig 구성 정보 호출 요약

  1. 필요한 대상의 Application, Environment, ConfigurationProfile와
    갱신 주기(RequiredMinimumPollIntervalInSeconds)를 전달하여 StartConfigurationSession 호출
  2. StartConfigurationSession은 initial token을 응답
  3. initial token으로 GetLatestConfiguration을 호출
  4. GetLatestConfiguration은 다음을 응답
    • 이후 호출에 필요한 토큰(NextPollConfigurationToken)
    • 이후 갱신 주기(NextPollIntervalInSeconds)
    • 구성(Configuration)
  5. 응답받은 Configuration으로 필요한 항목 처리
  6. 이후 추가적으로 최신 버전의 구성이 필요하다면 NextPollConfigurationToken으로 GetLatestConfiguration 호출

AWS의 의도는 주기적으로 AppConfig를 호출해서 최신 버전을 갱신하도록 설정해서 사용하는 것을 원하는 것 같다. 하지만 항상 갱신할 필요는 없는 데이터였고 호출할 때마다 확인하고 싶어서 따로 주기를 설정해서 다시 호출하도록 하지는 않았다.

 

Java Application에 적용

 위의 요약된 정보를 토대로 java 코드를 작성하면 다음과 같다. 실행하는 메서드들은 해당 응답 클래스의 정보를 통해 파악해서 사용했다.

  1. AppConfigDataClient의 create() 메서드를 통해 DefaultAppConfigDataClientBuilder로 AppConfigDataClient를 생성한다.
  2. 생성된 AppConfigDataClient에서 StartConfigurationSession을 요청 스펙에 맞게 호출한다.
  3. 응답값으로 받은 StartConfigurationSessionResponse 객체에서 initialConfigurationToken() 메서드를 통해 Token을 받아온다.
  4. AppConfigDataClient에서 받아온 Token값으로 getLatestConfiguration을 호출한다.
  5. 응답값으로 받은 GetLatestConfigurationResponse의 configuration() 메서드를 통해 SdkBytes 형태의 구성 정보를 받아온 뒤 String으로 변환하여 return 한다.
public class AppConfigService {

    public String getLatestAppConfigProfile(String applicationName, String env, String profileName) {
        // appConfigDataClient 생성(try-with-resource를 통해 자동으로 연결 종료)
        try (AppConfigDataClient appConfigDataClient = AppConfigDataClient.create()){
            // 구성 정보를 입력한 뒤 세션 요청
            StartConfigurationSessionResponse startConfigurationSessionResponse = appConfigDataClient.startConfigurationSession(builder ->
                builder.applicationIdentifier(applicationName)
                    .environmentIdentifier(env)
                    .configurationProfileIdentifier(profileName)
                    .build()
            );
            // 세션 시작
            String initialConfigurationToken = startConfigurationSessionResponse.initialConfigurationToken();
            // 세션 응답으로 받은 토큰으로 최신 Config 요청
            GetLatestConfigurationResponse latestConfiguration = appConfigDataClient.getLatestConfiguration(
                builder -> builder.configurationToken(initialConfigurationToken));
            // 응답 받은 데이터 String 형태로 반환
            SdkBytes sdkBytes = latestConfiguration.configuration();
            return sdkBytes.asUtf8String();
        } catch (Exception e) {
            throw new AwsServiceException(AWS_APP_CONFIG_ERROR, applicationName, profileName ,e.getMessage());
        }
    }
}

 

결과

 local 환경에서 호출할 때에는 속도가 빨랐는데 테스트 환경에서의 속도가 정상 상태일 땐 2초 실패 상태일 땐 6초가 걸려 해당 방법은 사용할 수 없다고 판단했다. 그래서 AppConfig가 배포되면 자동으로 redis cache를 업데이트하도록 하는 Lambda를 생성하고 Extension을 추가해서 Flag 값을 설정하도록 하였다. 해당 방법은 다음 포스팅에 작성할 예정이다.

Comments