Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

도메인구현 KSUG 20151128

12,113 views

Published on

KSUG 2015-11-28 발표 자료

Published in: Technology
  • Download or read that Ebooks here ... ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THI5 BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ..................................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, CookeBOOK Crime, eeBOOK Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THI5 BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download Full EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download Full EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

도메인구현 KSUG 20151128

  1. 1. 몇 가지 도메인 구현 이야기 최범균(madvirus@madvirus.net),  2015-­‐11-­‐28
  2. 2. 내용 • DIP • AGGREGATE과 참조 • CQRS • 이벤트 2
  3. 3. #1, 아키텍처와 DIP 3
  4. 4. 흔한 구조 ReserveService JavaMailService Reservation Reservation Repository 4
  5. 5. 인프라 스트럭처 도메인 impl 패키지 응용 모듈 구조 ReserveService JavaMailService Reservation Reservation Repository JpaReservation Repository JPA 5
  6. 6. 인프라 스트럭처 도메인 impl 패키지 응용 인프라로의 의존 ReserveService JavaMailService Reservation Reservation Repository JpaReservation Repository JPA 6
  7. 7. 인프라에 의존할 때의 흔한 단점 • 구현교체의어려움 • 응용서비스나 도메인로직테스트어려움 7
  8. 8. 원인 à고수준/저수준이 뒤섞임, 즉, 저수준이 고수준에 영향을 줌 ReserveService: 예약을 위한 응용 로직 à 고수준 Java API로 메일을 발송 à 저수준 도메인: 객체 영속성 à 고수준 JPA로 보관 à 저수준 RDBMS에 보관 à 저저수준 • 고수준모듈:  의미있는단일기능을제공하는 모듈 • 저수준모듈:고수준모듈의기능을구현하기 위해필요한 하위기능의실제구현 8
  9. 9. DEPENDENCY INVERSION PRINCIPLE • 뒤섞임을 제거하려면 à 고수준입장에서 저수준 구현을추상화해서 의존을뒤집음 ReserveService <<interface>> EmailNotifier JavaMail EmailNotifier 응용 로직을 구성하는 “이메일 통지하기"를 표현 9 ReserveService JavaMailService
  10. 10. DIP 적용 예 “저수준의 상세한 내용 없이 구현하기” 참고, http://javacan.tistory.com 10
  11. 11. DIP? 도메인 impl 패키지 SomeDomainService Reservation Repository JpaReservation Repository 11 응용 ReserveService 인프라 스트럭처 EmailService Java EmailService
  12. 12. 잘못된 DIP 적용 도메인 impl 패키지 SomeDomainService Reservation Repository JpaReservation Repository 12 응용 ReserveService 인프라 스트럭처 EmailService Java EmailService JPA
  13. 13. 올바른 DIP 적용 도메인 SomeDomainService Reservation Repository 13 응용 ReserveService 인프라 스트럭처 Email Notifier Java EmailNotifier JpaReservation Repository
  14. 14. DIP 적용 아키텍처 Reserve Service Reservation Reservation Repository JpaReservation Repository Email Notifier JavaMail EmailNotifier Controller Message Listener 14
  15. 15. 노력 • 끊임없는 추상화연습 • DIP  à고수준 모듈입장에서 추상화 15
  16. 16. #2,AGGREGATE, 참조 16
  17. 17. 많은 객체 17
  18. 18. 많은 객체 18 복잡도 관계? 이해? 작은 것에 매몰
  19. 19. 상위 수준에서 묶어서 생각하면 19
  20. 20. AGGREGATE = 개념적으로 하나인 객체 군 <<ROOT>> Order OrderLineShippingInfo Orderer 20
  21. 21. AGGREGATE • 관련된객체들의 묶음 • 특징 • 데이터변경시 한단위로 처리됨 • 비슷한또는거의유사한 라이프사이클을 갖는객체들 • 특히,  삭제시함께삭제됨 • 경계를가짐 • 기본적으로,  한Aggregate에 속한객체는다른Aggregate에 속하지않음 • 필요성 • 많은도메인모델을 가능한간단하고 이해가능한 수준으 로만들필요 • 연관의개수를 줄임으로써 복잡도 감소 21
  22. 22. AGGREGATE = 개념적으로 하나인 객체 군 Order  order  =  orderRepository.findById(orderId); order.changeShippingInfo(newShippingInfo); order.calcel(); 완전체를 로딩 AGG  ROOT가 로직/ 일관성(트랜잭션) 처리  책임 22
  23. 23. 도메인 모델에서 AGG 찾기 Showing Reservation Customer Movie DiscountStrategy Rule SeatNo Grade 23
  24. 24. 요구 사항에 따라AGG 경계 정의 예매시영화의시간과 좌석을할당한다 회원은등급을갖는다 영화는 상영일정을갖는다? 영화별로가격할인규칙이다르다 (영화별로다른가격할인을갖는다?) 24
  25. 25. AGG 경계 : 규칙〮트랜잭션 범위 상영관리자가 영화일정을추가해도 영화정보는바뀌지않음 컨텐츠담당자가 영화출연자정보를변경해도 상영일정은바뀌지않음 동시성 처리를 할 때, Moive를 변경하는 동안 관련 Showing을 잠금 필요가 없음 Showing Movie 25
  26. 26. AGG 경계 : 규칙〮트랜잭션 범위 Movie DiscountStrategy Rule • 영화 별로 할인 정책이 고정된다. • 할인 정책 별로 적용 가능 규칙을 갖는다. Movie가 AGG  루트: • movie.updateDescription(desc); • movie.changeDiscountStrategies(discountStrategies); • movie.calculateFee(showing); 26
  27. 27. AGG 경계 : SRP Movie DiscountStrategy Rule • Movie는 영화 정보 제공하는 책임만 갖도록 구성 • 할인 계산은 별도 모듈로 분리 FeeCalculator feeCalculator.calculate(movie,  showing) 27
  28. 28. 편리한 참조? Showing Reservation Customer Movie reservation.getShowing().getTime() reservation.getShowing().getMovie().getTitle() reservation.getCustomer().getName() 28
  29. 29. AGG 간 참조의 잠재적 문제 편한탐색을오용 (불필요한) 고민 showing.getMovie().changeDescription(…); showing.changeDiscountStrategy(disStrategy); //  Showing.java public  void  changeDiscountStrategy(List<DiscountStrategy>   strategies)  { this.movie.changeDiscountStrategy(strategies); } Lazy  Loading  vs  Earger  Loading?  OSIV? 29
  30. 30. AGG 간 참조의 잠재적 문제 확장 방해 Oracle MySQL Custom  Rule  Engine 30
  31. 31. AGG 간 ID로 참조하기 public  class  Showing  { … private  MovieId movieId; … } public  class  Reservation  { … private  ShowingId showingId; private  CustomerId customerId; … } Showing Reservation Customer 31
  32. 32. 연관 객체 조합은 응용 서비스에서 처리 public  class  ReserveService   { public  ReservationId  reserve(ShowingId   showingId,  CustomerId  customerId)  { Showing  showing  =  showingRepository.findById(showingId); checkNotNull(shwoing); Movie  movie  =  movieRepository.findById(showing.getMovie()); checkNotNull(movie); Customer  customer  =  customerRepository.findById(customerId); checkNotNull(customer); Reservation  reservation  =  reservationFactory.create( showing,  customer,  movie.calculateFee(showing) ); return  reservation.getId(); } … } 32
  33. 33. ID 참조의 특징 • 복잡도낮춤 • 모델복잡도 • 구현복잡도 • Lazy  Loading효과 • 오용방지 • 응집도강화 • AGG별로 확장가능 • 조회성능영향 • 별도모듈 • 더많은코드 33
  34. 34. 노력 • 인내필요 • 당장바꾸기힘든DB  조인중심표준 • 조인에집착하는 개발자 • 기술을떠나구현할 수있는실력쌓기 • 꼭ORM이 있어야AGGREGATE를 구현할수있는것은아님 • 기술중심이아닌도메인 중심으로AGGREGATE를 생각 34
  35. 35. #3, CQRS 35
  36. 36. 도메인 모델로 뷰 처리 ${resList[0].customer.name}님의 예매 목록: <c:forEach  var='res'  items='${resList}'> 예매번호 : ${res.number} 영화 : <a  href="…?id=${res.showing.movie.id"> ${res.showing.movie.title} </a> 시간 : ${res.showing.time} 금액 : ${res.fee} </c:forEach> 참조로 다 연결한 경우 List<Reservation>  resList    = reservationRepository.findByCustomer(customerId); model.addAttribute("resList",   resList); 36
  37. 37. 복잡한 도메인의 조회 기능 특징 • 여러AGG에걸쳐데이터접근 Showing -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ id:  ShowingId time:  Time … Reservation -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ number:  ReservationNo showing:   ShowingId customer:   CustomerId fee:  Money … Customer -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ id:  CustomerId name:  String … Movie -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ id:  MovieId title:   String description:   String … ${resList[0].customer.name}님의 예매 목록: <c:forEach9var='res'9items='${resList}'> 예매번호 : ${res.number} 영화 : <a9href="…?id=${res.showing.movie.id"> ${res.showing.movie.title} </a> 시간 : ${res.showing.time} 금액 : ${res.fee} </c:forEach> 37
  38. 38. 복잡한 도메인의 조회 기능 특징 • 성능중요 • 최대한빨리사용자에게 화면을제공해야 함 • 고민 • 한방쿼리! • 레프트조인! • DB  전용기능! • … 38
  39. 39. 한 모델로 처리하면 한방쿼리! 레프트조인! DB  전용기능! … 같은연관에대해 Lazy  Loading Eager  Loading Batch  Loading … 도메인모델구현복잡도 증가 39
  40. 40. 상태 변경 모델과 조회 모델 분리 [출처 :  http://martinfowler.com/bliki/CQRS.html] 40
  41. 41. 조회 전용 모델 ReservationList -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ customerName:   String reservations:   List<ReservationData> … ReservationData -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ number:   String movieId:   String movieTitle:   String showingTime:   Time fee:  Money … ${resList.customerName}님의 예매목록: <c:forEach  var='res'  items='${resList.reservations}'> 예매번호:${res.number} 영화:<a  href="…?id=${res.movieId"> ${res.movieTitle} </a> 시간:${res.showingTime} 금액:${res.fee} </c:forEach> 41
  42. 42. 다른 기술, 다른 아키텍처 사용 DAO (MyBatis) 컨트롤러 뷰 모델 컨트롤러 응용 서비스 도메인 인프라(JPA) 42
  43. 43. 다른 저장소 사용 DAO 컨트롤러컨트롤러 응용 서비스 도메인 인프라(JPA,  메시징) 43
  44. 44. 같은 기술, 뷰 모델 추가 컨트롤러 뷰 데이터 모델 컨트롤러 응용 서비스 도메인 인프라(JPA) 응용 서비스 44
  45. 45. CQRS 이점 • 모델복잡도감소 도메인자체에집중 조회성능을위한코드없음 45
  46. 46. CQRS 이점 • 조회성능향상에유리 조회전용DB를사용한처리량 향상 조회에특화된쿼리 조회단위캐시기술적용 46
  47. 47. 부담 요인 • 더많은코드,  더많은기술 더 많은 코드 데이터 동기화 처리 더 많은 구현 기술 47
  48. 48. 노력 • 장점과단점을 고려해서 CQRS  도입여부결정필요 • 트래픽이 없는데조회전용저장소고집하지 말것 • 트래픽이 증가하면 조회전용저장소도입검토 • 도메인이 복잡하면 효과있음 • 더많은코드à더많은시간:  X • 한모델로 뷰처리비용>>  뷰모델로 처리비용:  O 48
  49. 49. #4, 이벤트 49
  50. 50. 예매 취소시 환급하려면? • 도메인모델에서 처리? 50 public  class  Reservation  { public  void  cancel(RefundService   refundSvc)  { …  //취소처리 refundStatus  =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus  =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } }
  51. 51. 예매 취소시 환급하려면? • 응용서비스에서 처리? 51 public  class  CancelReservation   { @Transactional public  void  cancel(ReservationId   resId)  { Reservation  res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } }
  52. 52. 고민거리 : 트랜잭션? 52 public   class  Reservation   { public   void  cancel(RefundService   refundSvc)   { …  //취소처리 refundStatus   =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus   =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } } public   class  CancelReservation   { @Transactional public   void  cancel(ReservationId   resId)  { Reservation   res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } } 외부 서비스가 정상이 아닐 경우, 트랜잭션 처리는?
  53. 53. 고민거리 : 성능 53 public   class  Reservation   { public   void  cancel(RefundService   refundSvc)   { …  //취소처리 refundStatus   =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus   =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } } public   class  CancelReservation   { @Transactional public   void  cancel(ReservationId   resId)  { Reservation   res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } } 외부 서비스 완료까지 쓰레드 블록킹
  54. 54. 고민거리 : 설계 54 public   class  Reservation   { public   void  cancel(RefundService   refundSvc)   { …  //취소처리 refundStatus   =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus   =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } } public   class  CancelReservation   { @Transactional public   void  cancel(ReservationId   resId)  { Reservation   res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } } 예매 도메인 모델에 환불 도메인 로직이 섞임
  55. 55. 고민거리 : 설계 55 public   class  Reservation   { public   void  cancel(RefundService   refundSvc)  { …  //취소처리 refundStatus   =  State.REFUND_STARTED; try  { refundSvc.refund(this.paymentId); refundStatus   =  State.REFUND_COMPLETED; }  catch(SomeException   ex)  { … } } } public   class  CancelReservation   { @Transactional public   void  cancel(ReservationId   resId)  { Reservation   res  =  findById(resId); res.cancel(); res.refundStarted(); try  { refundSvc.refund(res.getPaymentId()); res.refundCompleted(); }  catch(SomeException   ex)  { …   } } } 기능이 추가되면 필요한 객체 파라미터 추가? DI로 주입 시도?
  56. 56. 적용해 볼 만한 것 56 이벤트 + 비동기
  57. 57. 이벤트 • 과거에벌어진 어떤것 • 주로상태의변화 • 이벤트예 • 영화추가함(NewMoviedCreated) • 예매함(RevervationCreated) • 영화상영일정추가함(ShowingAdded) • 영화정보변경함(MovieInfoChanged) • 영화가격정책변경함(PricePolicyUpdated) • 예매취소함(ReservationCanceled) 57
  58. 58. 이벤트의 구성 • 구성 • 발생주체(주로 식별자),  일렬번호/버전,  타입,  발생시간 • 내용(payload) • 예,  회원암호변경이벤트 • 발생주체:  "회원mad" • 버전:  1 • 타입:  "PasswordChangedEvent" • 발생시간 :  2015-­‐11-­‐27  09:59:59 • 내용:  {id:"mad",  newPwd:  "xxxx"} 58
  59. 59. 이벤트 관련 구성 요소 59 이벤트 생성 주체 이벤트 디스패처 (이벤트 퍼블리셔) 이벤트 핸들러 (이벤트 구독자) 이벤트
  60. 60. 이벤트 용도 1 • 트리거 • 다른기능을수행하기 위한트리거로 이벤트를 사용 • 예시 • 예매를하면SMS로통지한다. • 예매함이벤트àSMS  통지트리거 • 예매를취소하면환불한다. • 예매취소이벤트à환불트리거 60 예매 취소 이벤트 디스패처 예매취소됨 이벤트 핸들러예매 취소됨 이벤트 예매 취소됨 이벤트 환불 처리
  61. 61. 이벤트 용도 2 • 데이터동기화 • 다른시스템간데이터동기화목적으로 이벤트 사용 • 예시 • 상영일정추가이벤트핸들러 à조회전용저장소에 추가데이터반영 61 상영일정 추가 이벤트 디스패처 일정추가됨 이벤트 핸들러일정 추가됨 이벤트 일정 추가됨 이벤트 일정데이터 추가 커맨드 모델 저장소 쿼리 모델 저장소
  62. 62. 도메인과 이벤트 • 도메인의 상태변경을이벤트로 표현 • "~할때","~가발생하면", "만약~하면" 등의요구사항이 실 제로상태변경인지 확인 • 예시 • "영화정보를변경할때" àMovieInfoChangedEvent • "예매를취소하면" àReservationCanceledEvent 62
  63. 63. (도메인) 이벤트 발생과 처리 63 public  class  Reservation  { public  void  cancel()  { …취소로직 Events.raise(new  ReservationCanceledEvent(getId(),  getPaymentNo(),  …)); } } public  class  CancelReservationService   { @Transactional public  void  cancel(ReservationId   resId)  { Events.register( (ReservationCanceledEvent  evt)  -­‐>  refundSvc.refund(evt.getPaymentNo()) ); Reservation  resv  =  findById(resId); resv.cancel(); } }
  64. 64. 이벤트 적용 장점 • 서로다른도메인영역의 로직이섞이는것방지 • 불필요한 결합(coupling)  제거 64 예매! 취소 이벤트! 디스패처 예매!취소됨 이벤트! 핸들러예매!! 취소됨 이벤트 예매!! 취소됨 이벤트 환불! 처리 예매 취소에 더 이상 환불 로직 없음 예매 도메인에서 환불 도메인으로의 의존 제거
  65. 65. 이벤트 적용 장점 • 이벤트핸들러 추가로기능확장 65 예매 취소 이벤트 디스패처 예매취소됨 이벤트 핸들러예매 취소됨 이벤트 예매 취소됨 이벤트 환불 처리 예매취소됨 이벤트 핸들러2 이메일 통지 예매 취소됨 이벤트
  66. 66. 동기 이벤트 처리의 단점 • 트랜잭션 처리문제,성능(처리량) 문제 66 public  class  ReservationService   { @Transactional public  void  reserve(MovieId   movieId,  ShowingId  showingId,  CustomerId  custId)  { Events.register( (ReservationCreatedEvent   evt)  -­‐>  emailNotifier.notify(…) ); …//  예약도메인로직에서이벤트발생 } } 이메일 발송 중 익셉션이 발생하면? 이메일 서버가 응답 시간이 길면?
  67. 67. 비동기 : 이벤트 처리 시간 • "A할 때,  B해라" 요구사항에서 A와B의간격 • 도메인전문가의 '바로'는 '즉시 실행'이 아님 • 수용가능한지연허용범위가있음 • 예시 • 예매취소시, (늦어도 30분 이내에) 환급처리함 • 결제완료후, (늦어도 다음날7시부터) 배송상태를조회 할수있어야함 • 티켓예매시, (최대10분 안에) 분단위티켓판매 통계에반 영함 • 분단위티켓판매통계가10분주기로생성되어도 대세지장없음 67
  68. 68. 비동기 : 이벤트와 데이터일관성 • "A할 때,B해라" 요구사항에서 A와B의일관성 • 실제로는 한트랜잭션이 아닌경우많음 • 예시 • 이메일발송실패한다고 회원가입을못하지않음 • 고객이예매취소하면, 운영자가 수동으로환불처리가능 68
  69. 69. 응용/인프라 비동기 이벤트 처리 방식 1 • 이벤트디스패처에서 메시지 큐에전송 69 이벤트 디스패처 메시지큐도메인 메시지 리스너 스토리지 도입시 고려사항 • 글로벌 트랜잭션 • 메시지큐가 비정상일 때 이벤트 재전송 방안 이벤트 핸들러
  70. 70. 비동기 이벤트 처리 방식 2 • 로컬이벤트핸들러가 DB에 저장 • 포워더가 이벤트를 전달 70 응용/인프라 이벤트 디스패처 로컬 핸들러 도메인 메시지 리스너 스토리지 메시지큐포워더 단일 트랜잭션으로 처리이벤트 저장 이벤트를 주기적으로 읽어와 전달 어디까지 전달했는지 추적
  71. 71. DB 저장과 포워더 구현 예 • 쇼핑몰, ERP, 택배사연동 71 쇼핑 도메인 쇼핑+이벤트 DB 포워더 주문/결제시 관련 이벤트를 한 트랜잭션으로 저장 ERP 연동모듈 택배사 연동모듈 1분 주기로 새로 전달할 이벤트를 읽어와 외부 시스템에 전달
  72. 72. 비동기 이벤트 처리 방식 3 • 로컬 이벤트핸들러가 DB에 저장 • 이벤트수신측에서 이벤트를 직접가져감(pull) • 이벤트제공API 이용(RESTful  API등) 72 응용/인프라 이벤트 디스패처 로컬 핸들러 도메인 스토리지 이벤트 저장 이벤트 (REST)  API 이벤트 Fetcher 이벤트 핸들러 단일 트랜잭션으로 처리 읽어올 이벤트 범위를 지정해서 가져와 핸들러에 전달 이벤트 데이터 제공함 도메인과 같은 프로세스에서 실행해도 무방
  73. 73. 비동기 이벤트의 특징 • 이벤트생성자와 핸들 러의트랜잭션 분리 • 처리량향상 • 고객에게 빠른응답 • 구조가복잡해짐 • 재발송, 재처리등고려 사항증가 73
  74. 74. 이벤트 도입시 고려사항 • 이벤트도착순서 • 이벤트발송실패시 재발송 • 이벤트재처리 74
  75. 75. 노력 • 사고전환 • 상태의변경==이벤트 • 순차실행à이벤트+핸들러 • 트랜잭션 일관성:비동기처리+Eventually  일관성 • 기술집착버림 • 이벤트, 비동기자체에 대한이해필요 • 메시지큐가있어보이지만, 간단한기술로도 충분히구현 가능 • 이벤트+  CQRS 75
  76. 76. #5, 정리 76
  77. 77. 내용 • DIP • AGGREGATE • CQRS • 이벤트 77
  78. 78. 78 끝 최범균 |  madvirus@madvirus.net |  http://javacan.tistory.com

×