• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Startup +OpenSource Engineering
 

Startup +OpenSource Engineering

on

  • 4,437 views

- 스타트업에게 해주고 싶은 말들

- 스타트업에게 해주고 싶은 말들
- URQA 만든 이야기
- Rabbit MQ 라는 영웅을 만나다.
- Xitrum

Statistics

Views

Total Views
4,437
Views on SlideShare
1,898
Embed Views
2,539

Actions

Likes
27
Downloads
93
Comments
0

14 Embeds 2,539

http://arload.wordpress.com 2230
http://blog.studioego.info 141
http://www.hanrss.com 61
http://feedly.com 41
https://arload.wordpress.com 22
http://plus.url.google.com 21
http://localhost 6
https://twitter.com 6
https://tradeweapon.atlassian.net 4
http://studioego.tistory.com 2
http://www.google.co.kr 2
http://www.slideee.com 1
https://reader.aol.com 1
http://ko.wordpress.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • http://blog.daum.net/linguistics/8
  • Nodejs, wcf,기타 등등..

Startup +OpenSource Engineering Startup +OpenSource Engineering Presentation Transcript

  • (Startup
  •   +
  •   Open
  •   Source)
  •   
  •    Engineering
  •   
  •    with
  •   URQA
  •    김현종   손영수   황학범  
  • 오늘
  •   다루고자
  •   하는
  •   것들.
  •    처음
  •   스타트업을
  •   하는
  •   분들에게..
  •    
  •    URQA
  •   로
  •   보는
  •   최소
  •   가치
  •   찾는
  •   방법
  •    Rabit
  •   MQ
  •   -
  •   부하를
  •   커버하는
  •   또다른
  •   방식
  •    Xitrum
  •   -
  •   Danjgo
  •   /
  •   Rails를
  •   쓰신
  •   분들의
  •   고통을
  •   흡수
  •    
  •    배포
  •   구조
  •   
  •    맺음
  •   
  • Part
  •   I.
  •   
  •    처음
  •   스타트업을
  •   하는
  •   분들에게.
  •   
  • 이야기
  •   1.
  •   이런
  •   개발
  •   마인드
  •   조심!!
  •    고객
  •    고객
  •   몰라
  •   개발자
  •   
  • 잘못된
  •   개발
  •   편향적인
  •   마인드
  •    •  높은
  •   커버리지를
  •   보이는
  •   Test
  •   Unit들
  •    •  오염지표가
  •   하나도
  •   없는
  •   Software
  •    Architecture
  •    •  전문
  •   QA
  •   팀
  •    
  •   
  • 
  •   1)
  •   TDD
  •   항상
  •   진리일까?
  •   
  • Joel  Spolsky  VS  Uncle  Bob   h2p://www.infoq.com/news/2009/02/spolsky-­‐ vs-­‐uncle-­‐bob    
  • 고객의
  •   요구사항이
  •   죽
  •   끓이듯이.
  •    JOEL
  •   :
  •   
  •    
  •    고객의
  •   요구사항이
  •   죽
  •   끓듯이
  •   
  •    아키텍처가
  •   바뀌었고
  •   
  •    TEST
  •   CASE가
  •   다
  •   깨졌어?
  •   
  •   
  •    
  •    TDD가
  •   맞어??
  •   
  •   
  • TDD를
  •   제대로
  •   이해는
  •   하고
  •   있냐?
  •   
  • #@!?
  •   -
  •   ??????
  •    JOEL
  •   :
  •   
  •    
  •    도대체
  •   니가
  •   말한
  •   TDD는
  •   뭐냐.
  •   
  •    
  •    테스트
  •   케이스가
  •   안깨지는
  •   TDD??
  •    
  •    그런게
  •   있긴
  •   하니.
  •   
  •   BOB을
  •   욕함..
  •   
  •   
  • 다시
  •   생각해
  •   보기
  •    •  TDD가
  •   한번도
  •   안
  •   깨진
  •   사람?
  •   
  •   
  •    –  TDD
  •   얼마나
  •   하고
  •   있나?
  •   
  •    –  TDD
  •   를
  •   하는
  •   이유
  •   VS
  •   안하는
  •   이유.
  •    •  아키텍처가
  •   변경은
  •   안
  •   일어날까요?
  •    •  스타트업에서는
  •   많이
  •   일어납니다.
  •   
  • 스타트업과 TDD??   PRODUCT가 3년에 4번 바뀌었음..  
  • QUICK
  •   &
  •   DIRTY
  •    PROCESS   QUALITY   CONTENT  
  • 2)
  •   QA
  •   전문팀이
  •   없는
  •   Software
  •   
  • Startup
  •   에서
  •   상황
  •   (1인
  •   3역)
  •    기획
  •    QA
  •    개발
  •   
  • ???   고객에게
  •   팔리지
  •   않는
  •   소프트웨어
  •   인데
  •    •  QA
  •   
  •   전문팀이
  •   있으며,
  •   
  •    •  아키텍처가
  •   견고하며
  •    •  TDD
  •   도
  •   잘
  •   했다면..
  •    좋은
  •   소프트웨어
  •   일까요?
  •   
  • 3)
  •   .한국형
  •   우물에
  •   갇힌
  •   스타트업
  •   
  • Hybrid
  •   App의
  •   시대??
  •   
  • 왜
  •   한국만??
  •    2012
  •   세계
  •   인터넷
  •   속도
  •   순위
  •   -
  •    http://bit.ly/1fPuIFG
  •   
  •   
  •   
  • 미국에서
  •   네비게이션
  •   경험
  •   
  • 한국에서 아시아나 앱  
  • 중국에서는 CSS  공부를 하실수 있어요!  
  • 4)
  •   오픈
  •   소스를
  •   배우세요
  •   
  • 흔한
  •   안드로이드
  •   앱
  •   -
  •   Facebook
  •   
  • 오픈
  •   소스
  •   10개는
  •   써야.
  •   
  •    그나마
  •   쓸만한
  •   앱을
  •   만들수
  •   있어요.
  •                 
  • Part
  •   2.
  •   
  •    
  •    URQA
  •   이야기
  •   
  •   
  • URQA  Commi2ers  
  • 안드로이드
  •   마켓
  •   개발자
  •   현황
  •    73%
  •    개인
  •   개발자:
  •    무료  어플리케이션   유료  어플리케이션   회사,   734,   25%   회사,   957,   31%   개인,   2125,   69%   개인,   2235,   75%  
  • 50% 이상이 앱이 죽거나 멈추거나 느려지는 문제를 겪는다. 출처 :  h2p://offers2.compuware.com/rs/compuware/images/Mobile_App_Survey_Report.pdf  
  • 출처 :  h2p://offers2.compuware.com/rs/compuware/images/Mobile_App_Survey_Report.pdf  
  • 사후
  •   크래쉬
  •   리포트
  •   서비스로
  •   
  •    그나마
  •   다양한
  •   문제를
  •   대처할수
  •   있음
  •   
  • 2013년
  •   Play
  •   마켓
  •   앱
  •   개수
  •   
  •    전체
  •   앱
  •   중
  •   Bug
  •   report를
  •   사용하는
  •   앱
  •    Bugsense
  •    7%
  •    ACRA
  •    3%
  •    Others
  •    0%
  •    not
  •   use
  •    90%
  •    새로운
  •   앱
  •   중
  •   Bug
  •   report를
  •   사용하는
  •   앱
  •    BugSense
  •    14%
  •    not
  •   use
  •    81%
  •    버그리포트
  •   시장
  •   점유율
  •    ACRA
  •    3%
  •    ACRA
  •    16%
  •    Others
  •    2%
  •    BugSense
  •    77%
  •    Crittercism
  •    5%
  •    Others
  •    2%
  •   
  • 왜
  •   안쓰지?
  •   불편한가?
  •   
  • 3~7세
  •   어린이
  •   신발
  •   살때
  •   기준은?
  •    귀여운
  •   
  •    기능성
  •   
  • Pain
  •   Point
  •   
  • 비즈니스
  •   모델
  •   캔버스는
  •   창업자들이
  •   생각한
  •   가설이고,
  •    고객
  •   개발은
  •   창업자들이
  •   생각해낸
  •   해결책을
  •   검증하기
  •   보다는
  •   
  •    창업자들이
  •   가정한
  •   문제가
  •   진짜
  •   고객의
  •   문제인지
  •   검증하는
  •    것이다!
  •    
  •    
  •    Steve
  •   Blank
  •    
  •    Lean
  •   Startup의
  •   아버지
  •    Customer
  •   Development
  •   Method
  •   저자
  •   
  • 고객의
  •   
  •   문제를
  •   해결하자!
  •    =
  •    
  •   우리
  •   소프트웨어의
  •   핵심가치
  •   찾기
  •   
  • Customer
  •   
  •    Validation
  •    고객의
  •    요구사항
  •    Feedback
  •    Customer
  •   
  •    Discovery
  •   
  • Sleep
  •   If
  •   U
  •   Can
  •    
  •    
  •   
  • 기존
  •   경쟁
  •   제품의
  •   한계...
  •    사용자가
  •   앱을
  •   어떻게
  •    사용하다
  •   버그가
  •   발생
  •   
  •    하였는지
  •   알
  •   수
  •   없어
  •   
  •    
  •   Sleep
  •   If
  •   U
  •   Can
  •   개발자
  •    신재명
  •   BugSense사용
  •   중
  •    
  •    버그
  •   재현에
  •   
  •    많은
  •   시간
  •   걸림
  •   
  • 기존
  •   경쟁
  •   제품의
  •   한계...
  •    
  •   진정
  •   시급한
  •   버그가
  •   무엇인지
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   알
  •   수가
  •   없다.
  •   
  •    
  •    
  •    알람에서
  •    가장
  •    시급한
  •    버그는
  •    알람
  •    기능에서
  •    발생한
  •    버그이 다.
  •    하지만
  •    버그의
  •    발생
  •    수에
  •    가려
  •    진 짜
  •   시급한
  •   버그를
  •   노치게
  •   된다.
  •    말랑스튜디오
  •   CEO
  •    김영호
  •    BugSense사용
  •   중
  •   
  • Customer
  •   
  •    Validation
  •    Feedback
  •    고객의
  •    요구사항
  •    버그의
  •   위험
  •   정도를 
  •   판별
  •   할
  •   QA의
  •   부재
  •    Customer
  •   
  •    Discovery
  •    QA
  •   Insight
  •    가치찾기
  •   워크샵
  •   
  • QA
  •   Insight
  •    삼성전자
  •   소프트웨어QA
  •    조현길
  •   책임
  •   
  • QA
  •   Insight
  •    -
  •   QA는
  •   소프트웨어의
  •   품질을
  •   향상시키는
  •   역할
  •    
  •    -
  •   버그가
  •   발생하게되면
  •   이슈트레커를
  •   통해
  •   개발자에게
  •   버그에
  •   대한
  •   정보
  •   보고
  •    
  •    -
  •   버그가
  •   발생했을
  •   때
  •   양보다
  •   질을
  •   우선
  •   시
  •   하기
  •   위해
  •   위험도에
  •   따라
  •   등급을
  •    
  •   
  •   Crash,
  •   Critical,
  •   Major,
  •   Minor로
  •   분류
  •    
  •    -
  •   버그를
  •   재현시키는데
  •   가장
  •   많은
  •   시간을
  •   들임.
  •   
  •    
  •   
  •   재현이
  •   되지
  •   않는
  •   버그는
  •   버그로
  •   보지
  •   않음
  •    
  •    -
  •   New
  •   ->
  •   Assign
  •   ->
  •   Acknowledge
  •   ->
  •   Resolve
  •   ->
  •   Feedback
  •   과정으로
  •   버그를
  •   관리하 며
  •   대화형식으로
  •   기록을
  •   남겨둔다.
  •    
  •    -
  •   소프트웨어
  •   평가지표를
  •   도출한다.
  •    
  •    -
  •   QA는
  •   소프트웨어개발
  •   프로세스
  •   전반에
  •   관여하게
  •   된다.
  •   
  • 핵심
  •   가치
  •   찾기
  •   워크샵
  •   진행
  •   
  • 1)
  •   Purpose
  •   &
  •   Goal
  •   수립
  •   
  • 2)
  •   사야
  •   되는
  •   이유와
  •   사지
  •   않는
  •   이유를
  •   
  •    각자
  •   30개씩
  •   적고
  •   그룹화
  •   한다
  •   
  • Why
  •   &
  •   Why
  •   not
  •   Buy?
  •   
  • 3)
  •   Simple
  •   Value
  •   Proposition
  •   
  • 4)
  •   User
  •   Profiling을
  •   통한
  •   Opportunity도출
  •   
  • 작성한
  •   페르소나
  •   중
  •   
  •    우선순위가
  •   높은
  •   페르소나를
  •   선택하고
  •    키워드를
  •   그룹화
  •   
  • 5)
  •   Convergence
  •   
  • UrQA는
  •   모바일
  •   앱
  •   개발팀에게
  •   
  •    VALUE
  •    크래시를
  •   빠르게
  •   대응
  •    버그
  •   재현
  •   시간
  •   
  •   절약
  •    차별화된
  •   기술력
  •    가치를
  •   제공하는데
  •    FEATURE
  •    실시간으로
  •   에러를
  •   
  •    등급화하여
  •   리포팅
  •    사용자
  •   이벤트
  •   경로
  •    시각화
  •    C/C++
  •   네이티브
  •   
  •    크래시
  •   리포트
  •   제공 를
  •   통해서
  •   이루어
  •   진다.
  •   
  • 판단
  •   기준
  •   즉
  •   목적성이
  •   정립됨
  •   
  • 그래서
  •   나온
  •   소프트웨어
  •   
  • 버그의
  •   갯수만을
  •   강조하는
  •   View
  •   
  • 최근에러
  •   10개만
  •   보여주는
  •   데시보드
  •   
  • 아이콘과
  •   색을
  •   
  •    이용한
  •   버그의
  •   등급
  •   ,
  •   갯수표시
  •   
  • BugSense
  •   -
  •   Events
  •   View
  •    이벤트
  •   갯수만을
  •   강조하는
  •   View
  •   
  • Event
  •   Path
  •    버그를
  •   발생시킨
  •   사용자
  •   경로를
  •   
  •    시각화해서
  •   보여줌
  •    CRASH
  •   
  • BugSense
  •   -
  •   관계없는
  •   버전
  •   정보
  •    이
  •   App
  •   버전에서는
  •    어떤
  •   OS
  •   버전이
  •   문제인가?
  •    App
  •   버전과
  •   OS
  •   버전
  •    둘의
  •   관계성을
  •   파악이
  •    불가능한
  •   구조!!
  •    App
  •   업데이트가
  •   문제인가?
  •    OS
  •   버전만의
  •   문제인가?
  •   
  • OS버전
  •    App
  •   버전
  •   대비
  •   OS버전의
  •   
  •    버그
  •   발생량을
  •   보여줌
  •    앱
  •   버전
  •   
  • ACRA
  •      부족한
  •   통계자료
  •    한번에
  •   하나의
  •   통계만
  •   볼
  •   수
  •   있음...
  •   
  • 다양한 통계자료를 기간 별로   한눈에 파악 가능  
  • Bugsense,
  •   Acra
  •   
  •   
  • UrQA
  •   
  • Demo   http://www.ur-qa.com
  •   
  •   
  • UrQA
  •   Architecture
  •    UrQA
  •   Server
  •    Front
  •   end
  •    (view)
  •    Python
  •    Back
  •   end
  •    JSON
  •    Android
  •   App
  •   
  •    Restful
  •    Service
  •    (django)
  •    mysql
  •   
  • 등록된 앱은 잘 나가고..  
  • 사용자의
  •   폭주로
  •   
  •    서비스가
  •   죽었어요!!
  •   
  • To
  •   Be
  •   Architecture
  •    Front
  •   end
  •    (view)
  •    Android
  •   App
  •   
  •    Python
  •    Communicator
  •   (Json)
  •    Message
  •   queue
  •    RabbitMQ
  •    Back
  •   end
  •    Xitrum
  •    (Json
  •   parser)
  •    mysql
  •   
  • Part
  •   3.
  •   
  •   
  •    MQ
  •   Hero의
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   구하기
  •   
  •   
  • MQ가
  •   다루는
  •   Data
  •   속성
  •    
  •   One
  •   Way
  •    
  •   Read
  •   Only
  •    
  •   Write
  •   Only
  •   
  • 과부하!!
  • Message  Queue
  •    <
  •   JMS(Java  Message  System)
  •   Publisher-Subscriber
  •   방식
  •   >
  •   
  • Why
  •   MQ?
  •   
  •    
  •    
  •   
  •   
  •   비동기
  •   요청을
  •   Queuing하여
  •   
  •   
  •    
  •   
  •   Subscriber의
  •   Throughput에
  •   
  •    
  •   맞춰
  •   양을
  •   조절
  •   할
  •   수
  •   있다
  •   
  • Why
  •   MQ?
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •    
  •   부하에
  •   따라
  •   쉽게
  •   확장
  •   할
  •   수
  •   있다
  •   
  • Why
  •   MQ
  •   
  •    
  •    이질적인
  •   포멧을
  •   가진
  •   
  •    Publisher-Subscriber의
  •   데이터를
  •   
  •    변환
  •   (Marshalling,
  •   Unmarshalling)
  •   해준다.
  •   
  •   
  • Why
  •   MQ?
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •    다양한
  •   언어,
  •   
  •    프레임워크를
  •   사용하여
  •    여러
  •   응용
  •   프로그램을
  •    구축
  •   할
  •   수
  •   있다
  •   
  • To
  •   Be
  •   Architecture
  •    Front
  •   end
  •    Android
  •   App
  •   
  •    Web
  •    (View)
  •    Communicator
  •   (Json)
  •    Message
  •   queue
  •    RabbitMQ
  •    Back
  •   end
  •    Xitrum
  •    (Json
  •   parser)
  •    mysql
  •   
  • RabbitMQ
  •    •  AMQP(Advanced
  •   Message
  •   Queuing
  •   Protocol)
  •   Broker
  •    •  AMQP
  •   defines
  •   messaging
  •   protocol
  •    •  Written
  •   in
  •   Erlang
  •    •  Message
  •   routed
  •   via
  •   Exchanges
  •    •  Message
  •   Store
  •   ­–
  •   File
  •   System
  •   based
  •    
  •   
  •   
  •   (
  •   in
  •   memory
  •   +
  •   disk)
  •    
  •   
  • RabbitMQ
  •   Install
  •   (Liunx)
  •    
  •    •  sudo
  •   apt-get
  •   install
  •   rabbitmq-server
  •    •  /etc/rabbitmq/enabled_plugins
  •   
  •   파일
  •   생성
  •   
  •    
  •    •  enabled_plugins
  •   파일에
  •   
  •   [rabbitmq_management].
  •   
  •   입력
  •    
  •    •  http://localhost:15672
  •   
  •   
  •   
  •   ->
  •   (Admin
  •   Page)
  •    •  client
  •   download
  •   (java)
  •    
  •   
  •   -
  •   http://www.rabbitmq.com/java-client.htmls
  •   
  • RabbitMQ
  •   Admin
  •   
  •   
  • Exchange
  •   Type
  •   
  • Direct
  •   Exchange
  •    
  •   direct
  •   match
  •   방식
  •   
  • Topic
  •   Exchange
  •    wildcard
  •   match
  •   방식
  •   
  • Fanout
  •   Exchange
  •    Broadcast
  •   방식
  •   
  • Message
  •   flow
  •   
  • RabbitMQ
  •   Model
  •   
  •   
  • Publisher
  •    1.
  •   Classes
  •   imported
  •    
  •   
  •   
  •   
  •   import
  •   com.rabbitmq.client.ConnectionFactory;
  •   
  •    2.
  •   
  •   사용할
  •   큐
  •   이름
  •   지정
  •    
  •   
  •   
  •    import
  •   com.rabbitmq.client.Connection;
  •   
  •    
  •   
  •   
  •   
  •   i
  •   
  •   
  •   public
  •   class
  •   Send
  •   {
  •   
  •    3.
  •   Smport
  •   
  •   com.rabbitmq.client.Channel;
  •    erver
  •    연결
  •   및
  •   이벤트
  •   채널
  •   생성
  •   
  •    
  •   
  •   
  •   
  •   private
  •   final
  •   static
  •   String
  •   QUEUE_NAME
  •   =
  •   "hello";
  •   
  •    
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •    
  •   
  •   
  •   
  •   p 생성
  •    4.
  •   큐를
  •   ublic
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •   factory.setHost("localhost");
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   throws
  •   
  •   
  •   
  •   
  •   java.io.IOException
  •   {
  •   ...
  •   }
  •   
  •    channel.queueDeclare(QUEUE_NAME,false,false,
  •   false,
  •   null);
  •    
  •   Q onnection
  •   connection
  •    5.
  •   C}
  •   ueue
  •   메시지
  •   보내기
  •    =
  •   factory.newConnection();
  •   
  •    
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    String
  •   message
  •   =
  •   "Hello
  •   World!";
  •   
  •    channel.basicPublish("",
  •   QUEUE_NAME,
  •   null,message.getBytes()) System.out.println("
  •   [x]
  •   Sent
  •   '"
  •   +
  •   message
  •   +
  •   "'");
  •    channel.close();
  •   
  •    connection.close();
  •   
  • Publish
  •    import
  •   com.rabbitmq.client.ConnectionFactory;
  •    import
  •   com.rabbitmq.client.Connection;
  •    import
  •   com.rabbitmq.client.Channel;
  •    
  •    public
  •   class
  •   Send
  •   {
  •    
  •   
  •   private
  •   final
  •   static
  •   String
  •   QUEUE_NAME
  •   =
  •   "hello";
  •    
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •    
  •   
  •   
  •   
  •   
  •   
  •   throws
  •   java.io.IOException
  •   {
  •    
  •   
  •   
  •   
  •    
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •    
  •   
  •   
  •   
  •    
  •   factory.setHost("localhost");
  •    
  •   
  •   
  •   
  •    
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •    
  •   
  •   
  •   
  •    
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   channel.queueDeclare(QUEUE_NAME,
  •   false,
  •   false,
  •   false,
  •   null);
  •    
  •   
  •   
  •   
  •   
  •   
  •   String
  •   message
  •   =
  •   "Hello
  •   World!";
  •    
  •   
  •   
  •   
  •   
  •   
  •   channel.basicPublish("",
  •   QUEUE_NAME,
  •   null,
  •   message.getBytes());
  •    
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Sent
  •   '"
  •   +
  •   message
  •   +
  •   "'");
  •    
  •   
  •   }
  •    }
  •   
  • Worker
  •    
  •   (subscriber) W 1.
  •   Classes
  •   imported
  •    import
  •   com.rabbitmq.client.ConnectionFactory;
  •   
  •    2.Queue
  •   이름,
  •   서버
  •   연결,
  •   이벤트
  •   채널
  •   생성,
  •   큐
  •   생성
  •    import
  •   com.rabbitmq.client.Connection;
  •   
  •    public
  •   class
  •   Recv
  •   {
  •   
  •    import
  •   com.rabbitmq.client.Channel;
  •    3.
  •   private
  •   final
  •   static
  •   String
  •   QUEUE_NAME
  •   =
  •   "hello";
  •    Worker
  •   를
  •   이벤트채널에
  •   등록
  •    import
  •   com.rabbitmq.client.QueueingConsumer;
  •    public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    QueueingConsumer
  •   consumer
  •   =
  •   new
  •   QueueingConsumer(channel);
  •    
  •   
  •   
  •   
  •   tessage
  •   Data
  •   가져
  •   오기
  •    4.
  •   M hrows
  •   java.io.IOException,
  •   java.lang.InterruptedException
  •   {
  •   
  •    
  •   channel.basicConsume(QUEUE_NAME,
  •   true,
  •   consumer);
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •   
  •    QueueingConsumer
  •   consumer
  •   =
  •   new
  •   QueueingConsumer(channel);
  •    
  •   
  •   
  •   
  •   
  •   
  •   factory.setHost("localhost");
  •   
  •    
  •   channel.basicConsume(QUEUE_NAME,
  •   true,
  •   consumer);
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •   
  •    while
  •   (true)
  •   {
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •   
  •   
  •   
  •   
  •   QueueingConsumer.Delivery
  •   delivery
  •   =
  •   consumer.nextDelivery();
  •   
  •    channel.queueDeclare(QUEUE_NAME,
  •   false,
  •   false,
  •   false,
  •   null);
  •   
  •    
  •   
  •   
  •   
  •   
  •   String
  •   message
  •   =
  •   new
  •   String(delivery.getBody());
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [*]
  •   Waiting
  •   for
  •   messages.
  •   To
  •   exit
  •   press
  •   CTRL+C");
  •   
  •    
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Received
  •   '"
  •   +
  •   message
  •   +
  •   "'");
  •   
  •    
  •   
  •   }
  •   
  •    }
  •    }
  •   
  • Worker
  •    …⋯
  •    import
  •   com.rabbitmq.client.QueueingConsumer;
  •    public
  •   class
  •   Recv
  •   {
  •    
  •   
  •   private
  •   final
  •   static
  •   String
  •   QUEUE_NAME
  •   =
  •   "hello";
  •    
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •    
  •   
  •   
  •   
  •   
  •   
  •   throws
  •   java.io.IOException,
  •   java.lang.InterruptedException
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   factory.setHost("localhost");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •   
  •   
  •   
  •    
  •    
  •   
  •   
  •   channel.queueDeclare(QUEUE_NAME,
  •   false,
  •   false,
  •   false,
  •   null);
  •   
  •   
  •   
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   QueueingConsumer
  •   consumer
  •   =
  •   new
  •   QueueingConsumer(channel);
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicConsume(QUEUE_NAME,
  •   true,
  •   consumer);
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   while
  •   (true)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   QueueingConsumer.Delivery
  •   delivery
  •   =
  •   consumer.nextDelivery();
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   message
  •   =
  •   new
  •   String(delivery.getBody());
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Received
  •   '"
  •   +
  •   message
  •   +
  •   "'");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •    
  •   
  •   }
  •   
  • Work
  •   Queue logger W1 DB   W2 <
  •   Round-robin
  •   dispatching
  •   >
  •    W1 <
  •   Fair
  •   dispatching
  •   >
  •    W2
  • Work
  •   Queue W1 W2 <
  •   Round-robin
  •   dispatching
  •   >
  •   
  • Publish
  •    public
  •   class
  •   NewTask
  •   {
  •   
  •    private
  •   static
  •   final
  •   String
  •   TASK_QUEUE_NAME
  •   =
  •   "task_queue";
  •   
  •    
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •    
  •   
  •   
  •   throws
  •   java.io.IOException
  •   {
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •   
  •    Server
  •   연결
  •   이 
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   factory.setHost("localhost");
  •   
  •    벤트
  •   채널
  •   생성
  •   
  •    
  •   
  •   
  •   
  •    
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Channel
  •   channel
  •   =
  •   connection.createChannel(); 
  •    
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •    
  •   큐
  •   생성
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.queueDeclare(TASK_QUEUE_NAME,
  •   true,
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   false,
  •   false,
  •   null);
  •   
  •    
  •    
  •   String
  •   message
  •   =
  •   getMessage(argv);
  •   
  •    
  •   
  •   
  •   
  •    Message
  •   send
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicPublish("",
  •   TASK_QUEUE_NAME,
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   MessageProperties.PERSISTENT_TEXT_PLAIN, 
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   message.getBytes());
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Sent
  •   '"
  •   +
  •   message
  •   +
  •   "'");
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.close();
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   connection.close();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   //
  •   Something
  •   work
  •   
  •    }
  •   
  • public
  •   class
  •   Worker
  •   {
  •   
  •    private
  •   static
  •   final
  •   String
  •   TASK_QUEUE_NAME
  •   =
  •   "task_queue";
  •   
  •    
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   throws
  •   java.io.IOException,
  •   java.lang.InterruptedException
  •   {
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •   
  •    
  •   
  •    Server
  •   연결
  •   이벤
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   factory.setHost("localhost");
  •    트
  •   채널
  •   생성
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •   큐
  •   생성
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.queueDeclare(TASK_QUEUE_NAME,
  •   true,
  •   false,
  •   false,
  •   null);
  •    
  •    이벤트
  •   채널에
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   QueueingConsumer
  •   consumer
  •   =
  •   new
  •   QueueingConsumer(channel);
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicConsume(TASK_QUEUE_NAME,
  •   false,
  •   consumer);
  •   
  •    등록
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   while
  •   (true)
  •   {
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   QueueingConsumer.Delivery
  •   delivery
  •   =
  •   consumer.nextDelivery();
  •    
  •   
  •   data
  •   get
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   message
  •   =
  •   new
  •   String(delivery.getBody());
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •    
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Received
  •   '"
  •   +
  •   message
  •   +
  •   "'");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   doWork(message);
  •   
  •   //
  •   Do
  •   somthing
  •   work!
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Done"
  •   );
  •    처리
  •   완료
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicAck(delivery.getEnvelope().getDeliveryTag(),
  •   false);
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   //
  •   …⋯.
  •    
  •   
  •   
  •   }
  •    Worker
  •   
  • Work
  •   Queue W1 W2 <
  •   Fair
  •   dispatching
  •   >
  •   
  • public
  •   class
  •   NewTask
  •   {
  •   
  •    private
  •   static
  •   final
  •   String
  •   TASK_QUEUE_NAME
  •   =
  •   "task_queue";
  •   
  •    
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •    
  •   
  •   
  •   throws
  •   java.io.IOException
  •   {
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •   
  •    Server
  •   연결
  •   이벤
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   factory.setHost("localhost");
  •   
  •    
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •   
  •    트
  •   채널
  •   생성
  •    
  •    
  •    
  •    
  •   Channel
  •   channel
  •   =
  •   connection.createChannel(); 
  •    
  •    
  •    
  •   큐
  •   생성
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.queueDeclare(TASK_QUEUE_NAME,
  •   true,
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   false,
  •   false,
  •   null);
  •   
  •    Publish
  •    Fair
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicQos(1);
  •    dispatching
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •    
  •    
  •    
  •   String
  •   message
  •   =
  •   getMessage(argv);
  •   
  •    
  •   
  •   
  •   
  •    Message
  •   send
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicPublish("",
  •   TASK_QUEUE_NAME,
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   MessageProperties.PERSISTENT_TEXT_PLAIN,
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   message.getBytes());
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Sent
  •   '"
  •   +
  •   message
  •   +
  •   "'");
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.close();
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   connection.close();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   //
  •   Something
  •   work
  •   
  •    }
  •   
  • Publish/Subscribe
  •    Broadcast
  •   방식
  •    W1 Ex W2 default
  •   Exchage
  •   타입은
  •   direct
  •   타입이기
  •   때문에
  •   
  •    Exchage
  •   타입을
  •   
  •   fanout
  •   type
  •   으로
  •   지정
  •   해야
  •   
  •    한다
  •    
  •   
  • Publish
  •    public
  •   class
  •   EmitLog
  •   {
  •   
  •    
  •   private
  •   static
  •   final
  •   String
  •   EXCHANGE_NAME
  •   =
  •   "logs";
  •   
  •    
  •    
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •    
  •    
  •   throws
  •   java.io.IOException
  •   {
  •   
  •    
  •    
  •    
  •    
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •    
  •    
  •    
  •    
  •   factory.setHost("localhost");
  •   
  •    Server
  •   연결
  •   이벤 
  •    트
  •   채널
  •   생성
  •    
  •    
  •    
  •    
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •    
  •    
  •    
  •    
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •   큐
  •   생성
  •    
  •    
  •    
  •    
  •   channel.exchangeDeclare(EXCHANGE_NAME,
  •   "fanout");
  •   
  •    
  •    
  •    
  •    
  •   String
  •   message
  •   =
  •   getMessage(argv);
  •    
  •    
  •    
  •    
  •   channel.basicPublish(EXCHANGE_NAME,
  •   "",
  •   null,
  •   
  •    Message
  •   send
  •    
  •    
  •   
  •    
  •    
  •    
  •    
  •    
  •    
  •    
  •    
  •    
  •   message.getBytes());
  •    
  •    
  •    
  •    
  •   System.out.println("
  •   [x]
  •   Sent
  •   '"
  •   +
  •   message
  •   +
  •   "'");
  •   
  •    
  •    
  •    
  •    
  •   channel.close();
  •   
  •    
  •    
  •    
  •    
  •   connection.close();
  •    
  •    
  •    
  •   }
  •   //...
  •   
  •    }
  •   
  • Worker
  •    public
  •   class
  •   ReceiveLogs
  •   {
  •   
  •    
  •   private
  •   static
  •   final
  •   String
  •   EXCHANGE_NAME
  •   =
  •   "logs";
  •   
  •    
  •    
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •   
  •    
  •    
  •   
  •   
  •   
  •   
  •   throws
  •   java.io.IOException,
  •   java.lang.InterruptedException
  •   {
  •   
  •    
  •    
  •    
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •    
  •    
  •    
  •   factory.setHost("localhost");
  •   
  •    Server
  •   연결
  •   이벤 
  •    
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •   
  •    트
  •   채널
  •   생성
  •    
  •    
  •    
  •    
  •    
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •   큐
  •   생성
  •    
  •    
  •    
  •   channel.exchangeDeclare(EXCHANGE_NAME,
  •   "fanout");
  •   
  •    
  •    
  •   
  •   생성된
  •   큐의
  •   
  •    
  •    
  •   String
  •   queueName
  •   =
  •   channel.queueDeclare().getQueue();
  •    이름을
  •   가지고
  •   
  •    
  •    
  •    
  •   channel.queueBind(queueName,
  •   EXCHANGE_NAME,
  •   "");
  •   
  •    Ex에
  •   Bind
  •    
  •    
  •    
  •   System.out.println("
  •   [*]
  •   Waiting
  •   for
  •   messages.
  •   To
  •   exit
  •   press
  •   CTRL+C");
  •    
  •    
  •   QueueingConsumer
  •   consumer
  •   =
  •   new
  •   QueueingConsumer(channel);
  •    이벤트
  •   채널에
  •   
  •    등록
  •    
  •    
  •    
  •   channel.basicConsume(queueName,
  •   true,
  •   consumer);
  •   
  •    
  •    
  •    
  •   while
  •   (true)
  •   {
  •   
  •    
  •    
  •   
  •    
  •   QueueingConsumer.Delivery
  •   delivery
  •   =
  •   consumer.nextDelivery();
  •    
  •   
  •   data
  •   get
  •    String
  •   message
  •   =
  •   new
  •   String(delivery.getBody());
  •   
  •    
  •    
  •    
  •    
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Received
  •   '"
  •   +
  •   message
  •   +
  •   "'");
  •   
  •    
  •    
  •    
  •   }
  •    
  •    
  •   
  •   
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   
  •    }
  •   
  • Routing
  •    
  •   direct
  •   match
  •   방식
  •    Ex W1 W2 Exchange을
  •   통해
  •   전달
  •   되는
  •   메시지를
  •    queueBinding
  •   시에
  •   등록한
  •   routingKey를기반으로
  •    구분하여
  •   특정
  •   메시지만
  •   골라서
  •   worker가
  •   받게
  •   된다.
  •    routingKey는
  •   하나
  •   이상
  •   등록
  •   할
  •   수
  •   있다.
  •    
  •   
  • Publish
  •    public
  •   class
  •   EmitLogDirect
  •   {
  •   
  •    
  •   private
  •   static
  •   final
  •   String
  •   EXCHANGE_NAME
  •   =
  •   "direct_logs";
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   throws
  •   java.io.IOException
  •   {
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   factory.setHost("localhost");
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •   큐
  •   생성
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.exchangeDeclare(EXCHANGE_NAME,
  •   "direct");
  •    
  •   
  •   
  •   
  •    
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   routingKey
  •   =
  •   getSeverity(argv);
  •   
  •    Message
  •   
  •   를
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   message
  •   =
  •   getMessage(argv);
  •    
  •   
  •    
  •   
  •   
  •   
  •    보낼
  •   때
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicPublish(EXCHANGE_NAME,
  •   routingKey,
  •   
  •    
  •   
  •   
  •   
  •    
  •   routing
  •   Key
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   null,
  •   message.getBytes());
  •   
  •    와
  •   
  •   함께
  •   보냄
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Sent
  •   '"
  •   +
  •   severity
  •   +
  •   "':'"
  •   +
  •   message
  •   +
  •    "'");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.close();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   connection.close();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   //..
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   }
  •   
  • Worker
  •    public
  •   class
  •   ReceiveLogsDirect
  •   {
  •   
  •    
  •   
  •   
  •   private
  •   static
  •   final
  •   String
  •   EXCHANGE_NAME
  •   =
  •   "direct_logs";
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   throws
  •   java.io.IOException,
  •   java.lang.InterruptedException
  •   {
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   factory.setHost("localhost");
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •   큐
  •   생성
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.exchangeDeclare(EXCHANGE_NAME,
  •   "direct");
  •   
  •    
  •   
  •   
  •    생성
  •   된
  •   큐
  •   이름
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   queueName
  •   =
  •   channel.queueDeclare().getQueue();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   for(String
  •   routingKey:
  •   argv){
  •   
  •   
  •   
  •    Ex에
  •   Bind
  •   시
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.queueBind(queueName,
  •   EXCHANGE_NAME,routingKey)
  •    
  •    
  •   Routing
  •   Key
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   
  •    를
  •   등록
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("[*]
  •   Waiting
  •   for
  •   messages.
  •   To
  •   exit
  •   press
  •   CTRL+C");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •    이벤트
  •   채널에
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   QueueingConsumer
  •   consumer
  •   =
  •   new
  •   QueueingConsumer(channel);
  •    등록
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicConsume(queueName,
  •   true,
  •   consumer);
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   while
  •   (true)
  •   {
  •   
  •    
  •    
  •   
  •   data
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   QueueingConsumer.Delivery
  •   delivery
  •   =
  •   consumer.nextDelivery();
  •   
  •    및
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   message
  •   =
  •   new
  •   String(delivery.getBody());
  •   
  •    
  •   
  •   
  •    
  •    
  •   
  •   
  •   
  •    routing
  •   Key
  •   
  •   g
  •   et
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   routingKey
  •   =
  •   delivery.getEnvelope().getRoutingKey();
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("[x]
  •   Received
  •   '"
  •   +
  •   routingKey
  •   +
  •   "':'"
  •   +
  •   message
  •   +
  •   "'");
  •    
  •    
  •    
  •   }
  •   
  •    
  •   }
  •   
  •   
  • Topics
  •    wildcard
  •   match
  •   방식
  •    W1 Ex W2 Exchange을
  •   통해
  •   전달
  •   되는
  •   메시지를
  •    Routing
  •   Key의
  •   Pattern
  •   기반으로
  •   구분하여
  •    worker가
  •   받게
  •   된다.
  •     
  • Publish
  •    public
  •   class
  •   EmitLogTopic
  •   {
  •   
  •    
  •   
  •   
  •   private
  •   static
  •   final
  •   String
  •   EXCHANGE_NAME
  •   =
  •   "topic_logs";
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   throws
  •   Exception
  •   {
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   factory.setHost("localhost");
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •   큐
  •   생성
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.exchangeDeclare(EXCHANGE_NAME,
  •   "topic");
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   routingKey
  •   =
  •   getRouting(argv);
  •   
  •    
  •    Message
  •   를
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   message
  •   =
  •   getMessage(argv);
  •    보낼
  •   때
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicPublish(EXCHANGE_NAME,
  •   routingKey,
  •   
  •    
  •   routing
  •   Key
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   null,
  •   message.getBytes());
  •    
  •   
  •   
  •    와
  •   
  •   함께
  •   보냄
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   connection.close();
  •    
  •   
  •   
  •    
  •   
  •   
  •   
  •   
  •   }
  •   //...
  •   
  •    }
  •   
  • Worker
  •    public
  •   class
  •   ReceiveLogsTopic
  •   {
  •   
  •    
  •   
  •   
  •   
  •   private
  •   static
  •   final
  •   String
  •   EXCHANGE_NAME
  •   =
  •   "topic_logs";
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   argv)
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   throws
  •   Exception
  •   {
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   ConnectionFactory
  •   factory
  •   =
  •   new
  •   ConnectionFactory();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   factory.setHost("localhost");
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Connection
  •   connection
  •   =
  •   factory.newConnection();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Channel
  •   channel
  •   =
  •   connection.createChannel();
  •    
  •   큐
  •   생성
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.exchangeDeclare(EXCHANGE_NAME,
  •   "topic");
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   queueName
  •   =
  •   channel.queueDeclare().getQueue();
  •   
  •    Ex에
  •   Bind
  •   시
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   for(String
  •   routingKey
  •   :
  •   argv){
  •    
  •   
  •    
  •   Routing
  •   Key
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.queueBind(queueName,
  •   EXCHANGE_NAME,
  •   routingKey);
  •   
  •    를
  •   등록
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [*]
  •   Waiting
  •   for
  •   messages.
  •   To
  •   exit
  •   press
  •   CTRL+C");
  •    
  •   
  •   
  •   
  •   
  •    이벤트
  •   채널에
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   QueueingConsumer
  •   consumer
  •   =
  •   new
  •   QueueingConsumer(channel);
  •    등록
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicConsume(queueName,
  •   true,
  •   consumer);
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   while
  •   (true)
  •   {
  •   
  •    
  •   
  •   data
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   QueueingConsumer.Delivery
  •   delivery
  •   =
  •   consumer.nextDelivery();
  •   
  •    및
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   message
  •   =
  •   new
  •   String(delivery.getBody());
  •   
  •    
  •   
  •    
  •   
  •   
  •   
  •    routing
  •   Key
  •   g
  •   et
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   routingKey
  •   =
  •   delivery.getEnvelope().getRoutingKey();
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("
  •   [x]
  •   Received
  •   '"
  •   +
  •   routingKey
  •   +
  •   "':'"
  •   +
  •   message
  •   +
  •   "'");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •   
  •    }
  •   
  • RPC
  •    (Remote
  •   procedure
  •   call
  •   )
  •   
  • Server
  •    requestQueue
  •    생성
  •    이벤트
  •   채널에
  •    등록
  •    replyQueue
  •   
  •    에서
  •   받을
  •   ID를
  •    콜백
  •   큐에
  •   
  •   등록
  •   
  •    replyQueue
  •   
  •    정보와
  •   함께
  •    Message
  •   전달
  •    private
  •   static
  •   final
  •   String
  •   RPC_QUEUE_NAME
  •   =
  •   "rpc_queue";
  •    
  •    
  •    
  •    
  •   .
  •    
  •    
  •    
  •    
  •   .
  •    channel.queueDeclare(RPC_QUEUE_NAME,
  •   false,
  •   false,
  •   false,
  •   null);
  •    channel.basicQos(1);
  •    QueueingConsumer
  •   consumer
  •   =
  •   new
  •   QueueingConsumer(channel);
  •    channel.basicConsume(RPC_QUEUE_NAME,
  •   false,
  •   consumer);
  •    while
  •   (true)
  •   {
  •    
  •   QueueingConsumer.Delivery
  •   delivery
  •   =
  •   consumer.nextDelivery();
  •    
  •   BasicProperties
  •   props
  •   =
  •   delivery.getProperties();
  •    
  •   BasicProperties
  •   replyProps
  •   =
  •   new
  •   BasicProperties.Builder()
  •    
  •    
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   .correlationId(props.getCorrelationId()).build();
  •    
  •   String
  •   message
  •   =
  •   new
  •   String(delivery.getBody());
  •    
  •   
  •   int
  •   n
  •   =
  •   Integer.parseInt(message);
  •    
  •   
  •   System.out.println("
  •   [.]
  •   fib("
  •   +
  •   message
  •   +
  •   ")");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   String
  •   response
  •   =
  •   ""
  •   +
  •   fib(n);
  •    
  •   
  •   
  •   
  •   channel.basicPublish(
  •   "",
  •   props.getReplyTo(),
  •   replyProps,
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   response.getBytes());
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   channel.basicAck(delivery.getEnvelope().getDeliveryTag(),
  •   false);
  •    
  •   
  •   
  •   
  •   
  •   
  •   }
  •    16
  •   
  • Client
  •    replyQueue
  •    생성
  •    이벤트
  •   채널에
  •    등록
  •    replyQueue
  •   
  •    정보와
  •   함께
  •    Message
  •   전달
  •    
  •   
  •   data
  •   get
  •    private
  •   String
  •   requestQueueName
  •   =
  •   "rpc_queue";
  •    public
  •   RPCClient()
  •   throws
  •   Exception
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   .
  •    
  •   replyQueueName
  •   =
  •   channel.queueDeclare().getQueue();
  •   
  •    
  •   consumer
  •   =
  •   new
  •   QueueingConsumer(channel);
  •    
  •   channel.basicConsume(replyQueueName,
  •   true,
  •   consumer);
  •    }
  •    public
  •   String
  •   call(String
  •   message)
  •   throws
  •   Exception
  •   {
  •   
  •   
  •   
  •   
  •   
  •    
  •    
  •   String
  •   response
  •   =
  •   null;
  •    
  •    
  •   String
  •   corrId
  •   =
  •   java.util.UUID.randomUUID().toString();
  •    
  •    
  •   BasicProperties
  •   props
  •   =
  •   new
  •   BasicProperties.Builder()
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   .correlationId(corrId).replyTo(replyQueueName).build();
  •    
  •    
  •   channel.basicPublish("",
  •   requestQueueName,
  •   props,
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   message.getBytes()); 
  •   while
  •   (true)
  •   {
  •    
  •    
  •   QueueingConsumer.Delivery
  •   delivery
  •   =
  •   consumer.nextDelivery();
  •    
  •    
  •   if
  •   (delivery.getProperties().getCorrelationId().equals(corrId))
  •   {
  •    
  •    
  •    
  •   response
  •   =
  •   new
  •   String(delivery.getBody());
  •    
  •    
  •    
  •   break;
  •    
  •   }
  •    
  •   
  •   
  •   
  •   }
  •    
  •    
  •   return
  •   response;
  •   
  •   
  • Worker가
  •   메세지를
  •   씹으면..
  •   L
  •    
  •   메시지
  •   처리
  •   중에
  •   오류가
  •   발생한다면!!!
  •    이
  •   메시지는
  •   복구
  •   될
  •   수가
  •   없게
  •   된다!!
  •    
  •   
  •    Publisher
  •    
  •    Worker
  •    Error!
  •   
  •    Worker
  •   
  • 
  •    해결책은
  •   autoAck=false로
  •   하고
  •    Worker가
  •   작업이
  •   끝난후에
  •   ack을
  •   전달하면
  •   된다.
  •    
  •    
  •    Worker
  •    
  •   
  •    Publisher
  •    
  •    Worker
  •      QueueingConsumer  consumer  =  new  QueueingConsumer(channel);            boolean  autoAck  =  false;            channel.basicConsumer("hello",  autoAck,  consumer);                       while  (true)  {  QueueingConsumer.Delivery  delivery  =  consumer.nextDelivery();              //  something  work..                channel.basicAck(delivery.getEnvelope().getDeliveryTag(),  false);              }
  • MQ가
  •   죽으면..
  •   
  •   
  •   
  •   L
  •    Server가
  •   종료(다운)되더라도
  •   서버에
  •   보관되어
  •   있던
  •    메시지가
  •   소실되지
  •   않게
  •   하는
  •   방법은??
  •    
  •    Worker
  •    
  •   
  •    Publisher
  •    
  •    Server
  •   Down!!
  •    Worker
  •   
  • Channel.queueDelcare  호출시 “durable”  속성을 true로 해주면 메시지가
  •   소실되지
  •   않게
  •   된다.
  •    
  •    Worker
  •    
  •   
  •    Publisher
  •    
  •    Server
  •   Down!!
  •             boolean  durable  =  true;          channel.queueDeclare("hello",  durable,  false,  false,  null); Worker
  •   
  • Message
  •   Queue
  •   사용
  •   추이
  •    <
  •   2014년
  •   1월
  •   
  •   Google
  •   Trends
  •   자료
  •   >
  •    rabbitmq
  •    activemq
  •    qpid
  •    hometq
  •   
  • Part
  •   3.
  •   Message
  •   Queue
  •   정리
  •                                  •  부하에
  •   따라
  •   쉽게
  •   확장
  •   할
  •   수
  •   있다
  •   
  •    •  비동기
  •   요청을
  •   Queuing,
  •   Subscriber의
  •    Throughput에
  •   맞춰
  •   양을
  •   조절
  •   할수
  •   있다
  •   
  • Part
  •   4.
  •   
  •    슈퍼
  •   영웅
  •   -
  •   Xitrum
  •   
  • To
  •   Be
  •   Architecture
  •    Front
  •   end
  •    Web
  •    (View)
  •    Android
  •   App
  •   
  •    Communicator
  •   (Json)
  •    Message
  •   queue
  •    RabbitMQ
  •    Back
  •   end
  •    Xitrum
  •    (Json
  •   parser)
  •    mysql
  •   
  • 갑자기
  •   증가하는
  •   사용자
  •    Ideal
  • 현재상황..
  •    Django  +  python MySQL
  • 앞으로
  •   가야할
  •   상황..
  •    Load  Balancer REST Mysql REST Maria Scalability
  •    REST Mongo 변하는
  •   요구조건
  •    …
  • 성능 향상이 필요한데..
  • 네티?
  •    h2p://www.techempower.com
  • 초당 5만건???
  • 비록 Hello  World  테스트. 하지 만..
  • Ne2y로 결정!!! Ne2y   100   PLAY   SPRING   20.1   8.3   Djaing   2.8   Rails   1.7  
  • 어디서부터.....
  •   
  •   시작하지?
  •   
  • Reference 빠른개발 Rails,
  •   Django
  •    Play
  •    framework
  •    spring
  •    학습문제 성능
  • 다수가
  •   추천하는
  •   SPRING
  •   결정!!
  •   
  • SPRING?
  •    설정?
  •    서블릿? 개발?
  •    Eclipse?
  • 그래
  •   공부하자!!
  •    
  •    자바,
  •   서블릿,스트럿츠,스프링,
  •    
  •    하이버네이트,
  •   myBatis,
  •    
  •    클래스 API문서
  •   
  •    
  •    
  •    Eclipse
  •   설치하고…⋯
  •    Plugin
  •   깔고…⋯
  • 언제
  •   다
  •   해?
  •   -개발자가
  •   부족해요
  •    서비스 나오는데 최소 한달…⋯
  • 빠르고 가볍게 안될 까?
  • 성능도 고려하고
  • 학습곡선이 적은.  
  • PLAY  Framework으로 해보자!!
  • 좋은점 자바,  서블릿,스트럿츠,스프링,myBans       안배워도 됨.     안 좋은점     자바,  서블릿,스트럿츠,스프링,myBans       나중에는 배워야 됨.
  • 친숙한
  •   MVC
  •    models
  •   은
  •   모델
  •   정의와
  •   관련한
  •   소스
  •   코드를
  •   포함하고,
  •   
  •    controllers는
  •   비즈니스
  •   로직
  •   관련
  •   소스가
  •   위치한다.
  •   
  •    views
  •   는
  •   HTML과
  •   플레이
  •   템플릿
  •   언어
  •   기반
  •   소스
  •   코드를
  •   포함한다.
  •    
  •    
  •   
  • 깔끔한
  •   
  •   구조
  •   
  • Ne2y  +  Akka
  • 모두가 행복함.. 빠른 프로토 타입핑.
  •    
  •    짧은 개발주기 가장 보편적 기술의 도입.
  •    
  •    모바일과 웹을 동시에 지원 가능한 서비스 설계 Scale
  •   out
  •   고려한 설계 클라우드 고려한 설계
  • 나만 빼고….
  • 과연
  •   내가?
  •   
  • PLAY가 맘에 들긴 하는데.. 기본적인 구조는 play와 비슷하게
  •    
  •    필요한 부분만 사용할수 없을까?
  •    
  •   
  • 옮겨가기 쉽다
  • 우리는 스타트업 이랍니다 What
  •   Programming
  •   Languages
  •   Are
  •   Technology
  •   Startups
  •   Using?
  •    http://iseld.org/blog/2013/12/13/what-programming-languages-are-technology-startups-using/
  •   
  • 집근처
  •   마트를
  •   가는데?
  •    자전거 네비게이션,
  •    방수백,
  •    헤드라이트
  •    
  •    다른 기능은 필요없음..
  • 꼭
  •   필요한
  •   기능에.
  •   
  • 추가기능은
  •   이정도만.
  •    Session
  •   &
  •   Cookie
  •   암호화
  •    
  •    쉬운 Route
  •   설정
  •    
  •    기능별 배포가 가능한가?
  •    
  •    여러 DB에 동시 작업이 가능한가?
  •    
  •    멀티 뷰 대응
  •    
  •    
  •    
  •    
  •   
  • Xitrum?
  •    http://ngocdaothanh.github.io/xitrum/
  • 추가기능은
  •   이정도만.
  •    Session
  •   &
  •   Cookie
  •   암호화 
  •    
  •   
  •    
  •   
  •   
  •   
  •    Hazelcast
  •   (In
  •   Momory
  •   DataGrid
  •   )
  •   로
  •   되어있음
  •    
  •    쉬운 Route
  •   설정
  •    
  •    기능별 배포가 쉬운가?
  •    
  •    여러 DB에 동시 작업이 가능한가?
  •    
  •    멀티 뷰 대응
  •    
  •    
  •    
  •    
  •   
  • 추가기능은
  •   이정도만.
  •    Session
  •   &
  •   Cookie
  •   암호화
  •    
  •    쉬운 Route
  •   설정
  •    
  •    실행될
  •   Method
  •   앞에
  •   @anotation만
  •   달면
  •   됨.
  •    
  •    설정파일
  •   X
  •    
  •    
  •    기능별 배포가 쉬운가?
  •    
  •    여러 DB에 동시 작업이 가능한가?
  •    
  •    멀티 뷰 대응
  •    
  •    
  •    
  •    
  •   
  • 추가기능은
  •   이정도만.
  •    Session
  •   &
  •   Cookie
  •   암호화
  •    
  •    쉬운 Route
  •   설정
  •    
  •    기능별 배포가 쉬운가?
  •    
  •    하나의
  •   파일에
  •   Route,
  •   Control,
  •   Model,
  •   View
  •   전부
  •   가능
  •    
  •    모듈별로
  •   묶어서
  •   배포하면
  •   끝!!
  •    
  •    
  •    여러 DB에 동시 작업이 가능한가?
  •    
  •    쉬운 scalability/throughput   
  •    멀티 뷰 대응
  •    
  •    
  •    
  •    
  •   
  • 추가기능은
  •   이정도만.
  •    Session
  •   &
  •   Cookie
  •   암호화
  •    
  •    쉬운 Route
  •   설정
  •    
  •    기능별 배포가 쉬운가?
  •    
  •    여러 DB에 동시 작업이 가능한가?
  •    
  •    Multi
  •   DB,
  •   ORM
  •   지원
  •    
  •    
  •    멀티 뷰 대응
  •    
  •    
  •    
  •    
  •   
  • 꼭
  •   필요한
  •   기능만.
  •    멀티 뷰 대응
  •    
  •    •
  •   respondView:
  •   responds
  •   view
  •   template
  •   with
  •   or
  •   without
  •   layout
  •    •
  •   respondInlineView:
  •   responds
  •   with
  •   or
  •   without
  •   layout
  •    •
  •   respondText("hello"):
  •   responds
  •   a
  •   string
  •   without
  •   layout
  •    •
  •   respondHtml("<html>...</html>"):
  •   same
  •   as
  •   above,
  •   with
  •   content
  •   type
  •    set
  •   to
  •   “text/html”
  •   
  •    •
  •   respondJson(List(1,
  •   2,
  •   3)):
  •   converts
  •   Scala
  •   object
  •   to
  •   JSON
  •   object
  •    then
  •   responds
  •    •
  •   respondJs("myFunction([1,
  •   2,
  •   3])")
  •    •
  •   respondJsonP(List(1,
  •   2,
  •   3),
  •   "myFunction"):
  •   combination
  •   of
  •   the
  •    above
  •   two
  •    •
  •   respondJsonText("[1,
  •   2,
  •   3]")
  •    •
  •   respondJsonPText("[1,
  •   2,
  •   3]",
  •   "myFunction")
  •    •
  •   respondBinary:
  •   responds
  •   an
  •   array
  •   of
  •   bytes
  •    •
  •   respondFile:
  •   sends
  •   a
  •   file
  •   directly
  •   from
  •   disk,
  •   very
  •   fast
  •   because
  •   zerocopy
  •   (aka
  •   send-file)
  •   is
  •   used
  •   
  •    •
  •   respondEventSource("data",
  •   "event")
  •   
  • 기왕이면
  •   
  •    API
  •   문서도
  •        swagger를 이용한
  •    쉬운 문서화
  • Request   (Inbound) Response   (Outbound) HandlerEnv Netty From
  •   Netty Akka To
  •   Netty
  • Composite Request
  •    (Inbound) Response
  •    (Outbound) Auth Json Parse XML Uri File Akka Resource Resource Cache
  • Request   (Inbound) Adobe  Flash  policy     file  can  be  served  on     the  same  port  with   HTTP Response   (Outbound) ServerSsl H2pResponseEncoder H2pRequestDecoder ChunkedWrite Request2Env To  make  Xitrum     HandlerEnv FlashSocketPolicy Env2Response NoPipelining SetCORS BaseUrlRemover OPTIONSResponse BasicAuth FixiOS6SafariPOST PublicFileServer XSendFile PublicResourceServer XSendResource UriParser ResponseCacher These  4  handlers  are   provided  by  Ne2y To     FullH2pResponse Shortcut  may     happen   (acnon  is  not  called) MethodOverrider Dispatcher BadClientSilencer HANDLER
  •   ARCHITECTURE
  •    BASED
  •   ON
  •   NETTY
  •   4
  • SUPER RESTFul API
  • EXAMPLE REST
  •   API를
  •   이용한
  •   Blog
  •   만들기-
  •   Xitrum../
  •   demos/action/Articles.scala
  •    
  •    
  •    Routes
  •   설정
  •    
  •    @GET("articles")
  •    @GET("articles/:id<[0-9]+>")
  •    @GET("articles/new")
  •    @GET("articles/:id/edit")
  •    
  •    @POST("articles")
  •    @PATCH("articles/:id")
  •    @DELETE("articles/:id")
  •   
  • MODEL 
  •    
  •    case
  •   class
  •   Article(id:
  •   Int
  •   =
  •   0,
  •   title:
  •   String
  •   =
  •   "",
  •   content:
  •   String
  •   =
  •   "")
  •    
  •    object
  •   Article
  •   {
  •   
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   var
  •   storage
  •   =
  •   Map[Int,
  •   Article]()
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   var
  •   nextId
  •   
  •   =
  •   1
  •    
  •    def
  •   findAll()
  •   =
  •   storage.values
  •   
  •   
  •   
  •   
  •   
  •   전체검색
  •    def
  •   find(id:
  •   Int)
  •   =
  •   storage(id)
  •   
  •   
  •   
  •   
  •   
  •   
  •   ID로 검색
  •    def
  •   insert(article:
  •   Article)
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   저장
  •    def
  •   update(article:
  •   Article)
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   수정
  •    def
  •   delete(id:
  •   Int)
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   삭제
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  • ROUTE별 실행 명령 
  •    @GET("articles")
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   -
  •   
  •   
  •   전체조회
  •    Class
  •   Getarticles
  •   extends
  •   Api
  •   {
  •    ..
  •    val
  •   articles
  •   =
  •   Article.findAll()
  •    
  •    
  •    @GET("articles/:id<[0-9]+>")
  •   
  •   
  •   
  •   
  •   
  •   -
  •   ID를 파라미터로 조회
  •    val
  •   id
  •   
  •   
  •   
  •   
  •   
  •   =
  •   param[Int]("id")
  •   
  •   -
  •   Param
  •   Keyword
  •   
  •   
  •    var
  •   article
  •   =
  •   Article.find(id)
  •    
  •    @GET("articles/new")
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   -
  •   새로운 글 작성
  •    val
  •   article
  •   =
  •   new
  •   Article()
  •    
  •    @POST("articles")
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   -
  •   저장
  •    
  •   val
  •   title
  •   
  •   
  •   =
  •   param("title")
  •   
  •   
  •   
  •   
  •    val
  •   content
  •   =
  •   param("content")
  •   
  •   
  •   
  •   
  •    val
  •   article
  •   =
  •   Article(title
  •   =
  •   title,
  •   content
  •   =
  •   content)
  •    val
  •   id
  •   =
  •   Article.insert(article)
  • ROUTE별 실행 명령 
  •    @PATCH("articles/:id")
  •   -
  •   
  •   
  •   수정
  •    
  •   val
  •   id
  •   
  •   
  •   
  •   
  •   
  •   =
  •   param[Int]("id")
  •   
  •   
  •   
  •   
  •    val
  •   title
  •   
  •   
  •   =
  •   param("title")
  •   
  •   
  •   
  •    
  •   val
  •   content
  •   =
  •   param("content")
  •    val
  •   articles
  •   =
  •   Article.updatel(article)
  •    
  •    
  •    @DELETE("articles/:id")
  •   -
  •   
  •   
  •   삭제
  •    val
  •   id
  •   
  •   
  •   
  •   
  •   
  •   =
  •   param[Int]("id")
  •   
  •   -
  •   Param
  •   Keyword
  •   
  •   
  •    var
  •   article
  •   =
  •   Article.delete(id)
  •    
  •   
  • Part
  •   4.
  •   
  •   Xitrum
  •   정리
  •      Xitrum
  •   은 Play
  •   framework
  •   과 비슷하다.
  •    
  •    하지만 조금더 Rails나 Django
  •   사용자의 접근이 편하다
  •    
  •    Customizing이 편리
  •    
  •    다양한 응답에 대응하기 쉽다.
  •    
  •    성능을 고려한다면?
  •    
  •    학습곡선?
  •       
  • PART
  •   5.
  •   
  •    어떻게
  •   실제
  •   배포하나..
  •   
  •   
  • UrQA  To-­‐Be  Deployment  Architecture  
  • Reactor  –  select  ,  epoll  
  • Proactor  –  IOCP  
  • Average  CPU  Usage  per  Core  %  
  • Akka  Style   
  •    Reactor
  •   +
  •   Proactor
  •   Style
  •   
  • Akka 동작원리  
  • Akka  Policy  
  • AKKA
  •   동작
  •   원리
  •   
  • Dispatcher  
  • Pinned  Dispatcher  
  • Balancing  Dispatcher  
  • Router  
  • Custom  Router  
  • 성능 평가 데이터  
  • 성능
  •   평가
  •   (4
  •   cpu
  •   ­–
  •   4
  •   actor)
  •   
  • 실험
  •   결과
  •   
  • 성능평가 (4  cpu  –  10  actor)  
  • 실험
  •   결과
  •   
  • Akka    
  • Sharding   MySql   MySql   MySql  
  • Replica  Set  
  • UrQA  To-­‐Be  Deployment  Architecture  
  • 전체
  •   정리
  •    •  •  •  •  •  •  스타트업 개발자로 갖추어야 할 자세   최소 가치 찾기   Message  Queue를 이용한 버퍼링   Ruby,  Django  에서 넘어가기 좋은 Xitrum   AkkA  -­‐    CPU  Unlizanon을 극대화   배포  
  • 참고자료
  •   -
  •   Message
  •   Queue
  •   List
  •      •  AMQP  Homepage                    h2p://www.amqp.org/node/     •  AcnveMQ  Homepage                    h2p://acnvemq.apache.org/       •  STOMP  Protocol  Specificanon     h2p://stomp.github.com/stomp-­‐ specificanon-­‐1.2.html       •  HornetQ  homepage                    h2p://www.jboss.org.hornetq         •  RabbitMQ  support  JMS  in  the  future                 h2p://rabbitmq.1065348.n5.nabble.com/ RabbitMQ-­‐support-­‐JMS-­‐in-­‐the-­‐future-­‐ td24361.html     •  Message  Queue  Evaluanon  Notes                    h2p://wiki.secondlife.com/wiki/     •  Enabling  the  AcnveMQ  Broker  for  AMQP                    h2p://acnvemq.apache.org/amqp.html     •  Open  JMS  Homepage                    h2p://openjms.sourceforge.net/     •  Apache  Qpid  Homepage                    h2p://qpid.apache.org/     •  RabbitMQ  Homepage                    h2p://www.rabbitmq.com/     •  ZeroMQ  Homepage                    h2p://www.zeromq.org/    
  • 참고자료   •  Xitrum            h2p://ngocdaothanh.github.io/xitrum/       •  AkkA    h2p://akka.io/     •  AkkA  Actor  Thread  Unlizanon   h2p://bit.ly/1cA1VTa     •  AkkA  dispatcher   h2p://www.packtpub.com/arncle/dispatchers-­‐ routers