home

아이들나라 통합 회원 시스템을 소개합니다. (강력한 의존관계의 시스템에서 조금씩 느슨해지기)

안녕하세요. 저는 아이들나라 플랫폼팀 박승규입니다.
아이들나라플랫폼팀에서는 2023년 7월 아이들나라 통합 회원 시스템이 1차 오픈을 했습니다.
통합회원 시스템을 만들기 위해 기존 아이들나라 회원 시스템을 유지 보수하면서
과거의 아이들나라 회원 시스템의 모습
개선해야 할 부분과 그에 따른 고민
그리고 그 문제를 구조적으로 어떻게 해결하려고 하였는지
에 대한 내용과 그리고 그렇게 첫발을 내디딘 아이들나라 통합회원 시스템의 모습을 공유드리고자 글을 작성하게 되었습니다.

들어가며,

[문의1]
A: 회원 로그인 / 회원 가입이 안되는데 확인 부탁드려요.
B: 확인해 보니 아이들나라 회원 시스템에서 연동하는 시스템에서 오류가 발생되어 비정상 동작을 하였습니다. 해당 담당자에게 문의해보겠습니다.
[문의2]
A: 회원 로그인 / 회원 가입이 안되는데 확인 부탁드려요.
B: 확인해 보니 아이들나라 회원 시스템에서 연동하는 시스템의 유효성 처리 정책에 의해 처리 요청이 제한되었습니다. 해당 담당자에게 문의해보겠습니다.
위의 내용처럼 여러분들은 시스템을 구축, 운영하면서 연동하는 외부시스템에 의해 나의 비즈니스가 강력하게 영향을 받는 경험을 해본 신 적이 있으신가요?
우리가 담당하는 시스템은 필연적으로, 또는 어쩔 수 없이 외부 시스템과의 연동 을 하여 원하는 서비스의 기능을 구축하고 제공을 하게 됩니다.
외부연동 없이 독립적으로 돌아가는 서비스도 있겠지만 대부분의 시스템들은 타 시스템과의 의존관계를 형성할 수 밖에 없습니다.
그러다가 어느 순간 우리의 시스템은 연동하는 시스템과 강력하게 의존관계를 형성하게 되어 독립적으로 시스템의 확장, 수정이 어려운 상태로 가게 되는 경우가 많습니다.
돌아와서, 아이들나라 서비스는 기존에는 U+ 계정으로 이용하는 IPTV 와 Mobile에서 제공하는 서비스였습니다.
하지만 U+ 고객 이외에 다양한 많은 고객이 서비스를 사용할 수 있도록 2022년 11월 소셜 로그인 및 인앱구독을 할 수 있는 시스템이 오픈을 하였습니다.
But, 신규 회원 시스템은 오픈은 되었지만 기존에 사용하던 U+ 계정을 사용하던 U+ 시스템과의 연동은 그대로 있는 상태로 해당 시스템에 소셜 로그인/가입의 정보를 저장하거나 연동하도록 오픈이 되었습니다.

기존 아이들나라의 회원 시스템의 모습과 고민

소셜 로그인/가입이 가능한 기존 아이들나라 회원 시스템은 어떤 모습일까요?
기존 회원 시스템은 간략히 위와 같이 기존 U+ 계정처리를 담당하는 U+시스템과의 연동 Flow를 유지한 채 오픈을 하게 되었습니다.
회원 시스템 주요 기능은 대표적으로
1.
회원가입 / 탈퇴
2.
로그인
3.
회원가입/로그인에 필요한 정보 획득
4.
프로필 정보
가 있을 겁니다.
하지만 중간에 색칠이 되어있는 Box 영역을 보면 느낌이 살짝 오시나요?
아이들나라 회원 시스템은 위에 있는 회원의 주요 기능을 처리하기 위해 오른쪽에 있는 U+ 시스템에 있는 System A~D까지의 정보가 필요하며 System C와 Main System에 데이터를 적재 및 정보를 받아 와야 합니다.
소셜 로그인/가입 기능 오픈 전에는 아이들나라 회원 시스템은 없는 상태였습니다. 단지, Mobile과 U+시스템과의 직접적인 연동이 이루어지는 시스템에서 아이들나라 회원시스템이 소셜 로그인/가입 기능을 중간에서 관리하는 형식으로 오픈을 하게 된 것이었습니다.
그에 따라 아직까지는 원천적인 회원 체계의 처리 및 정보관리아직 U+가 메인으로 관리하고 있는 상황입니다.
→ 아이들나라 회원 시스템이 오픈하여 U+ 계정 이외의 사용자를 수용할 수 있게 되어있지만 시스템적으로는 기존에 연관되어 있던 시스템이 없으면 동작을 할 수 없는 강력한 의존 관계를 가지는 시스템의 모습을 가지게 되었습니다.

어떤 부분이 문제인가?

한가지의 예를 잠시 보시겠습니다.

회원가입시 아래와 같이 동작하게 됩니다.
회원 가입을 위해서는 모바일에서 SystemA, D의 정보를 먼저 획득
이상이 없을 경우 회원 시스템으로 System A,D로 부터 획득한 정보를 포함하여 회원 가입 요청
회원 시스템은 자체 DB에 정보를 적재 후 System C에게 회원 가입 요청(정확하게는 매핑 요청입니다.)
System C는 Main System에게 고객 정보 매핑 또는 생성 요청을 합니다.
Main System까지의 처리가 정상적으로 끝나면 회원가입이 완료
이후 서비스 로그인 시 동일하게 System C → Main System에 정보 존재여부를 확인하여 로그인 처리

그리고 한가지 더!

시스템의 강력한 의존관계 이외에도 추가적으로 U+ 시스템에서 사용하는 여러 가지 정보를 그대로 아이들나라 회원 시스템에 사용을 하고 있습니다.
의존 시스템에서 사용하는 도메인 용어
연동 프로토콜에서 사용하는 의존시스템에서 사용하는 변수명과 의미를 그대로 아이들나라 시스템 내에서 사용
DB 스키마에도 해당 변수명이 적용

문제를 정의하면

연동하는 시스템이 단순히 아이들나라 회원 시스템에서 필요한 기능을 하기 위한 협업 시스템의 의미가 아닌 아이들나라 회원시스템의 기능을 좌지우지하는 시스템이 된 것을 의미하고
그에 따라 아이들나라 회원시스템은 자체적으로 존재하는 시스템이지만, 절대 단독으로 의미를 가지고 동작할 수 없는 시스템이 되었습니다.

문제에 따른 영향은?

지금까지 이야기한 기존 아이들나라 회원시스템의 문제를 생각해 보고 정의한 내용에 따른 영향 범위를 생각하면 아래와 같습니다.
연동 System 이상에 따른 비정상 동작에 따른 우리 시스템의 비정상 동작
연동 System의 정보/제약사항 변경에 따른 영향 전파
이러한 부분은 아이들나라 시스템이 독립적으로 자체적인 회원체계와 계획으로 기능을 변경/발전시키는 것에 상당한 제약사항이 됩니다.

그럼 어떻게?

결국에는 강력하게 의존관계로 있는 시스템의 관계를 느슨하게 만들어야 되는 것이 목표이고 추후에는 서로가 서로의 시스템을 알지 않아도 독립적으로 동작하고 변경사항을 감지하여 진행할 수 있게 하는 것이 해결방안의 목표가 되었습니다.
회원시스템 내에서 느슨한 의존관계가 필요한 부분은?
의존 시스템의 도메인 용어나 변수명의 의존 분리 방안은?
해당 시스템이 문제가 생겨도 아이들나라 회원은 자체적으로 동작 할 수 있는 방안은?

회원시스템 내에서 느슨한 의존관계가 필요한 부분은?

아이들나라플랫폼팀에서 작성하신 의존성을 제어하기 위한 여러가지 노력들 내용을 참고해주시면 감사하겠습니다. (구독 시스템을 통해 알아보는 의존성을 제어하기 위한 여러가지 노력들)
이전 내용처럼 아이들나라 회원시스템은 별도 동작하는 시스템임에도 불구하고 U+ 여러 시스템에 강력하게 의존관계를 가지면서 시스템 내에서 경계가 없는 상태로 되어있습니다.
이러한 부분에서 첫 번째로는 아이들나라 회원은 여러 의존관계에 대해서 경계부터 나누어야 했습니다.
클린아키텍처에서, 소프트웨어 아키텍처는 선(경계)을 긋는 기술이라고 이야기를 하며
소프트웨어 요소를 서로 분리하고, 경계 한편에 있는 요소가 반대편에 있는 요소를 알지 못하도록 막는 것
이라고 이야기하고 있습니다.
그리하여 아이들나라 회원에서는 외부 시스템의 의존관계에 대해서 경계를 긋기로 하였습니다. (선을 긋는 내용에 대해서는 클린아키텍처 17장(경계: 선긋기)를 참고해주시면 감사하겠습니다.)
기존 아이들나라 회원시스템 처리되는 구조 / 비즈니스 로직에서는 아이들나라 자체 시스템의 처리 부분과 U+시스템과의 처리 요소에 의한 처리가 섞여 있었습니다.
이러한 부분은 결국 여러 의존성이 제어되지 않아 의존 시스템, 로직의 변경사항이 관심사의 로직에 영향을 끼치게 되었습니다.

AS-IS

한 예로 위의 간략한 그림처럼
기존 아이들나라 회원 시스템에서는 회원 가입 처리 시에는 SnsSignUpApiProxy라는 proxy를 이용하여 U+ 시스템으로 부터 회원 가입 요청 처리 요청이 완료된 후의 정보로 아이들나라 회원의 이후 회원 가입 처리 Flow가 진행되었습니다.
public TsnUser saveUser(TsnUser tsnUserVo, TsnSnsUserCi tsnSnsUserCiVo, List<TsnPrvs> tsnPrvsListVo) { //U+ 시스템 ASignUpResult signUpResult = getuPlusIdSignUpResult(tsnUserVo, tsnSnsUserCiVo, tsnPrvsListVo); TsnUser userInfo = tsnUserVo.signUpTsnUserOf(signUpResult, tsnSnsUserCiVo.id()); saveTsnUser(userInfo); //사용자 저장 saveTsnSnsUserCi(tsnSnsUserCiVo); //사용자 CI 저장 saveTsnPrvs(tsnPrvsListVo); //약관저장 return userInfo; } private ASignUpResult getuPlusIdSignUpResult(TsnUser tsnUserVo, TsnSnsUserCi tsnSnsUserCiVo, List<TsnPrvs> tsnPrvsListVo) throws BusinessException { // One ID Key가 존재하면 SNSID U+ID 연결, 없으면 SNS ID 신규 가입 호출 if (tsnUserVo.oneIdKey() != null && StringUtils.hasText(tsnUserVo.oneIdKey().value())) { return snsSignUpApiProxy.aSnsidMapping(); } //SNSID 신규 회원 가입(ASnsidRegister) return snsSignUpApiProxy.aSnsidRegister(); }
Java
복사
위에서 보면 알 수 있듯이 U+ 시스템의 처리를 호출한 후 그 후에 아이들나라 자체의 처리가 진행되는 것을 볼 수 있습니다.
이렇게 될 경우 회원가입 시 시작하는 첫 번째 단계인 U+ 시스템의 의존관계가 강력하게 아이들나라 회원가입처리에 영향을 주게 됩니다.
그리하여
위의 그림처럼 아이들나라 회원에서 회원가입 시 처리되는 서비스는 U+ 시스템과의 연동관계에 대해서 직접적인 의존관계 부분에 대해 경계를 그어 의존관계를 끊을 필요가 있었습니다.

TO-BE

그에 따라 AS-IS 상태의 의존관계를 느슨하게 하기 위해
1.
먼저 아이들나라 자체 서비스에서 제약사항을 체크 후 저장(가입 처리)
2.
처리 완료 후 SignUpEvent 발행
3.
이벤트 구독후 U+ 연동 처리 진행
의 단계로 아이들나라 회원 처리 영역과 U+ 시스템 처리 영역에 대해 경계를 나누었습니다.
override fun signUp(signUpCommand: SignUpCommand): SignUpResult { signUpValidator.validate( ci = signUpCommand.userPhoneAuthenticationInfo.ci, accountId = signUpCommand.accountId, accountType = signUpCommand.accountType, ) val inaraUserId = getInaraUserId(signUpCommand.userPhoneAuthenticationInfo.ci) val user: User = signUpCommand.toDomain(inaraUserId) val savedUser = signUpPort.signUp(user) //아이들나라 회원가입에 대한 처리 완료후 회원가입 이벤트 발행 val sessionId = UUID.randomUUID().toString() val signUpUserEvent: SignUpUserEvent = SignUpEventFactory.generateSignUpEvent(user, sessionId) applicationEventPublisher.publishEvent(signUpUserEvent) return SignUpResult( user = savedUser, sessionId = sessionId, ) }
Java
복사
위와 같이 TO-BE에서는 아이들나라 내부의 회원 가입 처리 완료 이벤트를 발행하여 이후 U+ 시스템 연동을 진행하도록 하였습니다.
강력한 의존 시스템과의 관계에서 경계를 긋고 비즈니스로직 처리 순서 및 이벤트 발행으로 느슨한 의존관계를 가질 수 있는 방안에 대해 대표적으로 회원 가입 부분에 대해서 간략히 공유를 드렸습니다.
이와 같이 아이들나라 회원 시스템 내에서 U+ 시스템과 강력하게 의존관계가 있는 비즈니스 로직 , 의존관계, 구조 등에 대해서 경계를 그는 작업을 하였습니다.

의존 시스템의 도메인 용어나 변수명의 의존 분리 방안은?

두 번째로 시스템 내에 있는 의존시스템에서 사용하는 도메인 용어, 변수명의 의존분리를 어떻게 할지에 대한 방안으로는 매핑 테이블을 구성하여 아이들나라에서 사용할 도메인을 새로 정의하고 해당 속성으로 동작하도록 변경했습니다. 그리고 의존시스템과 통신 시에는 해당 매핑 테이블을 통해 의존시스템과 연동하도록 하였습니다.
모두 간단히 사용하는 매핑 테이블을 두면서 기존 아이들나라 회원 시스템 깊숙이 있는 여러 U+ 시스템의 도메인 용어, 네이밍을 제거하게 되었습니다.
따라서, 이후 아이들나라 서비스 내에서는 아이들나라 내에서 사용되는 도메인 용어, 네이밍으로 연동하여 외부 시스템의 정책, 도메인 용어가 변경되어도 영향을 받지 않도록 설계 및 작업을 진행하였습니다.
기존 아이들나라 시스템에서 사용하던 U+ 시스템의 user_id , profile_id 등은 해당 dataType의 체계가 변할 때 영향을 받을 수 있기 때문에 새롭게 user_id , profile_id는 새로운 포맷으로 아이들나라에서만 사용될 수 있게 재 정의후 해당 매핑 테이블을 만들어 uplus_user_id , uplus_profile_id를 맵핑시켜 해당 값으로 U+ 시스템과 연동하도록 분리를 하였습니다.

해당 시스템이 문제가 생겨도 아이들나라 회원은 자체적으로 동작 할수 있는 방안은?

마지막으로는 외부시스템이 시스템적으로 비정상 동작을 하거나 또는 외부 시스템의 정책이 변경될 시 그것의 영향을 받지 않게 독립성을 유지하게 하는 방안을 고민하였습니다.
해당 고민의 방안으로는 외부시스템과의 연동 처리, 정책에 의한 비즈니스 로직등을 한 곳에 모아 관리하여
외부 시스템의 변경사항에 대한 작업이 해당 시스템에서만 영향을 받도록 하나의 전용 시스템을 구성하였습니다.
이처럼 신규 구축된 아이들나라 통합회원은 U+ 시스템과의 연동 처리가 필요한 것에 대해서는 Uplus Mapper Server에게 이벤트 발행, 정의된 프로토콜에 의한 연동 등을 통해 외부시스템의 처리를 진행하도록 하였습니다.
그리고 U+ 시스템의 변경 작업에 대해서는 해당 Uplus Mapper Server에서만 대응을 하여 더 이상 의존 시스템의 변경, 이상 등의 상태가 아이들나라 회원 시스템으로 전이되지 않도록 방안을 잡았습니다.

정리하면,

1.
아이들나라 회원 시스템 내의 비즈니스로직, 의존 관계에 대해서 경계를 정하고 분리한다.
2.
아이들나라 회원은 연동 시스템의 처리 여부와 상관없이 요청에 대한 처리를 마무리 짓는다.
3.
아이들나라 회원은 자체 도메인 용어와 정보로 동작을 하여 연동 시스템의 정보나 정책이 변경되어도 영향을 받지 않는다.
4.
연동 시스템에 변경사항, 시스템 이슈가 아이들나라 회원 시스템에 영향을 주지 않고 독립적으로 동작해야 한다.
기존 외부시스템의 강력한 의존관계에서 생기는 문제를 해결하기위해 위의 4가지를 문제해결 가설로 정의하고 해결하기 위한 방안을 공유 드렸습니다.

아이들나라 통합회원은?

그리하여 1차적으로 아이들나라 통합회원은 아래와 같은 모습으로 구성하게 되었습니다.

통합회원의 모습은?

1) Inara Member Server (아이들나라 통합회원 서버)는 이제는 자체 회원의 도메인과 네이밍으로 해당 영역에서 도메인 로직이 마무리될 수 있게 구성 및 U+ 시스템으로 부터 독립성을 가지게 하였고,
2) Inara Uplus Mapper Server (유플러스 매핑서버)에서는 아이들나라 통합회원의 Key와 U+ 시스템 연동 시 필요한 Key와 정보를 매핑하여 관리하여 U+ 시스템과의 처리를 한 곳에 묶어 변경사항이 외부로 전파되지 않도록 캡슐화를 하였습니다.
이렇게 기존에 여러 의존관계 책임을 가지고 있는 아이들나라 회원에서 각각의 책임(아이들나라 회원 관련 처리, Uplus 연동)을 가지는 시스템 군으로 분리하여 기존에 시스템의 고민을 해결 보려고 하였습니다.

느슨하게 하기위한 여러가지 내용들

간략한 그림으로 말씀드렸지만 해당 고민을 해결하기 위해 통합회원 시스템 구축 시 많은 고민에 따른 기술, 방법 등이 적용되었습니다.
DMS를 통한 기존 시스템의 데이터와 동기화
Event Driven을 이용한 비동기 처리, 이력 관리
Circuit Breaker를 활용한 Latency Tolerance, Fault Tolerance
등등
많은 방법들이 들어가 있으며 이 다음 의존성을 느슨하게 하기 위한 여러 작업들에 대해 계속 공유 드리 도록 하겠습니다.

마치며

서두에 이야기한 것처럼 우리가 운영하는 시스템은 언제나 강력한 의존 관계를 가질 수 있습니다.
이러한 의존관계가 우리 시스템의 발전을 막는다는 신호가 느껴지는 순간은 오게 되고 그것에 대해서 고민을 하는 시기를 맞이하게 됩니다.
이러한 부분에 대해 이번 시간에는 아이들나라 회원시스템이 기존 외부 시스템과 어떻게 느슨해지려고 고민하고 방안을 선택했는지 공유 드렸습니다.
이러한 의존관계를 개선하는 작업은 한 번에 되는 것이 아닌 계속 문제를 찾고, 정의하고, 방안을 선택하고 적용하는 과정이 반복되어야 한다고 생각합니다.
아직 아이들나라 통합회원은 이러한 과정의 한 사이클을 마치고 두번째 Phase를 진행하려고 하고 있습니다.
이후 더 개선된 아이들나라 통합회원 내용을 가지고 다시 찾아뵙도록 하겠습니다.
긴글 읽어주셔서 감사합니다.
+ 아이들나라서비스의 많은 팀들은 다양한 과제, 도전을 준비 중에 있습니다. 많은 관심과 지원 부탁드립니다.