Pinpoint

핀포인트에 어떤 기여를 하셨죠?

저는 Pinpoint Batch 모듈에 Webhook 기능을 개발하면서 Metric 별로 수집되는 서로 다른 값의 형식을 추상화할 수 있는 DTO 구조를 설계했고 관련 Alarm 도메인 구조를 재설계 하였습니다. 또한 Webhook Json Data Spec을 정의하고 Pinpoint webhook Receiver 예제 프로젝트를 개발하였습니다.

현재에도 진행중이신가요??

네 그렇습니다. 원래 계획대로라면 이미 끝났어야만 하는데 사실 Batch가 Pinpoint Web 모듈 내에서 독립된 모듈로 분리되면서 머지가 늦은 것 같습니다. 웹 모듈 내의 배치에서는 웹훅 기능이 정상동작하는 것을 테스트 했으며, 현재 독립된 batch 모듈로 webhook 기능을 옮기는 작업을 진행하고 있습니다.

얼마 정도 후에 머지가 될 예정인가요??

팀원 분들이 같이 힘을 합치면 2~3일 안에도 끝낼 수 있습니다. 하지만 두 분다 직장도 계시고 네이버 경력 공채에 참여중이시기 때문에 시간 맞추기도 어려웠고, 저도 현재 예약 플랫폼 채용 과정에 참여중이라서 이번 년도 안에 마스터에 머지하는게 저희 목표입니다. 핀포인트 팀과도 이미 이야기 나누었구요!!

핀포인트를 개발하시면서 어려움이 있으셨나요??

여러가지 어려움 중 한가지는 Checker에서 검색하는 Metrics 들의 타입이 너무 다르다는 것이었습니다. Checker의 구현체에 따라서 Metric 값의 타입은 Integer, Integer 타입의 Array, 특정 객체 타입의 Array 등 다양한 타입이 존재했습니다. 기존 SMS와 Email을 통해서 알람을 보낼 때는 수집된 값의 형식이 달라도 전송하기전에 Message Template을 통해서 특정 텍스트 형식을 만들어 보내면 됐었지만, Webhook 기능은 Pinpoint와 다른 어플리케이션 간에 확장성 제공이 목적이었기 때문에 Metric 별로 특정 텍스트 형식을 만들어 보내기에는 사용자의 입장에서 자유도가 떨어지고 필요시 다시 문자열 처리를 해야만하는 부담을 주는 상황이었습니다.

문제를 해결하기 위해 Metric 별로 수집된 값의 서로 다른 타입을 모두 추상화할 수 있는 DTO 구조를 설계 및 구현했고, 수집된 Metric 값의 형식에 기반하여 도메인 구조를 재설계 및 구현함으로써 문제를 해결할 수 있었습니다.

핀포인트를 개발하시면 가장 좋았던 점은 무엇인가요??

좋았던 점은 사실 너무 많았습니다 거의 대부분이라고 해도 될정도로요!! 모니터링 도메인에서 객체지향이 어떻게 적용되고 있는지도 배울 수 있었고, 같은 멘티들이 다들 경력직 개발자여서 코드리뷰를 통해 “이분들은 코드를 이렇게 짜는구나”, “그러면 이런 장점과 단점이 존재하구나”, “내가 코드를 작성하는 방식을 이렇게 한번 바꿔보면 어떨까?” 에 대해서도 많이 느끼고 배울 수 있었던 기회였던 것 같구요.

가장 좋았던 점은 제 코드에 대해서 질문할 수 있는 능력을 키운것이 가장 좋았던 것 같습니다.

예전에는 제가 코드를 작성함에 있어서 코드에 대해서 질문을 던진 적이 별로 없었습니다. 확장성이나 유지보수성이 어떻게 되든 버그가 없고 잘 돌아가기만 하면 만족했었습니다. 하지만 이번 기회를 통해서 “유지보수성이 좋은 코드란 무엇이고?”, “확장성이 좋은 코드란 무엇인가?” 에 대해서 깊게 생각해 볼 수 있었고 작성된 코드에 대해서 “왜 이건 이렇게 해야만하고?”, “다른 방법을 택하면 왜 안되지?”, “이 방법에 장점은 뭐고 단점은 뭘까?”, “이 사람은 어떤 의도로 이런 코드를 작성했을까?” 등의 질문들을 이제는 자연스럽게 제 자신에게 던질 수 있는 능력을 키운것이 가장 좋았습니다.

Batch 란 무엇인가요??

Batch란 데이터를 실시간으로 처리하는것이 아닌 일괄처리하는 것을 의미합니다. (ex. 정산, 알람 등의 어플리케이션을 구현하기 위해서 사용될 수 있습니다.)

Pinpoint Batch 구조에 대해서 설명해주실 수 있나요??

JobLauncher에 의해서 정해진 시간마다 AlarmJob이 실행되는데 AlarmJob은 하나의 AlarmStep을 가지고 있고, Alarm Step은 AlarmReader, AlarmProcessor, AlarmWriter로 구성되어 있습니다. AlarmReader는 HBase에서 어플리케이션의 Metrics를 가져오고, AlarmProcessor는 이 Metric들이 Threshold가 넘는지 확인하고, AlarmWriter는 Threshold가 넘는 Metric값과 관련 어플리케이션 정보를 User에게 email, sms, webhook 등을 이용해 전송하는 구조를 가지고 있습니다.

HBase에 대해서 알고 계시나요?

HBase는 컬럼 기반의 NoSQL 분산형 데이터 베이스라고 입니다. 스키마, 조인, 인덱스가 없고 대량 데이터에 대해 강력한 연산과 일관성을 제공하는 것으로 알고 있습니다.

분산형 데이터 베이스란 무엇인가요??

분산형 데이터 베이스란 데이터를 분산해서 저장하고 관리해 높은 신뢰성과 성능을 구현하는데 효과적인 데이터 베이스를 분산형 데이터베이스라고 합니다.

스키마 변경에 따른 하위 호환 기능 구현은 어떻게 하셨나요?

webhook 기능을 개발하며 DB 테이블에 컬럼이 하나 추가될 필요가 있었습니다. 컬럼이 추가되지 않으면 webhook 기능을 사용하지 못하기 때문에 기능을 사용하기 위해서는 사용자가 직접 DB에 들어가 컬럼을 추가하는 쿼리문을 실행해야만 했었습니다.

하지만 웹훅 기능을 사용하지 않지만 다른 기능 때문에 최근 release를 다운로드 받은 기존 사용자에게 “DB에 들어가서 column을 추가해 그렇지 않으면 알람 기능 자체를 사용 못할거야!” 라고 말하는 것은 적절하지 않다고 생각했기 때문에 웹훅을 사용하지 않을 기존 사용자를 위해서 하위 호환 기능을 구현할 필요가 있었습니다.

하위 호환을 위해 webhook.enable이라는 property를 통해 웹훅 기능을 사용하는 유저와 사용하지 않는 유저를 구분했습니다. 즉, webhook.enable이 true라고 설정되어 있다면 컬럼이 추가된 쿼리문이 날라가고 webhook이 동작하며, false라고 설정되어 있다면 컬럼이 추가되지 않은 쿼리문이 날라가고 webhook을 비활성화 하면서 하위 호환을 유지할 수 있었습니다.

이를 통해 평소에 전혀 경험해보지 못햇던 데이터베이스 하위 호환을 경험할 수 있어서 즐거운 경험이었습니다.


webper

Spring Security란 무엇인가요??

Spring Security란 인증과, 권한부여, 일반적인 공격에 대한 보호의 기능을 제공하는 프레임워크입니다. Spring Security를 사용하면 어플리케이션의 보안 관련 기능을 자체적으로 구현 할 필요 없이 쉽고 안전하게 구현할 수 있습니다.

왜 Spring Security를 사용하게 되었나요?

공식문서에서 인증과, 권한 부여, 일반적인 공격에 대한 보호의 기능을 제공하는 프레임워크라고 나와있었고 Spring Security를 사용하면 보안 관련 기능을 자체적으로 구현할 필요 없이 쉽고 안전하게 구현할 수 있다고 나와 있길레 사용했습니다. 하지만 사용해보니 전혀 쉽지 않았고 저는 단지 토큰 기반의 인증 기능을 구현하고 싶었을 뿐이지, Servlet이 맵핑되기 전에 Filter기반의 인증과정이 처리되어야 할 필요가 없었지만 토이프로젝트이기도해서 한번 도전해보자, 많이 배워보자 라는 마음으로 시작하였습니다.

무엇이 가장 어려웠나요??

처음에 Spring Security 구조를 잡는 것이 가장 어려웠습니다. Filter, Security Filter 개념도 매우 어려웠고 Servlet, Servlet Container, IoC Container의 개념도 잘 정립이 되어 있지 않은 상태였기 관련 문서도 잘 읽히지 않았지만 계속 하나하나 깊이있게 파다 보니까 구조를 알 수 있었습니다.

Filter와 Security Filter의 차이를 말씀해 주실 수 있나요?

Filter와 Security Filter는 서블릿 컨테이너에 의해 Servlet에 요청이 맵핑되기 전에 실행되는 필터입니다. 둘다 똑같은 필터인데 그냥 Filter는 서블릿 컨테이너에 등록되서 사용되는 필터이고 Security Filter는 DelegatingFilterProxy가 서블릿 컨테이너에 Filter로 등록되어서 ApplicationContext가 관리하는 Filter이자 Bean들인 Security Filter Chain으로 필터 작업을 위임하는 형태입니다.

즉, 쉽게 말해서 Filter와 Security Filter는 모두 서블릿에 요청이 맵핑되기 전에 실행되는 필터인데 이를 서블릿 컨테이너에 직접 등록하느냐, ApplicationContext에 Bean으로 등록해서 사용하느냐의 차이입니다.

Filter와 Interceptor의 차이를 말씀해 주실 수 있나요?

Filter는 Spring Context 외부에 존재하여 Servlet에 요청이 맵핑되기 전에 다양한 작업들을 하는 것을 의미하구요, Interceptor는 Spring Context 내부에 존재하여 DispatcherServlet이 컨트롤러를 호출하기 전, 후에 요청과 응답에 대해 처리 하는 것을 의미합니다.

종진님이 구현하신 Spring Security의 인증방식 아키텍처를 알 수 있을까요?

  1. 처음에 Servlet Container를 통해서 요청이 들어오고 Filter Chain을 수행합니다.
  2. Filter Chain 중에서 DelegatingFilterProxy 필터를 만나면 이는 FilterChainProxy에게 요청을 위임하고 이는 Security Filter Chain을 실행시킵니다.
  3. 다양한 Security FilterChain이 존재하지만 인증을 수행하는 필터인 AuthenticationFilter를 거치게 되고 이 객체를 통해 전체적인 인증 과정이 수행됩니다.
  4. 정상적으로 인증 과정이 수행이 되었다면 AuthenticationFilter는 SecurityContext에 인증 객체를 저장하게 됩니다.
  5. AuthenticationFilter의 임무가 끝났음으로 다음 Security Filter Chain이 시작됩니다.
  6. Security Filter Chain이 다 끝나고 Filter Chain도 다 끝나면 이제 DispatcherServlet으로 요청이 맵핑되어서 관련 로직들이 실행됩니다.

저는 여기서 AuthenticationFilter로서 JWTAuthenticationFilter를 만들었으며 Security Filter Chain에 등록하였습니다. 여기서 JWT 토큰을 분석하여 DB에 있는 데이터와 동일한지에 대해서 살펴 보았고 동일 하다면 SecurityContext에 관련 인증 객체를 저장하였습니다.

SecurityContext는 default로 ThreadLocalSecurityContextHolderStrategy를 사용하여 인증 객체를 저장하기 때문에 서블릿당 하나의 인증 객체가 저장됨을 알 수 있었습니다. 추후에 Controller에서 이러한 인증 객체를 가져와서 직접 관련 비즈니스 로직들을 사용자에 맞게 태웠습니다.

ORM 이란 무엇인가요??

ORM이란 Object-Relational Mapping의 줄임말로써 클래스와 SQL 데이터베이스 스키마의 메타데이터를 사용하여 DB와 통신시 객체와 SQL 테이블간에 자동으로 맵핑해주는 것을 의미합니다.

객체 모델과 관계형 모델간의 패러다임 불일치가 존재하는데 객체간의 관계를 바탕으로 SQL을 자동 생성하여 불일치를 해결하는 것이기도 하다.

ORM을 왜 사용하셨나요??

반복되는 쿼리문을 없앤 더 직관적이고 객체지향적인 코드를 작성하고 싶어서 사용했습니다.

ORM이 모든것을 해결해 주나요?

ORM을 사용하는 것은 매우 편리하지만, 이러한 편리함 때문에 내부 구조를 잘 모르고 사용하면 속도 저하 및 일관성을 무너뜨리는 문제점이 생길 수 있습니다. 또한 일부 자주 사용되는 대형 SQL 문은 속도를 위해 별도의 튜닝이 필요하기 때문에 결국 SQL을 사용할 수도 있습니다.

ORM을 사용하면 완벽하게 쿼리문이 없어지나요?

Spring Data JPA에서 지원해 주지 않는 연산이거나, 성능이 너무 안좋은 쿼리문이 발생할 시 엔티티들을 재설계 하거나 직접 쿼리문을 작성하는 경우도 있습니다.

ORM, JPA, Spring Data JPA의 차이점에 대해서 알려주세요

  • ORM은 클래스와 SQL 데이터베이스 스키마의 메타데이터를 사용하여 어플리케이션이 DB와 통신시 객체와 SQL 테이블간에 자동으로 맵핑해주는 것을 의미하구요
  • JPA는 자바단에서 ORM을 위한 명세를 의미하구요
  • Spring Data JPA는 Spring에서 JPA를 편리하게 사용하기 위해 이를 한번 레파지토리 인터페이스 기반으로 추상화 시킨 명세를 의미합니다.

Hibernate는 무엇인가요??

Hibernate는 자바단의 ORM 표준 명세인 JPA의 구현체 입니다.

엔티티 설정간에 어떠한 제약을 넣을 수 있나요?

Primary Key 맵핑, 엔티티 간의 관계 설정, nullable, length등의 제약을 넣을 수 있는 걸로 알고 있습니다.

JPA에서 객체의 상태는 어떤게 있나요?

  • Transient : JPA가 모르는 상태
  • Persistent : JPA가 관리중인 상태
    • 1차 캐시 : Persistent Context에 인스턴스 저장
    • Dirty Checking : Persistent Context에 올라간 객체의 변경사항을 계속 감지
    • Write Behind : 객체의 상태변화를 DB에 최대한 늦게 필요한 시점에 적용
  • Detached : JPA가 더이상 관리하지 않는 상태
  • Removed : JPA가 관리하긴 하지만 삭제하기로 한 상태

Entity 관계를 어떻게 가져올 것인가?

  • Eager : 지금 관련있는 엔티티를 전부다 가져온다
  • Lazy : 나중에 관련있는 엔티티를 가져온다.