SlideShare a Scribd company logo
㈜EXEM 기술연구소 박종원, 장훈
01.Netty??
연혁
Adopter
Benchmark
소개 구조
특징
03.스레딩모델
Bootstrap
Pipeline
04.주요컴포넌트
ByteBuf
Future
Promise
02.Overall
소개
소개
NIO 기반 고성능 네트워크 어플리케이션 프레임워크
오픈소스
Apache License Version 2.0
https://github.com/netty/netty
연혁
학부 시절 개인 프로젝트로 Netty 개발 및 공개
아파치 디렉터리 프로젝트의 서브 프로젝트로 진행
TLP(Top Level Project)로 승급
Netty 단독 프로젝트로 변경
현재
이희승 님이 개발
네트워크를 뜻하는 ‘Net’에 친근한 이미지를 풍기기 위해 ‘ty’를 붙여서 Netty
Mina(Multi-purpose Infrastructure for Network Applications)
~ 4.1.20까지 릴리즈. 계속 진행 중
4.x.x 버전으로 가면서 대대적인 변화가 생김
1. 프로젝트 구조 변경
2. 패키지가 org.jboss.netty 에서 io.netty로 변경
3. ByteBuf의 등장
4. 고정/동적 버퍼 모두 동적 버퍼로 변경
5. Buffer Pool 제공
6. Thread model의 재정의
자세한 내용은
http://netty.io/wiki/new-and-noteworthy-in-4.0.html
3.x.x 릴리즈
Adopter
약 100여 개의 조직에서 사용 중
Benchmark
우리는왜?
java.net.* 의 API를 이용하여 Blocking 방식 또는 java.nio.*를 이용하여 Non-Blocking 방식으로 네트워킹 구현을
해도 전혀 문제가 없음
하지만 이 작업을 올바르고 안전하게(Multi Thread, 동기화 등 고려) 처리하기는 쉽지 않음
즉, Netty의 사용 이유도 다른 Framework 사용 이유와 크게 다르지 않음
‘생산성,개발편의,코드품질’
마찬가지로 Framework 학습 시간, 개발 자유도의 한계라는 단점도 존재
Netty?
Netty is an asynchronous event-driven network application framework
for rapid development of maintainable high performance protocol servers & clients
“Netty는 비동기식 event-driven 네트워크 어플리케이션 프레임워크”
구조
특징
다양한 전송 유형을 위한 통합 API – Blocking & Non-blocking
Concern을 명확하게 분리 할 수 있는 유연하고 확장 가능한 이벤트 모델 기반
커스터마이징이 가능한 스레드 모델
진정한 connectionless datagram 소켓 지원
잘 정리된 Javadoc, 유저 가이드, 예제
추가적인 Dependency가 필요 없음
더 나은 처리량, 더 낮은 대기 시간
자원 소비량 감소
불필요한 메모리 복사의 최소화
SSL/TLS, StartTLS의 완벽한 지원
Design
디자인
Easeofuse
쉬운사용
Performance
성능
Security
보안
특징
Asynchronous event-driven?
이벤트에 기반하여 요청을 비동기 처리
Reactor Pattern, EventHandler, EventListener, Future, Callback Method 등을 사용하여 구현
특징
Reactor Pattern :
동시에 서버로 들어온 Request를 처리하기 위한 Event Handling Pattern
ReactorPattern
Reactor
HandleEvents()
registerHandler(in handle)
removeHandler(in handle)
Event
Demultiplexer
select()
Event Handler
handleEvent(in type)
getHandle()
Concrete
Event Handler
handleEvent(in type)
getHandle()
Concrete
Event Handler
handleEvent(in type)
getHandle()
Handle
dispatch
handle set own
use
notify
ReactorPattern
ReactorPattern
스레딩모델
EventLoop :
연결의 수명 기간 동안 발생하는 이벤트를 처리하는 작업을 나타내는 프로그래밍 구조
스레딩모델
동시성과 네트워킹 두 가지 기본 API를 활용하여 설계
- io.netty.util.concurrent 패키지는
java.util.concurrent에 기반을 두는 스레드 실행자를 제공
- io.netty.channel 패키지는
Channel 이벤트와 인터페이스 API를 확장
<<인터페이스>>
Executor
<<인터페이스>>
ExecutorService
AbstractExecutorService
<<인터페이스>>
ScheduledExecutorService
<<인터페이스>>
EventExecutorGroup
<<인터페이스>>
EventExecutor
AbstractEventExecutor
SingleThreadEventExecutor SingleThreadEventLoop
ThreadPerChannelEventLoop
<<인터페이스>>
EventLoop
<<인터페이스>>
EventLoopGroup
java.util.concurrent
io.netty.util.concurrent
io.netty.channel
스레딩모델
1. EventLoopGroup에 다중 EventLoop 또는 단일 EventLoop 할당이 가능
2. EventLoop의 이벤트/작업 처리 순서는 FIFO 방식
3. Runnable 또는 Callable을 EventLoop로 즉시 또는 예약 실행 가능(implements ScheduledExecutorService)
4. EventLoop는 변경되지 않는 Thread 하나로 동작
5. 모든 입출력 작업과 이벤트는 EventLoop에 할당된 Thread에 의해 처리 됨
4 + 5 )
EventLoop는 변경되지 않는 Thread 하나로 동작하는데 모든 입출력 작업과 이벤트는 EventLoop에 할당된 Thread에 의해 처리
따라서 인바운드(입력)와 아웃바인드(출력) 시에 Thread간 추가적인 컨텍스트 전환이 필요가 없으며
이벤트를 처리하는 ChannelHandler간의 동기화가 필요 없음
(단, 여러 동시채널에서 ChannelHandler가 공유될 수 있는 경우는 제외 @Sharable)
스레딩모델
일반 상황처럼 ScheduledExecutorService 구현은 풀 관리 작업의 일부로 스레드가 추가로 생성되는 등의 한계점을 가지고 있으며,
이 때문에 많은 작업을 예약할 경우 병목 현상이 발생할 수 있다.
이런 경우엔 Channel의 EventLoop를 이용하는 것이 성능상의 이익을 볼 수 있음
EventLoop가 ScheduledExecutorService를 implements 하기 때문에 JDK 구현의 모든 메서드를 제공
주기적이거나주기적이지않은작업(ex,HeartBeat)은어떻게하는것이좋을까?
스레딩모델
EventLoop는 현재 실행 중인 Thread를 확인하는 절차를 거침
즉, Thread가 현재 Channel과 해당 EventLoop에 할당된 것인지 확인
호출 Thread가 EventLoop에 속하는 경우 해당 코드 블록이 실행
그렇지 않다면 작업을 예약하고 내부 Queue에 넣음
단, 수행 시간이 오래 걸리는 작업은 실행 Queue에 넣지 않아야 함
- EventLoop에 할당 된 Thread는 하나이기 때문에 수행 되는 동안 Blocking이 걸림
- 해당 문제를 해결하기 위해 ChannelPipeline의 add*(EventExecutorGroup group, …) 사용
왜 성능상의 이점이 있을까? - EventLoop의 Thread 관리 때문
스레딩모델
write() 작업은 ChannelFuture를 리턴하며 비동기로 진행이 됨
실질적인 write()는 void형이며 각각의 Channel내에 정의되어있는
unsafe(unsafe는 netty내 실제 전송을 구현하기 위해서 사용)를 사용
unsafe 내에서 java.nio.channels.SocketChannel의 write(...)를
사용하여 비동기로 동작하게 됨
* SocketChannel의 실제 구현체는
sun.nio.ch.SocketChannelImpl인데 해당 부분의 내부 구현은
native라서 어떤 방식으로 non-blocking을 구현했는지 파악이 어려움
파라미터로 짐작해보면 FileDescriptor를 가지고 처리를 하는 것 같음
잠깐!!!! write() 작업은 어떻게 진행이 될까?
스레딩모델
작업
EventLoop의
Thread인가?
작업 실행
작업 예약
true
false
Thread 비교
스레딩모델
각각의 EventLoop는 taskQueue와 scheduledTaskQueue를 가짐
addTask()는 taskQueue에 작업을 넣는 행위이고
scheduledTaskQueue().add()는 scheduledTaskQueue에 작업을 넣는 행위
EventLoop에서는 오른쪽 코드처럼 select()를 진행 후에 taskQueue에 있는 모든 작업들을 수행
그 과정에서 scheduledTaskQueue에 있는 작업 중에 처리 순서가 된 작업은 taskQueue에 offer()하여 자연스럽
게 처리가 되도록 진행
따라서 앞의 예제에서 현재 Thread가 EventLoop의 thread라면 바로 해당 EventLoop의
scheduledTaskQueue에 작업을 넣고
EventLoop의 Thread가 아니라면 scheduledTaskQueue에 넣는 행위 자체를 taskQueue에 넣고 EventLoop
가 자기자신의 scheduledTaskQueue에 넣을 수 있도록 함
예시 시나리오)
1. Channel에는 id 1번 Thread를 가지는 EventLoop를 할당
2. id 2번 Thread에서 ch.eventLoop().schedule(..)을 호출
3. schedule()에서는 현재 Thread와 EventLoop의 Thread를 비교(id 1 != id 2)
4. Thread가 다르기 때문에 EventLoop의 taskQueue에 scheduledTaskQueue에 add하는 행위를 넣음
5. EventLoop가 select()를 끝내며 자신의 taskQueue에 들어있던 scheduledTaskQueue에 add하는 행위를
수행
6. 현재 Thread와 EventLoop의 Thread가 같기 때문에(id 1 == id 1) 정상적으로 수행
앞슬라이드예제소스의이해를도울EventLoop의Task처리구조
EventLoop 내에서 select() 수행 부분
스레딩모델
- 하나의 EventLoopGroup은 하나 이상의 EventLoop를 포함
- EventLoopGroup은 Channel에 EventLoop를 할당
- 하나의 EventLoop는 수명주기 동안 하나의 Thread로 바인딩
- 하나의 Channel은 수명주기 동안 하나의 EventLoop에 등록
- 하나의 EventLoop를 하나 이상의 Channel로 할당 가능
- EventLoop가 생성 및 할당 되는 방법은 전송의 구현에 따라 다름(Blocking 또는 Non-Blocking)
Channel,Thread,EventLoop,EventLoopGroup간의관계
스레딩모델
EventLoopGroup
EventLoop Channel
EventLoop Channel
EventLoop Channel
Blocking
EventLoop
EventLoop
EventLoop
ChannelChannelChannelChannelChannelChannelChannel
ChannelChannelChannelChannelChannelChannelChannel
ChannelChannelChannelChannelChannelChannelChannel
Non-Blocking
EventLoopGroup
Bootstrap
Bootstrap
프로세스를 지정된 포트로 바인딩하거나 지정된 호스트의 지정된 포트에서 실행 중인 다른 호스트로 연결하는 등의 일을 하는
어플리케이션의 네트워크 레이어를 구성하는 컨테이너
서버부트스트랩
ServerBootstrap
지정된 포트로 바인딩
클라이언트
부트스트랩
Bootstrap
다른 호스트로 연결
Netty의 Bootstrap 구조
Bootstrap
Bootstrap ServerBootstrap
네트워크 기능 원격 호스트와 포트로 연결 로컬 포트로 바인딩
필요한 EventLoopGroup의 수 1 2
Bootstrap 비교
Bootstrap에는 EventLoopGroup이 하나만 필요하지만 ServerBootstrap에는 2개(동일한 인스턴스 가능)가 필요
Why?
Bootstrap
ServerBootstrap은 각기 다른 Channel의 두 집합을 필요로 함
1. 로컬 포트로 바인딩된 서버 자체의 수신 소켓을 나타내는 ServerChannel
2. 서버가 수락한 연결마다 하나씩 들어오는 클라이언트 연결을 처리하기 위해 생성된 모든 Channel
EventLoopGroup
EventLoop EventLoop
EventLoopGroup에
들어있는
EventLoop를 이용
ServerChannel
EventLoop
EventLoopGroup
EventLoop EventLoop
EventLoopGroup에
들어있는
EventLoop를 이용
수락된
Channel
EventLoop
새로운
연결을 수락
수락된
Channel
EventLoop
스레딩모델
스레딩모델
ServerBootstrap bind(…) ServerChannel
Parent
EventLoopGroup
EventLoop
Server
Channel
register(…)
next().register(…)
group(…)
for(;;) select()
ServerBootstrap
Acceptor
Child
EventLoopGroup
register(…)
EventLoop
Child Channel
Child Channel
next().register(…)
Accept Event
발생
스레딩모델
1. ServerBootstrap은 EventLoopGroup을 2개 사용.(같은 인스턴스여도 상관 없음)
2. port를 bind할 때 ServerChannel이 생성
3. 해당 ServerChannel은 Parent EventLoopGroup에 register()되고 Parent EventLoopGroup은 해당 채널에 EventLoop
하나를 할당
4. ServerChannel을 register()하는 과정에서 EventHandler로 ServerBootstrapAcceptor를 등록
5. 채널에 할당 된 EventLoop는 ServerChannel에서의 Event를 지속적으로 select()
Port Binding
1. bind된 포트로 새로운 연결이 발생=>Accept Event가 발생하면 ServerBootstrapAcceptor를 호출하여 처리
2. ServerBootstrapAcceptor는 ServerChannel의 Child Channel(새롭게 연결된 Channel)을 생성하여 Child
EventLoopGroup에 register()하고 EventLoopGroup은 Child Channel에 EventLoop를 할당
3. register()하는 과정에서 새로운 Child Channel을 만들어 Child EventLoopGroup의 register()를 호출한 Thread와 실제
register()를 수행할 EventLoop의 Thread가 다르기 때문에 ‘슬라이드 23’에서 설명한 과정과 동일하게 처리가 진행
4. Child EventLoopGroup에서 할당된 EventLoop는 등록된 Child Channel의 Event를 지속적으로 select(). 앞의 과정들을 반
복
Accept
스레딩모델
Channel에서 발생한 Event의 처리는 어떻게할까?
ChannelPipeline & ChannelHandler
스레딩모델
ServerBootstrap bind(…) ServerChannel
Parent
EventLoopGroup
EventLoop
Server
Channel
register(…)
next().register(…)
group(…)
for(;;) select()
ServerBootstrap
Acceptor
Child
EventLoopGroup
register(…)
EventLoop
Child Channel
next().register(…)
Accept Event
발생
Channel
Handler
Channel
Handler
Context
ChannelPipeline
Child Channel
Channel
Handler
Channel
Handler
Context
Channel
Handler
Channel
Handler
Context
Piipeline
• Channel을 통해 오가는 Inbound와 Outbound 이벤트를 가로채는 ChannelHandler
인스턴스의 체인
• 데이터와 이벤트 처리 논리의 핵심
Piipeline
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))
.option(ChannelOption.TCP_NODELAY, true)
// .option(ChannelOption.SO_SNDBUF, 65536)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// ch.pipeline().addLast(new IdleStateHandler(120, 0, 0));
ch.pipeline().addLast(new ByteBufToDgPacketDecoder());
ch.pipeline().addLast(new DgPacketHandler(DgClient.this));
ch.pipeline().addLast(new DgPacketToByteBufEncoder());
}
});
Piipeline
• Inbound Handler
• Decoder
• ByteToMessageDecoder
• Http, ProtoBuf, Spdy ...
Piipeline
public class ByteBufToDgPacketDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) {
…
switch (packetType) {
…
case DgPacket.PKT_RES_TIMESYNC:
DgPacketResTimesync dgPacketResTimesync = new DgPacketResTimesync();
dgPacketResTimesync.server_time = msg.readLong();
dgPacketResTimesync.datagather_time = msg.readLong();
dgPacket = dgPacketResTimesync;
break;
…
}
…
out.add(dgPacket);
}
Piipeline
• Outbound Handler
• Encoder
• MessageToByteEncoder
• Http, ProtoBuf, Spdy ...
Piipeline
public class DgPacketToByteBufEncoder extends MessageToByteEncoder<DgPacket>{
private final static Logger logger =
LoggerFactory.getLogger(DgPacketToByteBufEncoder.class);
@Override
protected void encode(ChannelHandlerContext ctx, DgPacket msg, ByteBuf out) throws
Exception {
msg.write(out);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws
Exception {
logger.error("[MFJ-WSMJ-00080000] DataGather packing send error", cause);
}
}
Future
• 아직 정해지진 않은 미래의 결과 값에 접근할 수 있는 Placehoder Object
• Java의 Future : 값을 얻을 때까지 blocking, 상태를 수동으로 체크
• Netty의 Future : 리스너 추가를 통해 콜백으로 받을 수 있음
ChannelFuture f = b.connect().sync();
ChannelFuture f = b.connect();
f.addListener(new ChannelFutureListener() {
@Override public void operationComplete(ChannelFuture future) … {
if(future.isSuccess()){
future.get();
}
else if(future.isCancelled()){}
}
});
Promise
• Future의 일반화, Writable Futrue
• Future : 다른데서 하는 행위 - 그 행위에 대한 실제 결과 - 미리 받은 Future - 실
제 결과를 이용한 행동
• Promise : 다른데서 하는 행위가 빠졌고 - 실제 결과를 돌려주는 타이밍을 스스로
결정 - 실제 결과를 이용한 행동
ChannelPromise p = ctx.channel().newPromise();
p.addListener(new ChannelFutureListener() {
@Override public void operationComplete(ChannelFuture future) … {
if(future.isSuccess()){
future.get();
}
}
});
p.setSuccess(); p.setFailure(new Exception(""));
JavaOIO
DISK
Process
Buffer
Buffer
Disk
Controller
JVM Kernel
JavaNIO
DISKProcess Buffer
Disk
Controller
JVM Kernel
NIOByteBuffer
• DirectBuffer로 커널버퍼를 직접 핸들링 하기 때문에 JVM 내부 버퍼로의 복사로 인한
CPU 오버헤드 감소
• 그로 인한 GC 비용 감소
ByteBuffer buf = ByteBuffer.allocate(10);
ByteBuffer directBuf = ByteBuffer.allocateDirect(10);
NettyByteBuf
• NIO ByteBuffer를 개선
• 내장 복합 버퍼 형식을 통한 투명한 제로카피 달성
• 용량을 필요에 따라 확장가능
• 읽기와 쓰기에 고유 인덱스를 적용함
• ByteBuffer의 flip() 메소드 호출 없이도 Reader와 Writer 모드를 전환할 수 있음
• 메서드 체인이 지원됨
• 참조 카운팅이 지원됨
• 풀링 지원됨(PooledByteBufAllocator를 이용하면 성능개선 및 메모리 단편화 최소화,
jemalloc이라는 고효율 메모리할당 방식을 이용)
복합버퍼
• ByteBuf를 필요에 따라 추가삭제 할 수 있음
• 복사하지 않고 하나로 묶어줌
CompositeByteBuf messageBuf = Unpooled.compositeBuffer();
ByteBuf headerBuf = ctx.alloc().directBuffer();
ByteBuf bodyBuf = ctx.alloc().directBuffer();
messageBuf.addComponent(headerBuf);
messageBuf.addComponent(bodyBuf);
for(ByteBuf buf : messageBuf){
System.out.println(buf.toString());
}
인덱스관리
읽을 수 있는 바이트폐기 가능한 바이트 기록할 수 있는 바이트
0 readerIndex writerIndex capacity
• 읽기와 쓰기에 고유 인덱스를 적용함
• ByteBuffer의 flip() 메소드 호출 없이도 Reader와 Writer 모드를 전환할 수 있음
참조카운팅
• 생성시 기본적으로 1이 올라감(retain으로 카피하는 경우 1증가)
• 마지막으로 사용하는 로직에서 해제의 책임을 가짐
• 메모리 누수를 감지할 수 있는 디버깅 JVM 옵션을 제공
ByteBuf buf = ctx.alloc().directBuffer();
buf.refCnt(); // 참조카운트 1
buf.retain(); // 참조카운트 2
buf.release(); // 참조카운트 1
ByteBuf derived = buf.duplicate(); // 참조카운트 1
ReferenceCountUtil.release(buf); // 참조카운트 0, deallocate
Netty 세미나

More Related Content

What's hot

제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [개미야 뭐하니?팀] : 투자자의 반응을 이용한 실시간 등락 예측(feat. 카프카)
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [개미야 뭐하니?팀] : 투자자의 반응을 이용한 실시간 등락 예측(feat. 카프카)제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [개미야 뭐하니?팀] : 투자자의 반응을 이용한 실시간 등락 예측(feat. 카프카)
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [개미야 뭐하니?팀] : 투자자의 반응을 이용한 실시간 등락 예측(feat. 카프카)
BOAZ Bigdata
 
NiFi 시작하기
NiFi 시작하기NiFi 시작하기
NiFi 시작하기
Byunghwa Yoon
 
Maven
MavenMaven
Network Function Virtualization - Telkomsel Perspective (SDN NFV Day ITB 2016)
Network Function Virtualization - Telkomsel Perspective (SDN NFV Day ITB 2016)Network Function Virtualization - Telkomsel Perspective (SDN NFV Day ITB 2016)
Network Function Virtualization - Telkomsel Perspective (SDN NFV Day ITB 2016)
SDNRG ITB
 
Spark 의 핵심은 무엇인가? RDD! (RDD paper review)
Spark 의 핵심은 무엇인가? RDD! (RDD paper review)Spark 의 핵심은 무엇인가? RDD! (RDD paper review)
Spark 의 핵심은 무엇인가? RDD! (RDD paper review)
Yongho Ha
 
Ansible x napalm x nso 解説・比較パネルディスカッション nso
Ansible x napalm x nso 解説・比較パネルディスカッション nsoAnsible x napalm x nso 解説・比較パネルディスカッション nso
Ansible x napalm x nso 解説・比較パネルディスカッション nso
Akira Iwamoto
 
From MVC to Component Based Architecture
From MVC to Component Based ArchitectureFrom MVC to Component Based Architecture
From MVC to Component Based Architecture
Barak Drechsler
 
分散システム第7章(前半)
分散システム第7章(前半)分散システム第7章(前半)
分散システム第7章(前半)Kenta Hattori
 
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
준철 박
 
Message Analyzer でパケット キャプチャー
Message Analyzer でパケット キャプチャーMessage Analyzer でパケット キャプチャー
Message Analyzer でパケット キャプチャー
彰 村地
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향
Young-Ho Cho
 
OpenStackを使用したGPU仮想化IaaS環境 事例紹介
OpenStackを使用したGPU仮想化IaaS環境 事例紹介OpenStackを使用したGPU仮想化IaaS環境 事例紹介
OpenStackを使用したGPU仮想化IaaS環境 事例紹介
VirtualTech Japan Inc.
 
「Googleを支える技術」の解説 2010.08.23
「Googleを支える技術」の解説 2010.08.23「Googleを支える技術」の解説 2010.08.23
「Googleを支える技術」の解説 2010.08.23
Minoru Chikamune
 
Sphinx autodoc - automated api documentation - PyCon.KR 2015
Sphinx autodoc - automated api documentation - PyCon.KR 2015Sphinx autodoc - automated api documentation - PyCon.KR 2015
Sphinx autodoc - automated api documentation - PyCon.KR 2015
Takayuki Shimizukawa
 
Theses Soutenues sous Direction et Co-Direction du Pr YOUSSFI
Theses Soutenues sous Direction et Co-Direction du Pr YOUSSFITheses Soutenues sous Direction et Co-Direction du Pr YOUSSFI
Theses Soutenues sous Direction et Co-Direction du Pr YOUSSFI
ENSET, Université Hassan II Casablanca
 
ネットワークの自動化・監視の取り組みについて #netopscoding #npstudy
ネットワークの自動化・監視の取り組みについて #netopscoding #npstudyネットワークの自動化・監視の取り組みについて #netopscoding #npstudy
ネットワークの自動化・監視の取り組みについて #netopscoding #npstudy
Yahoo!デベロッパーネットワーク
 
mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교Woo Yeong Choi
 
Kubernetes Jobによるバッチシステムのリソース最適化 / AbemaTV DevCon 2018 TrackB Session B6
Kubernetes Jobによるバッチシステムのリソース最適化 / AbemaTV DevCon 2018 TrackB Session B6Kubernetes Jobによるバッチシステムのリソース最適化 / AbemaTV DevCon 2018 TrackB Session B6
Kubernetes Jobによるバッチシステムのリソース最適化 / AbemaTV DevCon 2018 TrackB Session B6
AbemaTV, Inc.
 
20分でわかった事にするパワーマネジメント
20分でわかった事にするパワーマネジメント20分でわかった事にするパワーマネジメント
20分でわかった事にするパワーマネジメントmagoroku Yamamoto
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
Chris Ohk
 

What's hot (20)

제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [개미야 뭐하니?팀] : 투자자의 반응을 이용한 실시간 등락 예측(feat. 카프카)
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [개미야 뭐하니?팀] : 투자자의 반응을 이용한 실시간 등락 예측(feat. 카프카)제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [개미야 뭐하니?팀] : 투자자의 반응을 이용한 실시간 등락 예측(feat. 카프카)
제 15회 보아즈(BOAZ) 빅데이터 컨퍼런스 - [개미야 뭐하니?팀] : 투자자의 반응을 이용한 실시간 등락 예측(feat. 카프카)
 
NiFi 시작하기
NiFi 시작하기NiFi 시작하기
NiFi 시작하기
 
Maven
MavenMaven
Maven
 
Network Function Virtualization - Telkomsel Perspective (SDN NFV Day ITB 2016)
Network Function Virtualization - Telkomsel Perspective (SDN NFV Day ITB 2016)Network Function Virtualization - Telkomsel Perspective (SDN NFV Day ITB 2016)
Network Function Virtualization - Telkomsel Perspective (SDN NFV Day ITB 2016)
 
Spark 의 핵심은 무엇인가? RDD! (RDD paper review)
Spark 의 핵심은 무엇인가? RDD! (RDD paper review)Spark 의 핵심은 무엇인가? RDD! (RDD paper review)
Spark 의 핵심은 무엇인가? RDD! (RDD paper review)
 
Ansible x napalm x nso 解説・比較パネルディスカッション nso
Ansible x napalm x nso 解説・比較パネルディスカッション nsoAnsible x napalm x nso 解説・比較パネルディスカッション nso
Ansible x napalm x nso 解説・比較パネルディスカッション nso
 
From MVC to Component Based Architecture
From MVC to Component Based ArchitectureFrom MVC to Component Based Architecture
From MVC to Component Based Architecture
 
分散システム第7章(前半)
分散システム第7章(前半)分散システム第7章(前半)
分散システム第7章(前半)
 
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
 
Message Analyzer でパケット キャプチャー
Message Analyzer でパケット キャプチャーMessage Analyzer でパケット キャプチャー
Message Analyzer でパケット キャプチャー
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향
 
OpenStackを使用したGPU仮想化IaaS環境 事例紹介
OpenStackを使用したGPU仮想化IaaS環境 事例紹介OpenStackを使用したGPU仮想化IaaS環境 事例紹介
OpenStackを使用したGPU仮想化IaaS環境 事例紹介
 
「Googleを支える技術」の解説 2010.08.23
「Googleを支える技術」の解説 2010.08.23「Googleを支える技術」の解説 2010.08.23
「Googleを支える技術」の解説 2010.08.23
 
Sphinx autodoc - automated api documentation - PyCon.KR 2015
Sphinx autodoc - automated api documentation - PyCon.KR 2015Sphinx autodoc - automated api documentation - PyCon.KR 2015
Sphinx autodoc - automated api documentation - PyCon.KR 2015
 
Theses Soutenues sous Direction et Co-Direction du Pr YOUSSFI
Theses Soutenues sous Direction et Co-Direction du Pr YOUSSFITheses Soutenues sous Direction et Co-Direction du Pr YOUSSFI
Theses Soutenues sous Direction et Co-Direction du Pr YOUSSFI
 
ネットワークの自動化・監視の取り組みについて #netopscoding #npstudy
ネットワークの自動化・監視の取り組みについて #netopscoding #npstudyネットワークの自動化・監視の取り組みについて #netopscoding #npstudy
ネットワークの自動化・監視の取り組みについて #netopscoding #npstudy
 
mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교
 
Kubernetes Jobによるバッチシステムのリソース最適化 / AbemaTV DevCon 2018 TrackB Session B6
Kubernetes Jobによるバッチシステムのリソース最適化 / AbemaTV DevCon 2018 TrackB Session B6Kubernetes Jobによるバッチシステムのリソース最適化 / AbemaTV DevCon 2018 TrackB Session B6
Kubernetes Jobによるバッチシステムのリソース最適化 / AbemaTV DevCon 2018 TrackB Session B6
 
20分でわかった事にするパワーマネジメント
20分でわかった事にするパワーマネジメント20分でわかった事にするパワーマネジメント
20分でわかった事にするパワーマネジメント
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
 

Similar to Netty 세미나

Springmvc
SpringmvcSpringmvc
Springmvc
HyungKuIm
 
.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기
Seong Won Mun
 
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
NAVER Engineering
 
Data-binding AngularJS
Data-binding AngularJSData-binding AngularJS
Data-binding AngularJS
EunYoung Kim
 
[Hello world 오픈세미나]open api client개발
[Hello world 오픈세미나]open api client개발[Hello world 오픈세미나]open api client개발
[Hello world 오픈세미나]open api client개발NAVER D2
 
K8s beginner 2_advanced_ep02_201904221130_post
K8s beginner 2_advanced_ep02_201904221130_postK8s beginner 2_advanced_ep02_201904221130_post
K8s beginner 2_advanced_ep02_201904221130_post
Inho Kang
 
[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성
NAVER D2
 
Spring integration을 통해_살펴본_메시징_세계
Spring integration을 통해_살펴본_메시징_세계Spring integration을 통해_살펴본_메시징_세계
Spring integration을 통해_살펴본_메시징_세계
Wangeun Lee
 
Introduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&CIntroduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&Csys4u
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
Yong Joon Moon
 
Spring boot DI
Spring boot DISpring boot DI
Spring boot DI
Hyosang Hong
 
Going asynchronous with netty - SOSCON 2015
Going asynchronous with netty - SOSCON 2015Going asynchronous with netty - SOSCON 2015
Going asynchronous with netty - SOSCON 2015
Kris Jeong
 
Angular 2 rc5 조사
Angular 2 rc5 조사Angular 2 rc5 조사
Angular 2 rc5 조사
Rjs Ryu
 
Design pattern 옵저버
Design pattern 옵저버Design pattern 옵저버
Design pattern 옵저버Sukjin Yun
 
Internship backend
Internship backendInternship backend
Internship backend
Yein Sim
 
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
Chanwoong Kim
 
KT 안재석 박사 - 오픈 소스 기반 클라우드 컴퓨팅 솔루션 open stack 이야기 (2011Y05M28D)
KT 안재석 박사 - 오픈 소스 기반 클라우드 컴퓨팅 솔루션 open stack 이야기 (2011Y05M28D)KT 안재석 박사 - 오픈 소스 기반 클라우드 컴퓨팅 솔루션 open stack 이야기 (2011Y05M28D)
KT 안재석 박사 - 오픈 소스 기반 클라우드 컴퓨팅 솔루션 open stack 이야기 (2011Y05M28D)
Ubuntu Korea Community
 
V8 add on with middleware modules
V8 add on with middleware modulesV8 add on with middleware modules
V8 add on with middleware modules
Jay Kim
 
Node.js의 도입과 활용
Node.js의 도입과 활용Node.js의 도입과 활용
Node.js의 도입과 활용
Jin wook
 
Multithread pattern 소개
Multithread pattern 소개Multithread pattern 소개
Multithread pattern 소개Sunghyouk Bae
 

Similar to Netty 세미나 (20)

Springmvc
SpringmvcSpringmvc
Springmvc
 
.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기
 
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
 
Data-binding AngularJS
Data-binding AngularJSData-binding AngularJS
Data-binding AngularJS
 
[Hello world 오픈세미나]open api client개발
[Hello world 오픈세미나]open api client개발[Hello world 오픈세미나]open api client개발
[Hello world 오픈세미나]open api client개발
 
K8s beginner 2_advanced_ep02_201904221130_post
K8s beginner 2_advanced_ep02_201904221130_postK8s beginner 2_advanced_ep02_201904221130_post
K8s beginner 2_advanced_ep02_201904221130_post
 
[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성
 
Spring integration을 통해_살펴본_메시징_세계
Spring integration을 통해_살펴본_메시징_세계Spring integration을 통해_살펴본_메시징_세계
Spring integration을 통해_살펴본_메시징_세계
 
Introduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&CIntroduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&C
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
 
Spring boot DI
Spring boot DISpring boot DI
Spring boot DI
 
Going asynchronous with netty - SOSCON 2015
Going asynchronous with netty - SOSCON 2015Going asynchronous with netty - SOSCON 2015
Going asynchronous with netty - SOSCON 2015
 
Angular 2 rc5 조사
Angular 2 rc5 조사Angular 2 rc5 조사
Angular 2 rc5 조사
 
Design pattern 옵저버
Design pattern 옵저버Design pattern 옵저버
Design pattern 옵저버
 
Internship backend
Internship backendInternship backend
Internship backend
 
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
 
KT 안재석 박사 - 오픈 소스 기반 클라우드 컴퓨팅 솔루션 open stack 이야기 (2011Y05M28D)
KT 안재석 박사 - 오픈 소스 기반 클라우드 컴퓨팅 솔루션 open stack 이야기 (2011Y05M28D)KT 안재석 박사 - 오픈 소스 기반 클라우드 컴퓨팅 솔루션 open stack 이야기 (2011Y05M28D)
KT 안재석 박사 - 오픈 소스 기반 클라우드 컴퓨팅 솔루션 open stack 이야기 (2011Y05M28D)
 
V8 add on with middleware modules
V8 add on with middleware modulesV8 add on with middleware modules
V8 add on with middleware modules
 
Node.js의 도입과 활용
Node.js의 도입과 활용Node.js의 도입과 활용
Node.js의 도입과 활용
 
Multithread pattern 소개
Multithread pattern 소개Multithread pattern 소개
Multithread pattern 소개
 

More from Jang Hoon

Kubernetes forum Seoul 2019 Review
Kubernetes forum Seoul 2019 ReviewKubernetes forum Seoul 2019 Review
Kubernetes forum Seoul 2019 Review
Jang Hoon
 
Deview 2018 review
Deview 2018 reviewDeview 2018 review
Deview 2018 review
Jang Hoon
 
Aws Summit Seoul 2018
Aws Summit Seoul 2018Aws Summit Seoul 2018
Aws Summit Seoul 2018
Jang Hoon
 
jemalloc 세미나
jemalloc 세미나jemalloc 세미나
jemalloc 세미나
Jang Hoon
 
Deview 2017 review
Deview 2017 reviewDeview 2017 review
Deview 2017 review
Jang Hoon
 
AWS re:Invent 2017
AWS re:Invent 2017AWS re:Invent 2017
AWS re:Invent 2017
Jang Hoon
 
배워봅시다 머신러닝 with TensorFlow
배워봅시다 머신러닝 with TensorFlow배워봅시다 머신러닝 with TensorFlow
배워봅시다 머신러닝 with TensorFlow
Jang Hoon
 

More from Jang Hoon (7)

Kubernetes forum Seoul 2019 Review
Kubernetes forum Seoul 2019 ReviewKubernetes forum Seoul 2019 Review
Kubernetes forum Seoul 2019 Review
 
Deview 2018 review
Deview 2018 reviewDeview 2018 review
Deview 2018 review
 
Aws Summit Seoul 2018
Aws Summit Seoul 2018Aws Summit Seoul 2018
Aws Summit Seoul 2018
 
jemalloc 세미나
jemalloc 세미나jemalloc 세미나
jemalloc 세미나
 
Deview 2017 review
Deview 2017 reviewDeview 2017 review
Deview 2017 review
 
AWS re:Invent 2017
AWS re:Invent 2017AWS re:Invent 2017
AWS re:Invent 2017
 
배워봅시다 머신러닝 with TensorFlow
배워봅시다 머신러닝 with TensorFlow배워봅시다 머신러닝 with TensorFlow
배워봅시다 머신러닝 with TensorFlow
 

Netty 세미나

  • 4. 소개 NIO 기반 고성능 네트워크 어플리케이션 프레임워크 오픈소스 Apache License Version 2.0 https://github.com/netty/netty
  • 5. 연혁 학부 시절 개인 프로젝트로 Netty 개발 및 공개 아파치 디렉터리 프로젝트의 서브 프로젝트로 진행 TLP(Top Level Project)로 승급 Netty 단독 프로젝트로 변경 현재 이희승 님이 개발 네트워크를 뜻하는 ‘Net’에 친근한 이미지를 풍기기 위해 ‘ty’를 붙여서 Netty Mina(Multi-purpose Infrastructure for Network Applications) ~ 4.1.20까지 릴리즈. 계속 진행 중 4.x.x 버전으로 가면서 대대적인 변화가 생김 1. 프로젝트 구조 변경 2. 패키지가 org.jboss.netty 에서 io.netty로 변경 3. ByteBuf의 등장 4. 고정/동적 버퍼 모두 동적 버퍼로 변경 5. Buffer Pool 제공 6. Thread model의 재정의 자세한 내용은 http://netty.io/wiki/new-and-noteworthy-in-4.0.html 3.x.x 릴리즈
  • 6. Adopter 약 100여 개의 조직에서 사용 중
  • 8. 우리는왜? java.net.* 의 API를 이용하여 Blocking 방식 또는 java.nio.*를 이용하여 Non-Blocking 방식으로 네트워킹 구현을 해도 전혀 문제가 없음 하지만 이 작업을 올바르고 안전하게(Multi Thread, 동기화 등 고려) 처리하기는 쉽지 않음 즉, Netty의 사용 이유도 다른 Framework 사용 이유와 크게 다르지 않음 ‘생산성,개발편의,코드품질’ 마찬가지로 Framework 학습 시간, 개발 자유도의 한계라는 단점도 존재
  • 9. Netty? Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients “Netty는 비동기식 event-driven 네트워크 어플리케이션 프레임워크”
  • 11. 특징 다양한 전송 유형을 위한 통합 API – Blocking & Non-blocking Concern을 명확하게 분리 할 수 있는 유연하고 확장 가능한 이벤트 모델 기반 커스터마이징이 가능한 스레드 모델 진정한 connectionless datagram 소켓 지원 잘 정리된 Javadoc, 유저 가이드, 예제 추가적인 Dependency가 필요 없음 더 나은 처리량, 더 낮은 대기 시간 자원 소비량 감소 불필요한 메모리 복사의 최소화 SSL/TLS, StartTLS의 완벽한 지원 Design 디자인 Easeofuse 쉬운사용 Performance 성능 Security 보안
  • 12. 특징 Asynchronous event-driven? 이벤트에 기반하여 요청을 비동기 처리 Reactor Pattern, EventHandler, EventListener, Future, Callback Method 등을 사용하여 구현
  • 13. 특징 Reactor Pattern : 동시에 서버로 들어온 Request를 처리하기 위한 Event Handling Pattern
  • 14. ReactorPattern Reactor HandleEvents() registerHandler(in handle) removeHandler(in handle) Event Demultiplexer select() Event Handler handleEvent(in type) getHandle() Concrete Event Handler handleEvent(in type) getHandle() Concrete Event Handler handleEvent(in type) getHandle() Handle dispatch handle set own use notify
  • 17. 스레딩모델 EventLoop : 연결의 수명 기간 동안 발생하는 이벤트를 처리하는 작업을 나타내는 프로그래밍 구조
  • 18. 스레딩모델 동시성과 네트워킹 두 가지 기본 API를 활용하여 설계 - io.netty.util.concurrent 패키지는 java.util.concurrent에 기반을 두는 스레드 실행자를 제공 - io.netty.channel 패키지는 Channel 이벤트와 인터페이스 API를 확장 <<인터페이스>> Executor <<인터페이스>> ExecutorService AbstractExecutorService <<인터페이스>> ScheduledExecutorService <<인터페이스>> EventExecutorGroup <<인터페이스>> EventExecutor AbstractEventExecutor SingleThreadEventExecutor SingleThreadEventLoop ThreadPerChannelEventLoop <<인터페이스>> EventLoop <<인터페이스>> EventLoopGroup java.util.concurrent io.netty.util.concurrent io.netty.channel
  • 19. 스레딩모델 1. EventLoopGroup에 다중 EventLoop 또는 단일 EventLoop 할당이 가능 2. EventLoop의 이벤트/작업 처리 순서는 FIFO 방식 3. Runnable 또는 Callable을 EventLoop로 즉시 또는 예약 실행 가능(implements ScheduledExecutorService) 4. EventLoop는 변경되지 않는 Thread 하나로 동작 5. 모든 입출력 작업과 이벤트는 EventLoop에 할당된 Thread에 의해 처리 됨 4 + 5 ) EventLoop는 변경되지 않는 Thread 하나로 동작하는데 모든 입출력 작업과 이벤트는 EventLoop에 할당된 Thread에 의해 처리 따라서 인바운드(입력)와 아웃바인드(출력) 시에 Thread간 추가적인 컨텍스트 전환이 필요가 없으며 이벤트를 처리하는 ChannelHandler간의 동기화가 필요 없음 (단, 여러 동시채널에서 ChannelHandler가 공유될 수 있는 경우는 제외 @Sharable)
  • 20. 스레딩모델 일반 상황처럼 ScheduledExecutorService 구현은 풀 관리 작업의 일부로 스레드가 추가로 생성되는 등의 한계점을 가지고 있으며, 이 때문에 많은 작업을 예약할 경우 병목 현상이 발생할 수 있다. 이런 경우엔 Channel의 EventLoop를 이용하는 것이 성능상의 이익을 볼 수 있음 EventLoop가 ScheduledExecutorService를 implements 하기 때문에 JDK 구현의 모든 메서드를 제공 주기적이거나주기적이지않은작업(ex,HeartBeat)은어떻게하는것이좋을까?
  • 21. 스레딩모델 EventLoop는 현재 실행 중인 Thread를 확인하는 절차를 거침 즉, Thread가 현재 Channel과 해당 EventLoop에 할당된 것인지 확인 호출 Thread가 EventLoop에 속하는 경우 해당 코드 블록이 실행 그렇지 않다면 작업을 예약하고 내부 Queue에 넣음 단, 수행 시간이 오래 걸리는 작업은 실행 Queue에 넣지 않아야 함 - EventLoop에 할당 된 Thread는 하나이기 때문에 수행 되는 동안 Blocking이 걸림 - 해당 문제를 해결하기 위해 ChannelPipeline의 add*(EventExecutorGroup group, …) 사용 왜 성능상의 이점이 있을까? - EventLoop의 Thread 관리 때문
  • 22. 스레딩모델 write() 작업은 ChannelFuture를 리턴하며 비동기로 진행이 됨 실질적인 write()는 void형이며 각각의 Channel내에 정의되어있는 unsafe(unsafe는 netty내 실제 전송을 구현하기 위해서 사용)를 사용 unsafe 내에서 java.nio.channels.SocketChannel의 write(...)를 사용하여 비동기로 동작하게 됨 * SocketChannel의 실제 구현체는 sun.nio.ch.SocketChannelImpl인데 해당 부분의 내부 구현은 native라서 어떤 방식으로 non-blocking을 구현했는지 파악이 어려움 파라미터로 짐작해보면 FileDescriptor를 가지고 처리를 하는 것 같음 잠깐!!!! write() 작업은 어떻게 진행이 될까?
  • 24. 스레딩모델 각각의 EventLoop는 taskQueue와 scheduledTaskQueue를 가짐 addTask()는 taskQueue에 작업을 넣는 행위이고 scheduledTaskQueue().add()는 scheduledTaskQueue에 작업을 넣는 행위 EventLoop에서는 오른쪽 코드처럼 select()를 진행 후에 taskQueue에 있는 모든 작업들을 수행 그 과정에서 scheduledTaskQueue에 있는 작업 중에 처리 순서가 된 작업은 taskQueue에 offer()하여 자연스럽 게 처리가 되도록 진행 따라서 앞의 예제에서 현재 Thread가 EventLoop의 thread라면 바로 해당 EventLoop의 scheduledTaskQueue에 작업을 넣고 EventLoop의 Thread가 아니라면 scheduledTaskQueue에 넣는 행위 자체를 taskQueue에 넣고 EventLoop 가 자기자신의 scheduledTaskQueue에 넣을 수 있도록 함 예시 시나리오) 1. Channel에는 id 1번 Thread를 가지는 EventLoop를 할당 2. id 2번 Thread에서 ch.eventLoop().schedule(..)을 호출 3. schedule()에서는 현재 Thread와 EventLoop의 Thread를 비교(id 1 != id 2) 4. Thread가 다르기 때문에 EventLoop의 taskQueue에 scheduledTaskQueue에 add하는 행위를 넣음 5. EventLoop가 select()를 끝내며 자신의 taskQueue에 들어있던 scheduledTaskQueue에 add하는 행위를 수행 6. 현재 Thread와 EventLoop의 Thread가 같기 때문에(id 1 == id 1) 정상적으로 수행 앞슬라이드예제소스의이해를도울EventLoop의Task처리구조 EventLoop 내에서 select() 수행 부분
  • 25. 스레딩모델 - 하나의 EventLoopGroup은 하나 이상의 EventLoop를 포함 - EventLoopGroup은 Channel에 EventLoop를 할당 - 하나의 EventLoop는 수명주기 동안 하나의 Thread로 바인딩 - 하나의 Channel은 수명주기 동안 하나의 EventLoop에 등록 - 하나의 EventLoop를 하나 이상의 Channel로 할당 가능 - EventLoop가 생성 및 할당 되는 방법은 전송의 구현에 따라 다름(Blocking 또는 Non-Blocking) Channel,Thread,EventLoop,EventLoopGroup간의관계
  • 26. 스레딩모델 EventLoopGroup EventLoop Channel EventLoop Channel EventLoop Channel Blocking EventLoop EventLoop EventLoop ChannelChannelChannelChannelChannelChannelChannel ChannelChannelChannelChannelChannelChannelChannel ChannelChannelChannelChannelChannelChannelChannel Non-Blocking EventLoopGroup
  • 27. Bootstrap Bootstrap 프로세스를 지정된 포트로 바인딩하거나 지정된 호스트의 지정된 포트에서 실행 중인 다른 호스트로 연결하는 등의 일을 하는 어플리케이션의 네트워크 레이어를 구성하는 컨테이너 서버부트스트랩 ServerBootstrap 지정된 포트로 바인딩 클라이언트 부트스트랩 Bootstrap 다른 호스트로 연결 Netty의 Bootstrap 구조
  • 28. Bootstrap Bootstrap ServerBootstrap 네트워크 기능 원격 호스트와 포트로 연결 로컬 포트로 바인딩 필요한 EventLoopGroup의 수 1 2 Bootstrap 비교 Bootstrap에는 EventLoopGroup이 하나만 필요하지만 ServerBootstrap에는 2개(동일한 인스턴스 가능)가 필요 Why?
  • 29. Bootstrap ServerBootstrap은 각기 다른 Channel의 두 집합을 필요로 함 1. 로컬 포트로 바인딩된 서버 자체의 수신 소켓을 나타내는 ServerChannel 2. 서버가 수락한 연결마다 하나씩 들어오는 클라이언트 연결을 처리하기 위해 생성된 모든 Channel EventLoopGroup EventLoop EventLoop EventLoopGroup에 들어있는 EventLoop를 이용 ServerChannel EventLoop EventLoopGroup EventLoop EventLoop EventLoopGroup에 들어있는 EventLoop를 이용 수락된 Channel EventLoop 새로운 연결을 수락 수락된 Channel EventLoop
  • 31. 스레딩모델 ServerBootstrap bind(…) ServerChannel Parent EventLoopGroup EventLoop Server Channel register(…) next().register(…) group(…) for(;;) select() ServerBootstrap Acceptor Child EventLoopGroup register(…) EventLoop Child Channel Child Channel next().register(…) Accept Event 발생
  • 32. 스레딩모델 1. ServerBootstrap은 EventLoopGroup을 2개 사용.(같은 인스턴스여도 상관 없음) 2. port를 bind할 때 ServerChannel이 생성 3. 해당 ServerChannel은 Parent EventLoopGroup에 register()되고 Parent EventLoopGroup은 해당 채널에 EventLoop 하나를 할당 4. ServerChannel을 register()하는 과정에서 EventHandler로 ServerBootstrapAcceptor를 등록 5. 채널에 할당 된 EventLoop는 ServerChannel에서의 Event를 지속적으로 select() Port Binding 1. bind된 포트로 새로운 연결이 발생=>Accept Event가 발생하면 ServerBootstrapAcceptor를 호출하여 처리 2. ServerBootstrapAcceptor는 ServerChannel의 Child Channel(새롭게 연결된 Channel)을 생성하여 Child EventLoopGroup에 register()하고 EventLoopGroup은 Child Channel에 EventLoop를 할당 3. register()하는 과정에서 새로운 Child Channel을 만들어 Child EventLoopGroup의 register()를 호출한 Thread와 실제 register()를 수행할 EventLoop의 Thread가 다르기 때문에 ‘슬라이드 23’에서 설명한 과정과 동일하게 처리가 진행 4. Child EventLoopGroup에서 할당된 EventLoop는 등록된 Child Channel의 Event를 지속적으로 select(). 앞의 과정들을 반 복 Accept
  • 33. 스레딩모델 Channel에서 발생한 Event의 처리는 어떻게할까? ChannelPipeline & ChannelHandler
  • 34. 스레딩모델 ServerBootstrap bind(…) ServerChannel Parent EventLoopGroup EventLoop Server Channel register(…) next().register(…) group(…) for(;;) select() ServerBootstrap Acceptor Child EventLoopGroup register(…) EventLoop Child Channel next().register(…) Accept Event 발생 Channel Handler Channel Handler Context ChannelPipeline Child Channel Channel Handler Channel Handler Context Channel Handler Channel Handler Context
  • 35.
  • 36. Piipeline • Channel을 통해 오가는 Inbound와 Outbound 이벤트를 가로채는 ChannelHandler 인스턴스의 체인 • 데이터와 이벤트 처리 논리의 핵심
  • 37. Piipeline Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .remoteAddress(new InetSocketAddress(host, port)) .option(ChannelOption.TCP_NODELAY, true) // .option(ChannelOption.SO_SNDBUF, 65536) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { // ch.pipeline().addLast(new IdleStateHandler(120, 0, 0)); ch.pipeline().addLast(new ByteBufToDgPacketDecoder()); ch.pipeline().addLast(new DgPacketHandler(DgClient.this)); ch.pipeline().addLast(new DgPacketToByteBufEncoder()); } });
  • 38. Piipeline • Inbound Handler • Decoder • ByteToMessageDecoder • Http, ProtoBuf, Spdy ...
  • 39. Piipeline public class ByteBufToDgPacketDecoder extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) { … switch (packetType) { … case DgPacket.PKT_RES_TIMESYNC: DgPacketResTimesync dgPacketResTimesync = new DgPacketResTimesync(); dgPacketResTimesync.server_time = msg.readLong(); dgPacketResTimesync.datagather_time = msg.readLong(); dgPacket = dgPacketResTimesync; break; … } … out.add(dgPacket); }
  • 40. Piipeline • Outbound Handler • Encoder • MessageToByteEncoder • Http, ProtoBuf, Spdy ...
  • 41. Piipeline public class DgPacketToByteBufEncoder extends MessageToByteEncoder<DgPacket>{ private final static Logger logger = LoggerFactory.getLogger(DgPacketToByteBufEncoder.class); @Override protected void encode(ChannelHandlerContext ctx, DgPacket msg, ByteBuf out) throws Exception { msg.write(out); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { logger.error("[MFJ-WSMJ-00080000] DataGather packing send error", cause); } }
  • 42. Future • 아직 정해지진 않은 미래의 결과 값에 접근할 수 있는 Placehoder Object • Java의 Future : 값을 얻을 때까지 blocking, 상태를 수동으로 체크 • Netty의 Future : 리스너 추가를 통해 콜백으로 받을 수 있음 ChannelFuture f = b.connect().sync(); ChannelFuture f = b.connect(); f.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) … { if(future.isSuccess()){ future.get(); } else if(future.isCancelled()){} } });
  • 43. Promise • Future의 일반화, Writable Futrue • Future : 다른데서 하는 행위 - 그 행위에 대한 실제 결과 - 미리 받은 Future - 실 제 결과를 이용한 행동 • Promise : 다른데서 하는 행위가 빠졌고 - 실제 결과를 돌려주는 타이밍을 스스로 결정 - 실제 결과를 이용한 행동 ChannelPromise p = ctx.channel().newPromise(); p.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) … { if(future.isSuccess()){ future.get(); } } }); p.setSuccess(); p.setFailure(new Exception(""));
  • 44.
  • 47. NIOByteBuffer • DirectBuffer로 커널버퍼를 직접 핸들링 하기 때문에 JVM 내부 버퍼로의 복사로 인한 CPU 오버헤드 감소 • 그로 인한 GC 비용 감소 ByteBuffer buf = ByteBuffer.allocate(10); ByteBuffer directBuf = ByteBuffer.allocateDirect(10);
  • 48. NettyByteBuf • NIO ByteBuffer를 개선 • 내장 복합 버퍼 형식을 통한 투명한 제로카피 달성 • 용량을 필요에 따라 확장가능 • 읽기와 쓰기에 고유 인덱스를 적용함 • ByteBuffer의 flip() 메소드 호출 없이도 Reader와 Writer 모드를 전환할 수 있음 • 메서드 체인이 지원됨 • 참조 카운팅이 지원됨 • 풀링 지원됨(PooledByteBufAllocator를 이용하면 성능개선 및 메모리 단편화 최소화, jemalloc이라는 고효율 메모리할당 방식을 이용)
  • 49. 복합버퍼 • ByteBuf를 필요에 따라 추가삭제 할 수 있음 • 복사하지 않고 하나로 묶어줌 CompositeByteBuf messageBuf = Unpooled.compositeBuffer(); ByteBuf headerBuf = ctx.alloc().directBuffer(); ByteBuf bodyBuf = ctx.alloc().directBuffer(); messageBuf.addComponent(headerBuf); messageBuf.addComponent(bodyBuf); for(ByteBuf buf : messageBuf){ System.out.println(buf.toString()); }
  • 50. 인덱스관리 읽을 수 있는 바이트폐기 가능한 바이트 기록할 수 있는 바이트 0 readerIndex writerIndex capacity • 읽기와 쓰기에 고유 인덱스를 적용함 • ByteBuffer의 flip() 메소드 호출 없이도 Reader와 Writer 모드를 전환할 수 있음
  • 51. 참조카운팅 • 생성시 기본적으로 1이 올라감(retain으로 카피하는 경우 1증가) • 마지막으로 사용하는 로직에서 해제의 책임을 가짐 • 메모리 누수를 감지할 수 있는 디버깅 JVM 옵션을 제공 ByteBuf buf = ctx.alloc().directBuffer(); buf.refCnt(); // 참조카운트 1 buf.retain(); // 참조카운트 2 buf.release(); // 참조카운트 1 ByteBuf derived = buf.duplicate(); // 참조카운트 1 ReferenceCountUtil.release(buf); // 참조카운트 0, deallocate