Nettyを使って、私達は一体何を開発していますか?

6944 ワード

java界では、nettyは間違いなくネットアプリケーションを開発する得意料理です.複雑なnioモデルや底辺ネットワークの詳細にはあまり関心を持たないでください.豊富なインターフェースを使って、複雑な通信機能を簡単に実現できます.
golangのネットモジュールに比べて、nettyはまだ大きすぎます.でも、javaのフレームはこのようにして、IDEから離れたら生存できないコード言語に属しています.
最新のキティちゃんバージョンはモジュールを非常に細かく分けます.各モジュールにどんな内容があるか分からないなら、直接にnetty-allを使えばいいです.
単純に使うと、nettyは非常に簡単で、ByteBuf、Chanel、Pipeline、Eventモデルなどを把握して開発することができます.面接のnettyに関する知識を見つけます.話ができませんでした.しかし、Nettyは他の開発モデルとは大きく違っています.最も主要なのはその非同期化です.非同期化による結果としては、プログラムモデルの違いとデバッグ上の困難があり、コードに対する要求が高いです.
しかし、プロジェクトから言えば、スズメは小さくても、業務層からサービスゲートウェイまで、監視と配置を含めて、さまざまな技術保障を備えています.キティ自体が小さいです.ここでは、nettyを使って開発し、どのような共通の内容に注目して、単独機で100 w接続をサポートするlinuxの配置を添付します.本文はnettyの基礎知識に注目していません.
プロトコル開発
ネットワーク開発において最も重要なのは、通信フォーマット、プロトコルです.私たちがよく見るプロトブ、json、avro、mqttなどはこの列に属します.協議には文法、意味、タイミングの三つの要素があります.
私は多くのミドルウェアの応用を見ましたが、redis契約を採用しています.そしてエンドダウンしたのはmysqlです.mysqlプロトコルを採用して実現される様々なカスタムストレージシステムも見たことがあります.例えば、proxy端末のライブラリ分割表の中間部品、tidbなどです.
私たちがよく使うredisはテキストプロトコルです.mysqlなどが実現しているのはバイナリプロトコルです.nettyに置くのも同じです.codecを実現すればいいです.nettyはデフォルトでdns、haproxy、http、http 2、memcache、mqtt、redis、smatp、socks、stomp、xmlなどの契約を実現しました.
一つの可能な製品の構造はこのようになります.外部には同じ外観を提供しますが、核心の記憶は違っています.テキスト協議は調整しています.バイナリプロトコルは、ログやワイスハークなど他の方法に依存して分析し、開発の難しさを高めています.伝説の粘着カバンは包装を外して、ここで処理します.また、ネバネバの原因は主に緩衝区の介入によるもので、双方の伝達概要などの情報を約束する必要があり、これをある程度解決しました.
ネットアプリケーションを開発しようとする学生たちは、心の中に新たな設計契約の夢の種を埋めています.しかし、契約の設計は非常に困難であり、業務を深く耕し、その拡張性も考慮しなければならない.特に必要がないなら、既存の契約を使うことを提案します.
接続管理機能
Nettyの開発は、接続管理機能が非常に重要です.通信品質、システム状態、およびいくつかの黒科学技術機能は、接続管理機能に依存しています.サービスとしても、クライアントとしても、nettyは接続を作成した後に、「netty」という名前をもらいます.Channelのオブジェクト.私たちがやるべきことは、その管理についてです.名前をつけることに慣れています.ConnectionManager管理クラスはいくつかのメモリオブジェクトをキャッシュして、実行中のデータを統計します.例えば接続に向けた機能:パッケージ送信、受信数;パケット送信、受信速度;エラーカウント;接続回数呼び出しの遅延;接続状態など.これは頻繁にjava中のconcurrent の関連する種類を使うことができて、よくbug集中地です.
しかし、私たちはもっと必要です.管理類は各接続にもっと多くの機能を与えます.例えば、接続が作成された後、機能を予熱したいなら、これらの状態はルートの決定に参加できます.通常、ユーザーまたは他のメタ情報を接続にもatchし、多次元の接続を条件に合わせて選別し、グレースケール、過負荷保護などの一括操作を行うことは、非常に重要な機能である.
管理バックグランドは各接続の情報を見ることができます.一つ以上の接続を選別した後、これらの接続に対する流量記録、情報監視、断点調整を開くことができます.すべてをコントロールする感覚を体験することができます.
管理機能はまた、システム全体の運行状態を見て、適時に負荷バランス戦略を調整することができます.同時に拡大・縮小に対してデータの根拠を提供する.
心拍検出
アプリケーションプロトコル層の心拍数は必須であり、tcp keepaliveとは全く異なる概念である.
アプリケーション層プロトコル層の心拍数検出は、接続者の生存性であり、接続品質であり、keepaliveが検出したのは接続自体の生存性である.しかも後者のタイムアウト時間はデフォルトでは長すぎて、現代のネット環境には全く適応できません.心拍は輪訓によるもので、サービスにしても、クライアントにしても、例えばGCMなどです.保活機構は異なるアプリケーションシーンでダイナミックな切り替えを行います.例えば、プログラムの起動とバックグラウンドでのラウンドトレーニングの戦略は違います.
Netty内蔵は、IdleStateHandlerの増加によりIDLEイベントを発生させることにより、簡単な心拍制御を行う.あなたが処理するのは、心拍タイムアウトのロジックです.しかし、そのターントレーニングの時間は固定されています.動的に変えることができません.高級機能は自分でカスタマイズする必要があります.
いくつかのクライアントでは、例えばAndroidのように、頻繁に心拍数の喚起は、ネットワークと電力量を無駄にしてしまいます.
境界
優雅な終了メカニズム
Javaの優雅な停止は、通常JDK Shutdown Hookを登録することによって実現される.
Runtime.getRuntime().addShutdownHook();
一般的にはkill -15を通じてjavaプロセスの閉鎖が行われ、プロセスが死ぬ前にいくつかの清掃作業が行われる.
注意:kill-9はすぐにプロセスを殺すので、遺言の機会を与えないと危険です.
キティちゃんは優雅に退出する仕事をたくさんしましたが、EventLoopGroupshutdownGracefully方法でニコの状態をいくつか設定しましたが、多くの場合、これはまだ多くないです.シングルマシン環境の優雅さだけを担当します.
トラフィックはまた、外部層のルーティングによって継続的に入力され、無効な要求を引き起こすかもしれない.私の通常のやり方はまず外層ルートで現地の例の摘出を行い、流量を遮断してから、netty自身の優雅な閉鎖を行います.この設計は非常に簡単で、再試行機構がなくてもよく実行されます.ルート層で事前に関連インターフェースを露出する必要があることが前提です.
異常処理機能
キティちゃんは、その非同期的な開発方式とその事件メカニズムによって、異常処理の面で非常に重要です.接続の高い信頼性を保証するために、多くの異常は静かに無視する必要があります.あるいはユーザ状態では感知されません.
nettyの異常はpipelineを通じて伝播しますので、どの階で処理してもいいですが、プログラミング習慣では一番外側に投げて集中的に処理します.
異常情報を最大限に区別するために、通常は大量の異常類を定義します.異常が発生したら、断線再接続(例えば、いくつかのバイナリプロトコルの暗号化復号化の乱れた問題)を異なるタイプによって選択したり、他のノードにスケジュールしたりすることができます.
機能制限
コマンドモード
ネットワークアプリケーションは、ネットワークアプリケーションのことをする必要があります.どの通信も高価です.「Linuxの『キャスト・アウェイ』(五)ネットワーク編」では、100万接続のサーバーについて話しています.1 kbメッセージを放送するには、1000 Mの帯域幅が必要です.だから、何でもインターネットアプリケーションに入れるというわけではありません.
大規模なネットワークアプリケーションの合理的な考え方は、関連する を送信することです.クライアントは、httpなどの他の方法で、大規模なファイルを取得することができます.多くのIMの設計の考え方はこのようです.
命令モードはまた、通信システムの拡張性と安定性を保証します.追加命令は配置式であり、直ちに発効してもいいです.サービス端末はコード再起動が必要ではありません.
安定性保証
ネットワークアプリケーションのトラフィックは一般的に非常に大きく、フルログのオープンには適していません.アプリケーションは主要イベントのログのみに注目し、異常な場合の処理フローに関心を持ち、ログはある程度印刷します.
ネットワークアプリケーションは、他の低速なapiを呼び出すのにも適していません.または、I/Oのインターフェースをブロックします.いくつかのリアルタイムのイベントは、インターフェースを呼び出してデータを吐き出すべきではなく、高速mqなどの他の非同期チャネルを歩くことができます.
キャッシュは、ネットワークアプリケーションで一番多く使われているコンポーネントかもしれません.jvm内のキャッシュには、いくつかのシングルマシンの統計データが格納されます.Redisなどは、大域的な統計と中間状態データを記憶しています.ネットワークアプリケーションでは、redis、kv、高スループットのmqが多く使われます.ユーザーの要望に迅速に応えてください.とにかく、通信層の爽やかさを維持してください.多くの心配が省けます.
単機は100万接続のLinux配置をサポートします.
シングルは100万接続が可能ですが、帯域幅の問題が大きなネックになります.圧縮を有効にするバイナリプロトコルは、帯域幅の一部を節約しますが、開発の難しさが増します.
「LWPプロセスの資源が尽きました.Resource temporarly unavailable」に記載されているES構成と同じように、最適化には似たような考え方があります.この構成では、数日間の時間を節約できます.どうぞ.
オペレーティングシステムの最適化
変更プロセスの最大ファイルのハンドル数
ulimit -n 1048576
個々のプロセスに割り当て可能な最大ファイル数を変更します.
echo 2097152 > /proc/sys/fs/nr_open
修正/etc/security/limits.com nfファイル
*   soft nofile  1048576
*   hard nofile 1048576
*   soft nproc unlimited
root soft nproc unlimited
整理/etc/security/limits.d/*下の配置を覚えてください.
ネットワーク最適化/etc/sysctl.confを開き、構成を追加して実行し、sysctlを使用して発効する.
#             
fs.nr_open=2097152

#         
fs.file-max = 1048576

#backlog   
net.core.somaxconn=32768
net.ipv4.tcp_max_syn_backlog=16384
net.core.netdev_max_backlog=16384

#          
net.ipv4.ip_local_port_range='1000 65535'

#TCP Socket    Buffer   
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.core.optmem_max=16777216
net.ipv4.tcp_rmem='1024 4096 16777216'
net.ipv4.tcp_wmem='1024 4096 16777216'

#TCP       
net.nf_conntrack_max=1000000
net.netfilter.nf_conntrack_max=1000000
net.netfilter.nf_conntrack_tcp_timeout_time_wait=30

#TIME-WAIT Socket     、       
net.ipv4.tcp_max_tw_buckets=1048576

# FIN-WAIT-2 Socket     
net.ipv4.tcp_fin_timeout = 15

締め括りをつける
キティちゃんの開発作業はキティ自身に集中していません.サービスの信頼性と安定性を保証する上で、多くの仕事が監視と調整に集中しています.
nettyを深く理解することは、システムが難解な問題に遭遇した時に、深く掘り下げて検査したり、厳しい性能を向上させたりすることです.しかし、多くの応用開発者にとって、nettyの着手コストは小さいです.
これはただの道具です.どうやってそれを譲ってもいいですか?