nettty
1.Netty-非同期およびイベント駆動
1.Nettyは、システムが150,000人の同時ユーザーをサポートできるようにする構築を支援します.
2.Netty設計キー:非同期+イベント駆動
1.1 Javaネットワークプログラミング(BIO)
典型的なBIOサービス:
1.プライマリ・スレッドがportで傍受され、クライアント接続を待機します.
2.クライアントが開始した接続を受信すると、クライアント要求を処理するための新しいスレッドが作成されます.
3.プライマリ・スレッドはportリスニングに戻り、次のクライアント接続を待機します.
欠点:
1.各新しいクライアントSocketは新しいThread処理を作成する必要があり、大量のスレッドがスリープ状態になる.
2.各スレッドには呼び出しスタックのメモリ割り当てがあり、接続数が非常に多い場合、メモリが多く消費されます.
3.接続数が多い場合、大量のスレッドが作成され、コンテキスト切り替えによるオーバーヘッドが大きい.
コード:
-
public void serve(int port) throws IOException {
-
// Socket
-
ServerSocket serverSocket =
new ServerSocket(port);
-
//
-
Socket clientSocket = serverSocket.accept();
-
//
-
BufferedReader in =
new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
-
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(),
true);
-
String request, response;
-
while((request = in.readLine()) !=
null) {
-
if(
"Done".equals(request)) {
-
break;
-
}
-
response = processRequest(request);
-
out.println(response);
-
}
-
}
1.2 Java NIO
1. Selector Java I/O 。 Socket Selector , / 。
2. 。
1.3 Nettyのコアコンポーネント
Netty :
1. Channel
2.
3. Future
4. ChannelHandler
1.3.1 Channel
Channel ( ) ( ) ( 、 Socket )。 , 。
1.3.2コールバック
: , 。Netty , : ChannelHandler channelActive() , , 。
1.3.3 Future
。 , 。
JDK Future ChannelFuture :
1. JDK Future ,
2. ChannelFuture Listener , operationComplete() 。
:
-
public static void connect() {
-
Channel channel = CHANNEL_FROM_SOMEWHERE;
-
-
ChannelFuture future = channel.connect(
new InetSocketAddress(
"127.0.0.1",
9080));
-
future.addListener(
new ChannelFutureListener() {
-
@Override
-
public void operationComplete(ChannelFuture future) throws Exception {
-
if(future.isSuccess()) {
-
ByteBuf buf = Unpooled.copiedBuffer(
"hello", Charset.defaultCharset());
-
ChannelFuture wf = future.channel().writeAndFlush(buf);
-
// ...
-
}
else {
-
// /
-
future.cause().printStackTrace();
-
}
-
}
-
})
-
}
1.3.4イベントとChannelHandler
1. : 。 : (channelActive)/ (channelRead)/ (exceptionCaught)/...
2. Channelhandler: 。 :ChannelInboundHanderAdapter.java
1.3.5 ChannelとEventLoopの :
Channel EventLoop Netty , , :
1. Channel EventLoop
2. EventLoop Channel(1:n )
3. EventLoop 4. Channel I/O , ChannelPipeline ChannelHandler
2. のNettyアプリケーション
1. ChannelHandler 。
2. Netty , : , 。 , 。
2.3 Echoサーバの
Netty : ChannelHandler + (Bootstrap)
2.3.1 ChannelHandlerとビジネスロジック
ChannelInboundHandlerAdapter , :
1. channelRead() -
2. channelReadComplete() -
3. exceptionCaught() - ,
:
-
@ChannelHandler.Sharable
-
public
class EchoServerHandler extends ChannelInboundHandlerAdapter{
-
-
/**
-
*
-
*/
-
@Override
-
public void channelRead(ChannelHandlerContext ctx, Object msg) {
-
ByteBuf in = (ByteBuf) msg;
-
System.out.println(
-
"Server received: " + in.toString(CharsetUtil.UTF_8));
-
ctx.write(in);
-
}
-
-
/**
-
* , channelReadComplete(...)
-
*/
-
@Override
-
public void channelReadComplete(ChannelHandlerContext ctx)
-
throws Exception {
-
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
-
.addListener(ChannelFutureListener.CLOSE);
-
}
-
-
/**
-
*
-
*/
-
@Override
-
public void exceptionCaught(ChannelHandlerContext ctx,
-
Throwable cause) {
-
cause.printStackTrace();
-
ctx.close();
-
}
-
}
:
1. channelRead channelReadComplete : channelRead(...) channelReadComplete 。
2. ctx.write(...) ChannelOutboundBuffer , flush(...)
3. @Sharable : ChannelHandler 。 Channel 。 @Sharable ChannelHandler
4.
2.3.2ブートサーバ
1. Netty Channel。 EventLoop ChannelPipeline。
2. Channel ChannelPipeline。ChannelPipeline ChannelHandler 。
:
-
EventLoopGroup group =
new NioEventLoopGroup();
-
try {
-
ServerBootstrap b =
new ServerBootstrap();
-
b.group(group)
-
.channel(NioServerSocketChannel.class)
-
.localAddress(
new InetSocketAddress(port))
-
.childHandler(
new ChannelInitializer
() {
-
@Override
-
public void initChannel(SocketChannel ch) throws Exception {
-
ch.pipeline().addLast(
new EchoServerHandler());
-
}
-
});
-
}
finally {
-
group.shutdownGracefully().sync();
-
}
2.4 Echoクライアントの
:
1.
2.
3.
2.4.1 ChannelHandlerクライアントロジック
1. Java GC 。 Netty ByteBuf, 。 : Netty, 。 ,
2. SimpleChannelInboundHandler Handler, 。SimpleChannelInboundHandler.java channelRead() 。
3. 。 TCP 。
:
-
// SimpleChannelInboundHandler
channelRead msg
-
public
abstract
class SimpleChannelInboundHandler<I> ...{
-
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-
boolean release =
true;
-
try {
-
// ...
-
}
finally {
-
if (autoRelease && release) {
-
// msg
-
ReferenceCountUtil.release(msg);
-
}
-
}
-
}
-
}
:ChannelHandler ?
1. : SimpleChannelInboundHandler, msg ChannelHandler
2. : SimpleChannelInboundHandler, msg ctx.write(...)
2.4.2ブートクライアント
,
:
-
EventLoopGroup group =
new NioEventLoopGroup();
-
try {
-
Bootstrap b =
new Bootstrap();
-
b.group(group)
-
.channel(NioSocketChannel.class)
-
.remoteAddress(
new InetSocketAddress(host, port))
-
.handler(
new ChannelInitializer
() {
-
@Override
-
public void initChannel(SocketChannel ch)
-
throws Exception {
-
ch.pipeline().addLast(
-
new EchoClientHandler());
-
}
-
});
-
//
-
ChannelFuture f = b.connect().sync();
-
f.channel().closeFuture().sync();
-
}
finally {
-
group.shutdownGracefully().sync();
-
}
ふろく
1.
2.netty-in-action
-
public void serve(int port) throws IOException {
-
// Socket
-
ServerSocket serverSocket =
new ServerSocket(port);
-
//
-
Socket clientSocket = serverSocket.accept();
-
//
-
BufferedReader in =
new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
-
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(),
true);
-
String request, response;
-
while((request = in.readLine()) !=
null) {
-
if(
"Done".equals(request)) {
-
break;
-
}
-
response = processRequest(request);
-
out.println(response);
-
}
-
}
1.2 Java NIO
1. Selector Java I/O 。 Socket Selector , / 。
2. 。
1.3 Nettyのコアコンポーネント
Netty :
1. Channel
2.
3. Future
4. ChannelHandler
1.3.1 Channel
Channel ( ) ( ) ( 、 Socket )。 , 。
1.3.2コールバック
: , 。Netty , : ChannelHandler channelActive() , , 。
1.3.3 Future
。 , 。
JDK Future ChannelFuture :
1. JDK Future ,
2. ChannelFuture Listener , operationComplete() 。
:
-
public static void connect() {
-
Channel channel = CHANNEL_FROM_SOMEWHERE;
-
-
ChannelFuture future = channel.connect(
new InetSocketAddress(
"127.0.0.1",
9080));
-
future.addListener(
new ChannelFutureListener() {
-
@Override
-
public void operationComplete(ChannelFuture future) throws Exception {
-
if(future.isSuccess()) {
-
ByteBuf buf = Unpooled.copiedBuffer(
"hello", Charset.defaultCharset());
-
ChannelFuture wf = future.channel().writeAndFlush(buf);
-
// ...
-
}
else {
-
// /
-
future.cause().printStackTrace();
-
}
-
}
-
})
-
}
1.3.4イベントとChannelHandler
1. : 。 : (channelActive)/ (channelRead)/ (exceptionCaught)/...
2. Channelhandler: 。 :ChannelInboundHanderAdapter.java
1.3.5 ChannelとEventLoopの :
Channel EventLoop Netty , , :
1. Channel EventLoop
2. EventLoop Channel(1:n )
3. EventLoop 4. Channel I/O , ChannelPipeline ChannelHandler
2. のNettyアプリケーション
1. ChannelHandler 。
2. Netty , : , 。 , 。
2.3 Echoサーバの
Netty : ChannelHandler + (Bootstrap)
2.3.1 ChannelHandlerとビジネスロジック
ChannelInboundHandlerAdapter , :
1. channelRead() -
2. channelReadComplete() -
3. exceptionCaught() - ,
:
-
@ChannelHandler.Sharable
-
public
class EchoServerHandler extends ChannelInboundHandlerAdapter{
-
-
/**
-
*
-
*/
-
@Override
-
public void channelRead(ChannelHandlerContext ctx, Object msg) {
-
ByteBuf in = (ByteBuf) msg;
-
System.out.println(
-
"Server received: " + in.toString(CharsetUtil.UTF_8));
-
ctx.write(in);
-
}
-
-
/**
-
* , channelReadComplete(...)
-
*/
-
@Override
-
public void channelReadComplete(ChannelHandlerContext ctx)
-
throws Exception {
-
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
-
.addListener(ChannelFutureListener.CLOSE);
-
}
-
-
/**
-
*
-
*/
-
@Override
-
public void exceptionCaught(ChannelHandlerContext ctx,
-
Throwable cause) {
-
cause.printStackTrace();
-
ctx.close();
-
}
-
}
:
1. channelRead channelReadComplete : channelRead(...) channelReadComplete 。
2. ctx.write(...) ChannelOutboundBuffer , flush(...)
3. @Sharable : ChannelHandler 。 Channel 。 @Sharable ChannelHandler
4.
2.3.2ブートサーバ
1. Netty Channel。 EventLoop ChannelPipeline。
2. Channel ChannelPipeline。ChannelPipeline ChannelHandler 。
:
-
EventLoopGroup group =
new NioEventLoopGroup();
-
try {
-
ServerBootstrap b =
new ServerBootstrap();
-
b.group(group)
-
.channel(NioServerSocketChannel.class)
-
.localAddress(
new InetSocketAddress(port))
-
.childHandler(
new ChannelInitializer
() {
-
@Override
-
public void initChannel(SocketChannel ch) throws Exception {
-
ch.pipeline().addLast(
new EchoServerHandler());
-
}
-
});
-
}
finally {
-
group.shutdownGracefully().sync();
-
}
2.4 Echoクライアントの
:
1.
2.
3.
2.4.1 ChannelHandlerクライアントロジック
1. Java GC 。 Netty ByteBuf, 。 : Netty, 。 ,
2. SimpleChannelInboundHandler Handler, 。SimpleChannelInboundHandler.java channelRead() 。
3. 。 TCP 。
:
-
// SimpleChannelInboundHandler
channelRead msg
-
public
abstract
class SimpleChannelInboundHandler<I> ...{
-
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-
boolean release =
true;
-
try {
-
// ...
-
}
finally {
-
if (autoRelease && release) {
-
// msg
-
ReferenceCountUtil.release(msg);
-
}
-
}
-
}
-
}
:ChannelHandler ?
1. : SimpleChannelInboundHandler, msg ChannelHandler
2. : SimpleChannelInboundHandler, msg ctx.write(...)
2.4.2ブートクライアント
,
:
-
EventLoopGroup group =
new NioEventLoopGroup();
-
try {
-
Bootstrap b =
new Bootstrap();
-
b.group(group)
-
.channel(NioSocketChannel.class)
-
.remoteAddress(
new InetSocketAddress(host, port))
-
.handler(
new ChannelInitializer
() {
-
@Override
-
public void initChannel(SocketChannel ch)
-
throws Exception {
-
ch.pipeline().addLast(
-
new EchoClientHandler());
-
}
-
});
-
//
-
ChannelFuture f = b.connect().sync();
-
f.channel().closeFuture().sync();
-
}
finally {
-
group.shutdownGracefully().sync();
-
}
ふろく
1.
2.netty-in-action