参考資料:https://www.cnblogs.com/imstudy/p/9908791.html
1.Nettyの一般的な使用シナリオ
分散システムでは、さまざまなノード間でリモートサービスコールが必要であり、高性能RPCフレームワークが不可欠です。非同期の高性能通信フレームワークとして、NettyはこれらのRPCフレームワークで基本的な通信コンポーネントとしてよく使用されます。典型的なアプリケーションは次のとおりです。Ali分散サービスフレームワークDubboのRPCフレームワークは、ノード間通信にDubboプロトコルを使用します。Dubboプロトコルは、プロセスノード間の内部通信を実装するための基本的な通信コンポーネントとしてデフォルトでNettyを使用します。
2.高性能設計
1.バイオモード[従来のブロッキングタイプ]
2.NIOモード[I / O再利用モデル]
Reactorスレッドモデル
Reactorはリアクターを意味します。Reactorモデルは、1つ以上の入力を介してサービスプロセッサーに同時に渡されるサービス要求のイベント駆動型処理モードを指します
。Nettyスレッドモデル
Netty mainマスタースレーブReactorsマルチスレッドモデル(下の図に示す)に基づいて、特定の変更が加えられました。その中で、マスタースレーブReactorマルチスレッドモデルには複数のReactorがあります。
コード例
EventLoopGroup bossGroup = newNioEventLoopGroup();
EventLoopGroup workerGroup = newNioEventLoopGroup();
ServerBootstrap server = newServerBootstrap();
server.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
【ブートストラップ、サーバーブートストラップ】:
Bootstrapはブートを意味します。Nettyアプリケーションは通常Bootstrapで始まります。主な機能はNettyプログラム全体を構成し、さまざまなコンポーネントを接続することです。NettyのBootstrapクラスはクライアントプログラムのスタートアップブートクラスであり、ServerBootstrapはサーバーのスタートアップブートです。クラス。
【チャネル】:
ネットワークI / O操作を実行するために使用できるNettyネットワーク通信のコンポーネント。呼び出しはすぐにChannelFutureインスタンスを返します。リスナーをChannelFutureに登録することにより、I / O操作が成功、失敗、またはキャンセルされたときに呼び出し元にコールバックして通知できます。
異なるプロトコルおよび異なるブロッキングタイプの接続には、それらに対応する異なるチャネルタイプがあります。
以下は、一般的に使用されるチャネルタイプです。
NioSocketChannel,异步的客户端 TCP Socket 连接。
NioServerSocketChannel,异步的服务器端 TCP Socket 连接。
NioDatagramChannel,异步的 UDP 连接。
NioSctpChannel,异步的客户端 Sctp 连接。
NioSctpServerChannel,异步的 Sctp 服务器端连接,这些通道涵盖了 UDP 和 TCP 网络 IO 以及文件 IO。
【セレクタ】:
Nettyは、セレクタオブジェクトに基づいてI / O多重化を実装します。セレクタを介して、1つのスレッドで複数の接続のチャネルイベントを監視できます。
チャネルがセレクターに登録されると、セレクターの内部メカニズムは、これらの登録されたチャネルに準備ができたI / Oイベント(読み取り可能、書き込み可能、ネットワーク接続完了など)があるかどうかを自動的かつ継続的に照会(選択)できます。プログラムは、1つのスレッドを使用するだけで、複数のチャネルを効率的に管理できます。
【NioEventLoop】:
スレッドとタスクキューは、タスクの非同期送信と実行をサポートするNioEventLoopで維持されます。スレッドが開始されると、NioEventLoopのrunメソッドが呼び出され、I / Oタスクと非I / Oタスクが実行されます。
I / Oタスク、つまり、accept、connect、read、writeなどのselectionKeyのreadyイベントは、processSelectedKeysメソッドによってトリガーされます。
非IOタスク、register0、bind0、その他のタスクなど、taskQueueに追加されたタスクは、runAllTasksメソッドによってトリガーされます。
【NioEventLoopGroup】:
主にeventLoopのライフサイクルを管理するNioEventLoopGroupは、スレッドプールとして理解できます。スレッドのセットは内部で維持されます。各スレッド(NioEventLoop)は、複数のチャネルでのイベントの処理を担当し、チャネルは1つのスレッドにのみ対応します。
Nettyサーバーを初期化および起動するための一般的なプロセスコードは次のとおりです。
publicstaticvoidmain(String[] args) {
// 创建mainReactor
NioEventLoopGroup boosGroup = newNioEventLoopGroup();
// 创建工作线程组
NioEventLoopGroup workerGroup = newNioEventLoopGroup();
finalServerBootstrap serverBootstrap = newServerBootstrap();
serverBootstrap
// 组装NioEventLoopGroup
.group(boosGroup, workerGroup)
// 设置channel类型为NIO类型
.channel(NioServerSocketChannel.class)
// 设置连接配置参数
.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true)
// 配置入站、出站事件handler
.childHandler(newChannelInitializer<NioSocketChannel>() {
@Override
protectedvoidinitChannel(NioSocketChannel ch) {
// 配置入站、出站事件channel
ch.pipeline().addLast(...);
ch.pipeline().addLast(...);
}
});
// 绑定端口
intport = 8080;
serverBootstrap.bind(port).addListener(future -> {
if(future.isSuccess()) {
System.out.println(newDate() + ": 端口["+ port + "]绑定成功!");
} else{
System.err.println("端口["+ port + "]绑定失败!");
}
});
}
基本的なプロセスは次のとおりです。
1)最初に2つのNioEventLoopGroupsを作成します。boosGroupはAccetpt接続確立イベントと要求の配布に使用され、workerGroupはI / O読み取りおよび書き込みイベントとビジネスロジックの処理に使用されます。
2)ServerBootstrap(サーバー起動ブートクラス)に基づく:EventLoopGroup、チャネルタイプ、接続パラメーターを構成し、インバウンドおよびアウトバウンドのイベントハンドラーを構成します。
3)バインドポート:作業を開始します。
上で紹介したNettyReactorモデルと組み合わせて、サーバーNettyの動作アーキテクチャ図を紹介します。
サーバー側には、1つのボスNioEventLoopGroupと1つのワーカーNioEventLoopGroupが含まれています。
NioEventLoopGroupは、イベントループグループと同等です。このグループには複数のイベントループNioEventLoopが含まれ、各NioEventLoopには1つのセレクターと1つのイベントループスレッドが含まれます。
Boss NioEventLoopループによって実行される各タスクは、次の3つのステップで構成されます。
1)ポーリング受け入れイベント。
2)I / Oイベントの受け入れを処理し、クライアントとの接続を確立し、NioSocketChannelを生成し、NioSocketChannelをワーカーNioEventLoopのセレクターに登録します。
3)タスクキューrunAllTasks内のタスクを処理します。タスクキュー内のタスクには、eventloop.executeまたはscheduleを呼び出すユーザーによって実行されるタスク、または他のスレッドによってイベントループに送信されるタスクが含まれます。
各ワーカーNioEventLoopループによって実行されるタスクは、次の3つのステップで構成されます。
1)読み取りおよび書き込みイベントのポーリング。
2)I / Oイベント、つまり読み取りイベントと書き込みイベントを処理し、NioSocketChannelの読み取り可能および書き込み可能なイベントが発生したときにそれらを処理します。
3)タスクキューrunAllTasks内のタスクを処理します。