[E6]2012. netty internals

10,692 views

Published on

Published in: Technology, Education
0 Comments
25 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
10,692
On SlideShare
0
From Embeds
0
Number of Embeds
5,686
Actions
Shares
0
Downloads
184
Comments
0
Likes
25
Embeds 0
No embeds

No notes for slide

[E6]2012. netty internals

  1. 1. Netty Internals and Core Concepts이희승Twitter, Inc.
  2. 2. CONTENTS● 소개● 이벤트 모델● 스레드 모델● 테스팅● 생각할 거리
  3. 3. 소개● 네티란 ?● 구성요소 – 이벤트 루프 – 파이프라인 (BiDiCoR)
  4. 4. 네티란 ?● Java network application framework – http://netty.io/ – @netty_project● Asynchronous & event-driven – High-throughput & highly concurrent connection – .. with less resources – threads, memory & CPU cycles● API as an I/O abstraction layer – Works with NIO, OIO, AIO & more without many changes● Well-defined event model & thread model● Flexible event handling with bi-directional chain of responsibility pattern● Promotes separation of concerns – I/O layer (Netty) – Protocol codec (Netty or user) – Business logic (user)
  5. 5. 구성요소 Business Logic Custom Event Handlers & Codecs User Code HTTP TCP UDP In-VM Codec Framework Event Handlers Transports Handlers I/O Abstraction – Channels, Event Loops, and Pipelines Buffers Core
  6. 6. 이벤트 루프● Similar to.. – Windows event dispatcher – Swing event loop – Reactor● 사용자의 I/O 요청을 처리 – 이벤트 루프 스레드 내에서 요청했을 경우 즉시 – 이벤트 루프 스레드 외에서 요청했을 경우 이벤트 루프의 작업 큐에 넣어 스케쥴● 외부의 자극에 반응하고 파이프라인에 알림 – 데이터를 읽어들임 – 소켓 버퍼가 꽉 찼음● 사용자가 원하는 임의 작업 실행 – One-time or periodic
  7. 7. 파이프라인● BiDiCoR – Bi-directional Chain of Responsibility pattern – Similar to Servlet filters and decorator pattern● Inbound event – 이벤트 루프가 발생시킨 이벤트 ( 소켓 연결 , 데이터 수신 등 ) – 사용자가 작성한 inbound event handler 가 수신할 수 있도록 해 줌● Outbound event – 사용자가 요청한 동작 ( 쓰기 , 읽기 일시 중단 등 ) – 사용자가 작성한 outbound event handler 가 다른 핸들러에서 요청한 동작을 가로챌 수 있도록 해 줌 – 최종적으로 이벤트 루프에 전달되어 실제 I/O 가 수행되도록 함● 예시 – [1:EvLoop] → [2:Protocol Decoder] → [3:Protocol Encoder] → [4:Business Logic] – 수신 : 1 → 2 → 4 – 송신 : 4 → 3 → 1
  8. 8. 이벤트 모델● Before, After & Considerations
  9. 9. 기존의 이벤트 모델● 이벤트 = 자바 객체 ● Is GC cheap?● 예시 – No at extreme scale – ChannelOpen (instanceof ChannelStateEvent) ● Can buffer pool beat JVMs memory allocator? – ChannelBound (instanceof ChannelStateEvent) – Think memory bandwidth took by memset – ChannelConnected (instanceof ChannelStateEvent) – Modern concurrency constructs enable close-to-native efficiency in object pooling – MessageEvent (inbound) ● Too many state events! – MessageEvent (outbound) – Open → bound → connected is an overkill in most TCP conns – ChannelDisconnected (instanceof ChannelStateEvent) – Whats interesting to user is connected. – ChannelUnbound (instanceof ChannelStateEvent) – ChannelClosed (instanceof ChannelStateEvent) ● New buffer is created on every MessageEvent. – GC pressure – User has no control over the buffer ● Heap or direct ● Bounded or unbounded ● No buffered flush – Every write is an immediate flush – Sometimes not desired
  10. 10. 새 이벤트 모델● 이벤트 = 메소드 호출 ● 상태 전이 단순화● 예시 ● 핸들러가 수신 및 송신 버퍼를 만들어 네티에게 제공하면 지속적으로 재사용 – ChannelRegistered – 버퍼 해제 시점이 명확하므로 풀링 구현 단순화 가능 – ChannelActive – 이벤트에 버퍼 정보가 없음 – InboundBufferUpdated ● Buffered flush – Flush – ChannelInactive – 버퍼에 데이터를 채운 뒤 flush 이벤트를 발생시키는 것으로 MessageEvent 대체 – ChannelUnregistered – 여러 개의 메시지를 쓴 뒤 flush 하여 시스템 콜 절약 ● 훨씬 적은 GC 빈도 – 이벤트 객체 생성 → 호출 스택 – 수신 및 송신 버퍼 ● 단점 – 이벤트 유형별로 메소드를 전부 정의해야 함 ( 코드 중복 ) – 사용자 정의 이벤트 처리 어려움 ● 별도로 UserEventTriggered 메소드 추가
  11. 11. 스레드 모델● Why is well-defined thread model necessary?
  12. 12. 잘 정의된 스레드 모델의 필요성● 프레임워크에서 사용자의 코드가 어느 스레드에서 언제 실행될 지 충분히 정확히 정의해야 함● 프레임워크가 어느 정도의 thread safety 를 사용자 코드 (e.g. 이벤트 핸들러 ) 에게 제공할 것인가 ? – 이벤트 간의 happens-before 관계 – 네티가 핸들러 메소드를 동시 실행하는 경우가 있는가 – 비동기 I/O 요청 이후에 완료 알림은 어느 스레드에서 실행되어야 하는가 – 사용자가 직접 동기화하도록 했을 때 dead lock 발생은 하지 않는가● 정확한 스레드 모델이 제시되지 않으면 사용자 코드는 방어적으로 ( 또는 부정확하게 ) 작성됨 – 불필요한 동기화 및 그에 따른 dead lock ( 또는 부족한 동기화로 인한 race condition) – 성능 저하 및 유지 보수 비용 증가● 예 : 네티의 SSL 핸들러 – LoC: 1469 → 925 (3.5 vs 4.0)
  13. 13. 네티 4 스레드 모델● 3.x 대비 이벤트 모델 개선과 함께 가장 중요하고 긍정적인 변화● 네티는 핸들러가 @Sharable 어노테이션이 붙어 있는 경우가 아니면 절대 같은 핸들러 메소드를 동시에 호출하지 않는다 . – 사용자는 자신이 작성한 핸들러 클래스의 메소드를 동기화할 필요가 없다 . – 단 , 사용자는 같은 핸들러 인스턴스를 파이프라인에 여러 번 추가할 수 없다 .● 네티가 핸들러 메소드를 호출할 때 각 호출 사이에는 happens-before 관계가 성립한다 . – 사용자는 핸들러의 멤버 변수를 volatile 로 선언할 필요가 없다 .● 이벤트루프는 항상 싱글 스레드로 실행된다 . – 핸들러 메소드는 항상 같은 스레드로부터 호출된다 .● 비동기 요청에 대한 결과 통보 (ChannelFuture) 는 이벤트 루프 스레드에서 항상 이루어진다 .
  14. 14. 테스팅● 네티 유저의 테스트● 네티 자체의 테스트
  15. 15. 네티 유저의 테스트● 네티는 EmbeddedChannel 이라 불리는 Channel 구현을 제공● 사용자는 자신이 작성한 핸들러를 EmbeddedChannel 의 파이프라인에 추가하고 이벤트를 임의로 발생시켜 테스트 @Test public void testLineProtocol() { EmbeddedByteChannel ch = new EmbeddedByteChannel(new LineDecoder()); // Ordinary input ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { A })); assertNull(ch.readInbound()); ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { B })); assertNull(ch.readInbound()); ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { C })); assertNull(ch.readInbound()); ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { n })); assertEquals(Unpooled.wrappedBuffer(new byte[] { A, B, C }), ch.readInbound()); // Truncated input ch.writeInbound(Unpooled.wrappedBuffer(new byte[] { A })); assertNull(ch.readInbound()); ch.close(); assertNull(ch.readInbound()); }
  16. 16. 네티 자체의 테스트● 각 트랜스포트의 정확한 동작을 확인하기 위해 모든 트랜스포트 조합과 주요 프로토콜 조합에 대해 교차 테스트 수행 – TCP: NIO x AIO x OIO = 9 – 1 (OIO x OIO) – UDP: NIO x OIO = 4 – 프로토콜 : Echo, SSL, SPDY = 3 * TCP (8) = 24● 자체 제공 핸들러의 경우는 EmbeddedChannel 을 이용● 기타 – Jenkins – Animal Sniffer: Build fails on violation before packaging – Checkstyle: Build fails on violation before compilation
  17. 17. 생각할 거리● Dynamic event routing● Statistical Distributed Performance Analysis on Mesos Cluster● Management and Monitoring● Native Transport● Scalable Community
  18. 18. 유용할만한 곳● 공식 자료 – 홈페이지 - http://netty.io/ – 4.0 변경 사항 모음 - http://goo.gl/E2BJ2● 커뮤니티 자료 – 블로그 모음 - http://goo.gl/2iMKP – 스택오버플로 - http://stackoverflow.com/questions/tagged/netty● 네티 프로젝트 트위터 계정 – https://twitter.com/netty_project● 네티 한국어 이용자 모임 – https://groups.google.com/forum/#!forum/netty-ko

×