feature flag, feature toggle 또는 flag라고 부르는 feature flag는 무엇일까?
나는 이 개념을 얼마전 devops 관련 멘토링을 통해서 처음 듣게 되었는데, 생각보다 이에 대한 자료가 많이 없어서 직접 작성하게 되었다.
이러한 예시가 무엇이 있을까?
여러 서비스 제공 업체들은 이러한 방식으로 feature flag를 사용하여, 기능을 운영환경에서 테스트하고 있다.
근데, 보통 feature flag 서비스를 구성해서 사용하는 것이 더 장점이 많다고 한다.
장점들을 살펴보자.
feature flag 서비스
위와 같은 서비스 혹은 오픈소스는 아래와 같은 UI를 제공하고, 이를 통해 feature flag를 toggle 할 수 있도록 제공한다.
git clone https://github.com/Unleash/unleash-docker.git
cd unleash-docker
docker compose up -d
위와 같이 docker compose를 이용하면, 간단하게 unleash client를 생성할 수 있다.
unleash client는 http://localhost:4242 에 올라가며, 초기 아이디와 비밀번호는 다음과 같다.
username : admin
password : unleash4all
로그인하고 들어가게 되면, new feature toggle이라는 버튼을 눌러보자.
위와 같은 화면이 나오면, test라는 feature toggle을 생성하자. toggle을 생성하게 되면 아래와 같이 toggle의 status가 보인다.
상단 바의 configure -> api access 를 누르자.
위와 같은 화면이 나오면, 정보를 대충 채우고 environment만 production으로 변경해주자.
생성하면 다음과 같은 API token이 나오는데, 어디인가에 저장해두자.
스프링 프로젝트 생성은 넘어가고, sdk를 사용하기 위해 gradle에 다음 라이브러리를 추가해주자.
dependencies {
implementation 'io.getunleash:unleash-client-java:5.1.0'
}
추가하여 설치 후, UnleashService class를 생성하고 다음과 같이 작성해보자
@Service
public class UnleashService {
private final Unleash unleash;
public UnleashService() {
UnleashConfig config = UnleashConfig.builder()
.appName("java-test")
.instanceId("instance x")
.environment("production")
.unleashAPI("http://localhost:4242/api/")
.customHttpHeader("Authorization", "*:production.901a0b7802e7259e4d8046973b135e7a8cbf4ba2f10f2d46e88288cb")
.build();
this.unleash = new DefaultUnleash(config);
}
public boolean isEnabled() {
return unleash.isEnabled("test");
}
}
appName, instanceId는 unleash에서 식별하기 위해 사용되는 것이니 일단 이 실습에서는 저렇게만 적어두자.
http header의 authorization 뒤에 들어가는 값은 아까 복사해두었던 API Key를 넣으면 된다.
isEnabled
함수는 toggle이 되어 있는지 아닌지 판단해주기위해 boolean을 return하는 함수이다. 이것을 통해 test라는 toggle이 enable 되었는지 판단 할 것이다.
@RestController
@RequestMapping("/test")
public class TestController {
private final UnleashService unleashService;
public Controller(UnleashService unleashService) {
this.unleashService = unleashService;
}
@GetMapping
public String test() {
if (unleashService.isEnabled()) {
return "yes!";
}
return "no!";
}
}
테스트를 위해 다음과 같은 controller를 작성하자.
위 GetMapping이 걸려있는 end-point는 toggle이 활성화되어 있다면 "yes!"를 return 할 것이고, 아니라면 "no!"를 return 할 것이다.
결과를 확인해보자.
feature flag를 on 했을 때, 원하던 것 처럼 yes!가 return 된다.
위와 반대로 off 했을 때, 원하던 것 처럼 no!가 return 된다.
실습을 하다보면, 어차피 on인지 off인지만 판단해줄 서비스가 필요한거면 직접 만들어도 되는거 아닌가? 라고 생각할 수도 있다.
하지만 저런 feature flag를 위한 서비스를 만들 때, 보안적으로 조심해야 할 것이 많다고 생각한다. 이 서비스는 token 발급 및 user 인증등을 통해 그런것을 자동으로 해주어 발생할 수 있는 보안 이슈를 줄여준다.
또한, user metric도 설정을 통해 수집할 수 있기 때문에 feature flag에 대해 유저 정보를 수집하기 쉬워진다는 장점이 있다.