まず、起源の需要
ウェブサーバーは、通常の構成を有し、ワーカースレッドの最大数は、バックエンド・サービスは、一般的な構成を持っている、スレッドプールの作業中のスレッドの数は、異なる構成のビジネスアーキテクトのスレッドの数が異なる経験、いくつかのビジネスのセットのCPUコアを持っていますCPUコアの8倍の数、CPUコアの32倍の数のいくつかの動作設定にいくつかの動作設定の2倍の数。
CPUのパフォーマンスを最大化するように設定することができますどのくらいの最後には、どのような設定「ワーカースレッドの数を」基づいており、問題はこの資料に記載されています。
第二に、共通の認識
さらに、詳細な議論の前に、質問の最初の形式は、いくつかの一般的な知識に同意します。
Q:ワーカースレッドの数が大きく、より良い設定されていないのでしょうか?
A:絶対にありません、
-
シングルコアCPU万労働者は意味をなさない設定されたサーバーのCPUコアの数が限られ、同時に並行スレッドの数が限られ、
-
スレッドの切り替えは、スレッドがあまりにも頻繁に切り替えると、オーバーヘッドですが、パフォーマンスが低下します
Q:スレッドがCPUを占有されているかどうか、時間の呼び出しスリープ()関数で、?
A:別のスレッドがCPUリソースを必要とするのを待つ間、CPUが出すだろう、取りません。
より多くの睡眠()関数よりも、いくつかの時間後に、このようなネットワークプログラミングなどのコールをブロック:
-
クライアントが接続するのを待って、)(受け入れるブロッキング
-
パックにはrecv()、下流バックの待機をブロック
CPUリソースを占有しないでください。
Q:シングルコアCPU、マルチスレッドは、並行性を向上させることができるかどうか、それを設定することが理にかなっていますか?
:でも、シングルコア、マルチスレッドも同時実行性を向上させることができ、ほとんどの場合、理にかなっています
-
マルチスレッド符号化は、例えば、コードをより明確に:IOスレッドトランシーバパッケージ、ワーカースレッドタスキング、タイムアウトスレッドタイムアウト検出
-
計算では、タスクのCPUリソースがあった場合、そのスレッドは、並行性を増加させない増加、例えば、次のコードは、常にCPUを占有し、100%のCPU使用率になります。
一方、(1){I ++。}
-
休憩中にこのスレッドは、他のスレッドが仕事を続けることができるので、一般的に、ワーカースレッドが並行性を向上させることができワーカースレッドを増やし、一般的にCPUはシングルコアであっても、この時点で計算されていないCPUを占有し、話します
第三に、一般的なスレッドモデルサービス
スレッドモデル共通サービスについて、一般的に、同時サービスの原理を理解するために2つの方法で、共通のスレッドモデルのインターネットサービスを支援します。
-
IOスレッドとタスクキューを切り離すことにより、求人情報サイト
-
ピュア非同期
クラスモデルを切り離すことにより、IOスレッド作業キュースレッド
上記のように、ウェブ・サーバーおよびサービスフレームワークのほとんどは、スレッドモデルクラスを「デカップリングキューを介してIOスレッドワーカースレッド」などAを使用しています:
-
いくつかのスレッドは、IO要求が上流側、及びパケット送受信(メーカー)を介して送信モニター
-
一つ以上のタスクキュー、およびデータ伝送チャネルIOスレッドワーカースレッドの非同期デカップリング(重要なリソース)と
-
定期的なタスク(消費者)を実行するために、実際に複数のワーカースレッドがあります。
Tomcatのスレッドは、Javaプログラムを実行する方法場面のほとんどに沿って、非常に広範囲のスレッドモデルは、この機能のスレッドモデルは、内部スレッドはミッションの仕事(リコールをブロック同期であるということです、ダボのワーカースレッドがタスクを実行する方法です)、されて議論される労働者のフォーカス今日同時スレッドの数を増やすことで容量を増加させることができる「ワーカースレッドのモデル番号は、同時の最大数に到達するために設定されています。」
純粋な非同期スレッドモデル
いかなる障害物が、このスレッドモデルは、いくつかの非常に高いスループットを行うことができるようになりますスレッドの数だけを必要とせず、このモデルの欠点は次のとおりです。
-
あなたはの利点を使用するシングルスレッド、マルチコアCPUやより多くの困難を使用している場合
-
プログラマは、より多くの書き込み同期コード、コードの読みやすさに影響を与えるためのコールバック方法に慣れている、プログラマはまた、より高い必要です
-
より複雑なフレーム、多くの場合、サーバ側送受信部を必要とするキューサーバ側、クライアント側送受信部、キューのクライアント側、コンテキスト管理コンポーネント、アセンブリの有限状態機械、タイムアウト管理コンポーネントをサポートするために
記事「RPCクライアント非同期レシーバ・コアの詳細?「より具体的には、しかし、このモデルは、今日の議論の焦点ではありません
第四に、ワーカースレッドの動作モード
ワーカースレッドのモードを理解し、定量分析のスレッドのセット数は非常に有用です:
図は、プロセスの最初から最後まで処理を終了、7つのステップの合計を処理するタスクを開始、ワーカースレッドの典型的なプロセスであります:
-
たとえばHTTPプロトコル解析、パラメータ解析、パラメータ校正などとしてキューからタスクを、いくつかのローカル初期化コンピューティング、うまく
-
データ・キャッシュ・アクセスの一部を取ります
-
キャッシュ内のデータを取得した後、その後、いくつかのローカル計算の、これらの計算およびビジネスロジックが関連します
-
下流のサービスにより、RPCコールは、データの一部を奪還、または関連するタスクの数に対処するための下流のサービスをできるように
-
RPCコールの後、その後、ローカルコンピューティングの一部、計算方法とビジネスロジック関連
-
DBアクセスいくつかのデータ操作
-
操作完数据库之后做一些收尾工作,同样这些收尾工作也是本地计算,和业务逻辑相关
分析整个处理的时间轴,会发现:
-
其中1,3,5,7步骤中(上图中粉色时间轴),线程进行本地业务逻辑计算时需要占用CPU
-
而2,4,6步骤中(上图中橙色时间轴),访问cache、service、DB过程中线程处于一个等待结果的状态,不需要占用CPU,进一步的分解,这个“等待结果”的时间共分为三部分:
2.1)请求在网络上传输到下游的cache、service、DB
2.2)下游cache、service、DB进行任务处理
2.3)cache、service、DB将报文在网络上传回工作线程
五、量化分析并合理设置工作线程数
最后一起来回答工作线程数设置为多少合理的问题。
通过上面的分析,Worker线程在执行的过程中,有一部计算时间需要占用CPU,另一部分等待时间不需要占用CPU,通过量化分析,例如打日志进行统计,可以统计出整个Worker线程执行过程中这两部分时间的比例,例如:
-
执行计算,占用CPU的时间(粉色时间轴)是100ms
-
等待时间,不占用CPU的时间(橙色时间轴)也是100ms
得到的结果是,这个线程计算和等待的时间是1:1,即有50%的时间在计算(占用CPU),50%的时间在等待(不占用CPU):
-
假设此时是单核,则设置为2个工作线程就可以把CPU充分利用起来,让CPU跑到100%
-
假设此时是N核,则设置为2N个工作现场就可以把CPU充分利用起来,让CPU跑到N*100%
结论:
N核服务器,通过执行业务的单线程分析出本地计算时间为x,等待时间为y,则工作线程数(线程池线程数)设置为 N*(x+y)/x,能让CPU的利用率最大化。
经验:
一般来说,非CPU密集型的业务(加解密、压缩解压缩、搜索排序等业务是CPU密集型的业务),瓶颈都在后端数据库访问或者RPC调用,本地CPU计算的时间很少,所以设置几十或者几百个工作线程是能够提升吞吐量的。
六、总结
-
线程数不是越多越好
-
sleep()不占用CPU
-
单核设置多线程不但能使得代码清晰,还能提高吞吐量
-
站点和服务最常用的线程模型是“IO线程与工作现场通过任务队列解耦”,此时设置多工作线程可以提升吞吐量
-
N核服务器,通过日志分析出任务执行过程中,本地计算时间为x,等待时间为y,则工作线程数(线程池线程数)设置为 N*(x+y)/x,能让CPU的利用率最大化