ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 6. 외부설정과 프로필1
    Spring-Boot/스프링부트 - 핵심 원리와 활용 2023. 5. 24. 15:10

    1. 프로젝트 설정

    2. 외부 설정이란?

    - 각각의 환경에 맞는 `개발app.jar` , `운영app.jar` 가 만들어지므로 해당 파일들을 각 환경별로 배포하면 된다.

    - 하지만 이것은 좋은 방법이 아니다.

        ㆍ환경에 따라서 빌드를 여러번 해야 한다.

        ㆍ개발 버전과 운영 버전의 빌드 결과물이 다르다.

        ㆍ따라서 개발환경에서 검증이 되더라도 운영환경에서 다른 빌드 결과를 사용하기 때문에 예상치 못한 문제가

            발생할 수 있다.

        ㆍ개발용 빌드가 끝나고 검증한 다음에 운영용 빌드를 해야 하는데 그 사이에 누군가 다른 코드를 변경할 수 있다.

        ㆍ한마디로 진짜 같은 소스코드에서 나온 결과물인지 검증하기 어렵다

        ㆍ각 환경에 맞추어 최종 빌드가 되어 나온 빌드 결과물은 다른 환경에서 사용할 수 없어서 유연성이 떨어진다.

        ㆍ향후 다른 환경이 필요하면 그곳에 맞도록 또 빌드해야 한다.

     

    - 배포 환경과 무관하게 하나의 빌드 결과물을 만든다. 여기서는 `app.jar`를 빌드한다. 이 안에는 설정값을 두지 않는다.

    - 설정값은 실행 시점에 각 환경에 따라 외부에서 주입한다.

     

    - 이렇게 하면 빌드도 한번만 하면 되고, 개발 버전과 운영 버전의 빌드 결과물이 같기 때문에 개발환경에서 검증되면 운영환경에서도 믿고 사용할 수 있다.

    - 그리고 이후에 새로운 환경이 추가되어도 별도의 빌드 과정 없이 기존 `app.jar`를 사용해서 손쉽게 새로운  환경을 추가할 수 있다.

     

    *유지보수하기 좋은 애플리케이션 개발의 가장 기본 원칙은 변하는 것과 변하지 않는 것을 분리하는 것이다.*

    - 유지보수하기 좋은 애플리케이션을 개발하는 단순하면서도 중요한 원칙은 *변하는 것과 변하지 않는 것을 분리* 하는 것이다.

    - 각 환경에 따라 변하는 외부 설정값은 분리하고, 변하지 않는 코드와 빌드 결과물은 유지했다. 덕분에 빌드 과정을 줄이고 환경에 따른 유연성을 확보하게 되었다.

     

    외부 설정

    - 1. OS 환경 변수 : OS에서 지원하는 외부 설정, 해당 OS를 사용하는 모든 프로세스에서 사용

    - 2. 자바 시스템 속성 : 자바에서 지원하는 외부 설정, JVM 안에서 사용

    - 3. 자바 커맨드 라인 인수 : 커맨드 라인에서 전달하는 외부 설정, 실행시 `main(args)` 메서드에서 사용

    - 4. 외부 파일(설정 데이터) : 프로그램에서 외부 파일을 직접 읽어서 사용

        ㆍ애플리케이션에서 특정 위치의 파일을 읽도록 해둔다. 예) `data/hello.txt`

        ㆍ그리고 각 서버마다 해당 파일안에 다른 설정 정보를 남겨둔다.

            ○ 개발 서버 `hello.txt` : `url=dev.db.com`

             운영 서버 `hello.txt` : `url=pro.db.com`

     

    3. 외부 설정 - OS 환경 변수

    - OS 환경 변수(OS environment variables) 는 해당 OS를 사용하는 모든 프로그램에서 읽을 수 있는 설정값이다.

    - 한마디로 다른 외부 설정과 비교해서 사용 범위가 가장 넓다.

     

    *조회 방법*

    - 윈도우OS : `set`

    - MAC, 리눅스 OS: `printenv`

     

    *설정 방법*

    - OS환경 변수의 값을 설정하는 방법은 `윈도우 환경 변수` , `mac 환경 변수` 등으로 검색하면 많은 예시 확인 가능

     

    - `System.getenv()` 를 사용하면 전체 OS 환경 변수를 `Map`으로 조회할 수 있다.

    - `System.getenv(key)` 를 사용하면 특정 OS 환경 변수를 `String` 으로 조회할 수 있다.

     

    - OS 환경변수를 설정하고, 필요한 곳에서 `System.getenv()` 를 사용하면 외부 설정을 사용할 수 있다.

    - 이제 데이터 접근 URL과 같은 정보를 OS 환경 변수에 설정해두고 읽어들이면 된다.

    - 예를 들어서 개발 서버에서는 `DBURL=dev.db.com` 과 같이 설정하고, 운영 서버에서는 `DBURL=prod.db.com` 와 같이 설정하는 것이다.

    - 이렇게 하면 `System.getenv("DBURL")` 을 조회할 때 각각 환경에 따라서 서로 다른 값을 읽게 된다.

     

    - 하지만 OS 환경 변수는 이 프로그램 뿐만 아니라 다른 프로그램에서도 사용할 수 있다.

    - 쉽게 이야기해서 전역변수 같은 효과가 있다.

    - 여러 프로그램에서 사용하는 것이 맞을 때도 있지만, 해당 애플리케이션을 사용하는 자바 프로그램 안에서만 사용되는 외부 설정값을 사용하고 싶을 때도 있다.

     

    4. 외부 설정 - 자바 시스템 속성

    - 자바 시스템 속성(Java System properties) 은 실행한 JVM 안에서 접근 가능한 외부 설정이다.

    - 추가로 자바가 내부에서 미리 설정해두고 사용하는 속성들도 있다.

    - 자바 시스템 속성은 다음과 같이 자바 프로그램을 실행할 때 사용한다.

        ㆍ예) `java -Durl=dev -jar app.jar`

        ㆍ`-D` VM 옵션을 통해서 `key=value` 형식을 주면 된다.

        ㆍ순서에 주의해야 한다. `-D` 옵션이 `-jar` 보다 앞이다.

     

    - `System.getProperty(key)` 를 사용하면 속성값을 조회할 수 있다.

    - 자바가 기본으로 제공하는 수 많은 속성들이 추가되어 있는 것을 확인할 수 있다.

    - 자바는 내부에서 필요할 때 이런 속성들을 사용하는데, 예를 들어서 `file.encoding=UTF-8`를 통해서 기본적인 파일 인코딩 정보 등으로 사용한다.

     

    *Jar 실행*

    * `jar` 로 빌드되어 있다면 실행시 다음과 같이 자바 시스템 속성을 추가할 수 있다.

    java -Durl=devdb -Dusername=dev_user -Dpassword=dev_pw -jar app.jar

     

    *자바 시스템 속성을 자바 코드로 설정하기*

    - 자바 시스템 속성을 앞서 본 것처럼 `-D` 옵션을 통해 실행 시점에 전달하는 것도 가능하고,

    - 다음과 같이 자바 코드 내부에서 추가하는 것도 가능하다. 코드에서 추가하면 이후 조회시 값을 조회할 수 있다.

        ㆍ설정 : `System.setProperty(propertyName, "propertyValue")`

        ㆍ조회 : `System.getProperty(propertyName)`

    - 참고로 이 방식은 코드안에서 사용하는 것이기 때문에 외부로 설정을 분리하는 효과가 없다.

     

    5. 외부 설정 - 커맨드 라인 인수

    - 커맨드 라인 인수(Command line arguments)는 애플리케이션 실행 시점에 외부 설정값을 `main(args)` 메서드의 `args` 파라미터로 전달하는 방법이다.

    - 다음과 같이 사용한다.

        ㆍ예) `java -jar app.jar dataA dataB`

        ㆍ필요한 데이터를 마지막 위치에 스페이스로 구분해서 전달하면 된다.

            이 경우 `dataA`, `dataB` 2개의 문자가 `args`에 전달된다.

     

    *Jar 실행*

    - `jar` 빌드되어 있다면 실행시 다음과 같이 커맨드 라인 인수를 추가할 수 있다.

    java -jar project.jar dataA dataB

     

    *key=value 형식 입력*

    - 애플리케이션을 개발할 때는 보통 `key=value` 형식으로 데이터를 받는 것이 편리하다

    - 실행해보면 커맨드 라인 인수는 key=value 형식이 아니다. 단순히 무자를 여러개 입력 받는 형식이다.

    - 개발자가 = 을 기준으로 직접 데이터를 파싱하고 Map 같은 형식으로 변환하는 번거러움이 있다.

     

    6. 외부 설정 - 커맨드 라인 옵션 인수

    *커맨드 라인 옵션 인수(command line option arguments)*

    - 커맨드 라인 인수를 `key=vlaue` 형식으로 구분하는 방법이 필요하다.

    - 그래서 스프링에서는 커맨드 라인 인수를 `key=value` 형식으로 편리하게 사용할 수 있도록 스프링 만의 표준 방식을 정의했는데, 그것이 바로 커맨드 라인 옵션 인수이다.

     

    - 스프링은 커맨드 라인에 `-`(dash) 2개(`--`)를 연결해서 시작하면 `key=value` 형식으로 정하고 이것을 커맨드 라인 옵션 인수라 한다.

        ㆍ`--key=value` 형식으로 사용

        ㆍ`--usename=userA --username=userB` 하나의 키에 여러 값도 지정할 수 있다.

     

    *옵션인수*

    - `--` 로 시작

    *옵션인수가 아님*

    - `--` 로 시작하지 않는다.


    *참고*

    - 참고로 옵션 인수는 `--username=userA --username=userB` 처럼 하나의 키에 여러 값을 포함할 수 있기 때문에 `appArgs.getOptionValues(key)` 의 결과는 리스트(`List`)를 반환한다.

    - 커맨드 라인 옵션 인수는 자바 언어의 표준 기능이 아니다. 스프링이 편리함을 위해 제공하는 기능이다.

     

    7. 외부 설정 - 커맨드 라인 옵션 인수와 스프링 부트

    - 스프링 부트는 커맨드 라인을 포함해서 커맨드 라인 옵션 인수를 활용할 수 있는 `ApplicationArguments`를 스프링 빈으로 등록해둔다.

    - 그리고 그 안에 입력한 커맨드 라인을 저장해둔다.

    - 그래서 해당 빈을 주입 받으면 커맨드 라인으로 입력한 값을 어디서든 사용할 수 있다.

     

    8. 외부 설정 - 스프링 통합

    - 지금까지 살펴보, 커맨드 라인 옵션 인수, 자바 시스템 속성, OS 환경변수, 어디에 있는 외부 설정값을 읽어야 하는지에 따라 각각 읽는 방법이 다르다.

    - 외부 설정값이 어디에 위치하든 상관없이 일관성있게 외부 설정값을 읽을 수 있다면 더 편리할 것이다.

    - 스프링은 이 문제를 `Environment`와 `PropertySource` 라는 추상화를 통해서 해결한다.

     

    *스프링의 외부 설정 통합*

     

    *PropertySource*

    - `org.springframework.core.env.PropertySource`

    - 스프링은 `PropertySource` 라는 추상 클래스를 제공하고, 각각의 외부 설정을 조회하는 `XxxPropertySource` 구현체를 만들어 두었다.

        ㆍ`CommandLinePropertySource`, `SystemEnvironmentPropertySource`

    - 스프링은 로딩 시점에 필요한 `PropertySource`들을 생성하고, `Environment` 에서 사용할 수 있게 연결해둔다.

     

    *Environment*

    - `org.springframework.core.env.Environment`

    - `Environment`를 통해서 특정 외부 설정에 종속되지 않고, 일관성 있게 `key=value` 형식의 외부 설정에 접근할 수 있다.

        ㆍ`environment.getProperty(key)` 를 통해서 값을 조회할 수 있다.

        ㆍ`Environment`는 내부에서 여러 과정을 거쳐서 `PropertySource` 들에 접근한다.

        ㆍ같은 값이 있을 경우를 대비해서 스프링은 미리 우선순위를 정해두었다.

    - 모든 외부 설정은 이제 `Environment`를 통해서 조회하면 된다.

     

     

    9. 설정 데이터1 - 외부 파일

     

    10. 설정 데이터2 - 내부 파일 분리

     

    11. 설정 데이터3 - 내부 파일 합체

     

    12. 우선순위 - 설정 데이터

     

    13. 우선순위 - 전체

     

    14. 정리

     

    댓글

Designed by Tistory.