피처 플래그, 언제 유용하고 언제 독이 되는가
When Feature Flags Do and Don't Make Sense

피처 플래그는 A/B 테스트, 대규모 기능 개발, 배포 통제 불가 상황에서 유용하다. 하지만 모든 변경을 플래그 뒤에 숨기라는 정책은 오히려 복잡성을 키우고 기술 부채를 쌓는다. 플래그가 쌓이면 조합 폭발로 버그가 생기고, 죽은 코드가 대형 사고를 유발한 사례도 있다. 저자는 플래그 사용의 장단점을 균형 있게 따져보고, 배포를 통제할 수 있는 팀이라면 롤백과 테스트에 집중하라고 조언한다.
플래그가 1년 동안 꺼지지 않았다면, 그것은 큰 회귀를 가리고 있을 수 있다.
HN 토론
36- paulryanrogers
플래그 설정 테이블에 기본값이 아닌 레코드가 5,000개나 있는 회사에서 일한 적이 있는데, 수백 가지의 가능한 설정이 있었습니다. 또한 어떤 설정을 건드릴 때마다 대규모 덮어쓰기 위험이 있는, 활성화된 ID가 포함된 압축된 플래그도 보았습니다. 그리고 실제 또는 유사한 구조의 레코드 집합을 로드하기 전에는 정확히 어떤 일이 일어날지 아무도 이해할 수 없을 정도로 마법이 가득한 플래그 회피 모듈도 있었습니다. 그들은 변화가 잦아서 결과를 한 달 이상 신뢰하지 않았습니다. 이런 혼란의 근거는 플래그가 너무 많으면 사람들이 간과하거나, 출시 기간 후에 새로운 기능을 기본으로 켜는 것을 잊어버릴 수 있다는 것입니다. 제 경험상 모든 기능과 코드 경로에 플래그를 다는 것과 아무것도 플래그를 달지 않는 것 사이에 균형이 있습니다. 물론 플래그 자체가 복잡성과 위험을 초래합니다. 그리고 회귀 테스트를 위해 잔재물과 QA를 제거하는 작업도 있습니다.
- stopping
워크플로우에 피처 플래그를 통합하는 좋은 방법을 찾지 못했습니다. 12단계 롤아웃을 수십 개의 독립적인 활성 플래그로 관리하면서 상당한 인지 부하가 발생했습니다. 제가 하는 변경은 대개 수백 또는 수천 개의 호출자가 있는 기본 라이브러리의 광범위하고 사소하지 않은 리팩터링입니다. 이런 변경은 플래그를 적용하기가 매우 어렵고(특히 API 변경), 다른 개발자가 병합 충돌 해결을 잘못해서 제 플래그 게이트 중 하나를 실수로 빼먹기 쉽습니다. 지금까지 이런 변경에 플래그를 적용하는 좋은 지침을 찾지 못했습니다. 파일을 광범위하게 복제하거나 OOP를 남용하거나 임시 버전 관리 시스템을 사용하지 않고서는 말이죠. 우리 조직에서 아무도 이런 작업을 하려 하지 않은 것은 놀라운 일이 아닙니다.
- classictraffic
전체 전제에 동의하지만 비용 논쟁은 다소 과장된 것 같습니다. '불필요한' 피처 플래그를 추가하는 것은 그렇게 큰 문제가 아니라고 생각합니다. 피처 플래그는 추가하고 유지하는 데 비용이 저렴합니다. 또한 때로는 피처 플래그를 전환하는 것이 롤백보다 빠를 수 있습니다. 특히 여러 시스템이 관련된 경우에는 더욱 그렇습니다. 진짜 비용은 피처 플래그가 코드 비대와 가독성 문제를 일으킬 수 있다는 것입니다. 엔지니어들이 일반적으로 출시 후 피처 플래그를 정리하는 데 신경을 쓰지 않기 때문입니다. 하지만 이것은 '피처 플래그를 덜 사용하거나 필요할 때만 사용하자'는 부족 사고방식을 요구할 정도로 쉽게 해결할 수 있는 문제라고 생각합니다. LaunchDarkly는 피처 플래그 사용을 추적하고 오래된 플래그를 정리하도록 알리는 것을 쉽게 해줍니다.
- MaulingMonkey
피처 플래그는 훌륭합니다. 선택적 하위 시스템에서 크래시나 메모리 손상을 조사하고 있나요? 하위 시스템을 비활성화하여 같은 브랜치에서 일하는 동료들의 작업을 막지 않으면서 원인을 추적하세요.
피처 플래그는 끔찍합니다. 선택적 하위 시스템에서 크래시나 메모리 손상을 조사하고 있나요? 이전에 로컬 빌드에서 비활성화해 두었다면, QA가 훌륭한 재현 단계를 제공했음에도 불구하고 재현에 실패하며 몇 시간을 낭비하게 될 것입니다.
(게임 개발 경험에서 저는 오디오 하위 시스템을 비활성화하는 대신 볼륨을 0으로 설정하여 오디오를 음소거하는 법을 배웠습니다.)
- conradludgate
저는 우리 컴포넌트에 피처 플래그를 도입하고 있습니다.
롤백이 우리에게 충분하지 않은 이유는 우리 서비스가 반 상태 저장형이기 때문입니다(postgres 연결은 상태 저장형이며, 우리는 그 연결을 프록시합니다). 이 때문에 우리는 항상 연결이 소진되도록 5일 동안 이전 포드를 유지합니다.
배포+롤백은 3배의 포드가 남게 되고, 수정 패치를 배포하면 4배가 됩니다. 수정을 배포하지 않으면 다음 릴리스를 위해 2주 분량의 변경 사항이 쌓이게 됩니다.
이 때문에 우리는 대신 피처 플래그를 사용합니다. 위험한 변경 사항에 대해 매우 빠르게 켜고 끌 수 있으며, 포드 수에는 변화가 없습니다.