背景
「300台から時刻同期されても問題ないですか?」
知らんので試した。
問題ないってなにを根拠にしたらいいんですかね?
構成前提
・Windows Server2019を NTPサーバとしてLAN内に公開。
Linuxのほうが厳密な時刻同期を提供できるみたいですが、今回は数秒程度の誤差は許容するので(標準実装しているデーモンがRFC準拠だからと言うべき?)
・クライアント数は300台、すべてWindows10
・クライアントはワークグループ環境とする
クライアント側の設定
そもそもWindowsの時刻同期については下記の連載がかなり参考になりました。
https://www.atmarkit.co.jp/ait/series/1842/spv/
それを踏まえて、レジストリで設定していきます。
・クライアントモードで動作。
時効同期のモードというとslewかstepか?と思いますよね。Windowsの場合はそれとは他に動作モードの概念があるみたいです。具体的には下記。
https://www.atmarkit.co.jp/ait/articles/1205/17/news135_2.html
このレジストリ値の第2パラメータでは、同期モードと同期間隔を同時に設定できる。以下のような意味を持っており、組み合わせて使うことができる。例えば0x9の場合、「Clientモードで、かつ一定の間隔で同期する」ことを意味する。ちなみに0x0または値なしの場合は0x4と同様の動作をする。
NtpServerエントリ値の末尾がポイントなわけです。
手元のWindows10 1903で確認したところ、デフォルトは0x8でした。RFC準拠の同期間隔のようです。このあたりのデフォルト値はバージョンごとに異なるかもしれないので、参考までに。
同期間隔のデフォルトは1024秒~32768秒。(Min/MaxPollInterbalで指定されてる値で2を乗じた数)
単純にクライアントとしてだけ動作かつ同期間隔を制御しなくても良いのであれば、GUIで設定できます。
ファイル名を指定して実行(コマンドプロンプトでもよいです)→timedate.cpl
インターネット時刻タブ
この画面で、「設定の変更」→「今すぐ更新」を選ぶと、指定されている時刻同期先と即時同期を行いますが、このとき先ほど説明した同期モードが「0x9」に更新されます。気を付けて下さい。
※0x9になっていると、(Min/MaxPollInterbalの間隔ではなく、SpecialPollIntervalの値に応じて同期を行う)
timedate.cplでインターネット時刻タブが出てこない場合はドメイン環境下で同期しているか、ローカルグループポリシー等で、クライアント個別での時刻同期設定が制限されている可能性があります。
さて、上記設定のクライアントを300台用意すれば実験出来ます。でもやってられないので、エミュレートします。
JMeterでNTP
あまり情報が出てきませんでした。一般には、あまり検証需要が無いんでしょうね。
UDPのプラグインが必要です。
https://dev.to/qainsights/network-time-protocol-performance-testing-using-apache-jmeter-1197
上記の解説ページにあるUDPサンプラ プラグイン取得先のURLからダウンロードして、zip解凍します。
https://jmeter-plugins.org/wiki/UDPRequest/
解凍された「lib」フォルダ以下を、Jmeterを解凍したフォルダのlib以下に、丸っとコピーすればプラグイン追加完了です。
UDPサンプラにセットするデータは、NTPクライアント役からの送信をWireSharkでパケットキャプチャして、まんまセットします。
NTPリクエストデータ取得
まずコマンドプロンプトを起動して、NTPリクエストのコマンドを打ち込んでおきます(まだEnter押さない)
UDPサンプラの使用例だと「w32tm /stripchart ~」を使ってましたが、同期を取り直しに行く/resyncにしてみました。
WireSharkを起動してパケットキャプチャを開始したら、上記のコマンドを実行します。NTPリクエストが確認できたら、キャプチャを止めて構いません。「udp.port==123」で表示フィルタをかけるとわかりやすいと思います。
ちょっと注意が必要なのは、キャプチャしたリクエストデータ全体をコピーするわけではないことです。
こうではなく、(リクエストのパケットを選択して、右クリックしています)
こうです。Netowork Time Protocol~のところにマウスを合わせて、コピー→as Hex Streamです。
これを、JMeterのUDPサンプラの、リクエストデータのところにペーストします(右クリックできないのでCtrl + vでどうぞ)
僕はこれで4時間溶かしました。悔しい。
NTPリクエストの実行
この時点で、試しにいっかいリクエストを実行してみます。
JMeterのリスナーで「結果をツリーで表示」を追加してから、実行を押下します。ちなみに結果をぱっと確認したいときは、リスナ「結果を表で表示」と、「統計レポート」もオススメです。
あとは、これをテストシナリオとしてカスタマイズしていけばOKです。
今回は下記のようにしてみました。
スレッド数300、ランプアップは1分、無限ループに設定して、持続時間は300秒。
※すみません、画像のスレッド数が150になってしました。あとで修正します。
タイマで15秒くらいインターバルを設けます。
お約束の通り、実際のテストのときはコマンドラインから起動します。
https://qiita.com/tatesuke/items/827e6190753964e46814
サーバ側のリソース状況を把握したい場合は、リクエストを受ける側でパフォーマンスモニタを起動しておきましょう。
これであとは待つだけ。wiresharkのパケットでも眺めてましょう。
NTPサーバ側のリソース状況
ざっくり確認ならリソースモニタを目視で監視、ログを取るならパフォーマンスカウンタを起動しておく。
カウンタはリソースといえば代表的なものということで、下記にします。
グラフ描画時はそもそものスケールを変更するなどして、みやすくしないと何がなんだかわからなくなるので、気を付けましょう。下記を参考にして、スケールの変更や、グラフの上限値を変更します。
https://qiita.com/tsuttie/items/9e9a6389dd843bcdcdad
ちなみに、帯域(current bandwidth)は既定値の単位がよくわからなかったのですが、カウンタ追加時に説明を確認できるので、そこで確認したらbit per secondsとのことでした。
CPUのバーストがちょっと気になりますが元々独自プログラムをたくさん動かしてるので、いったんそのせいということにします。本来はここでもう少し深堀するべきなんでしょうけどね。
ちなみに、Windows公式でネットワークモニタが提供されているようです。標準で付属しないので追加インストールが必要みたいです。
https://www.microsoft.com/en-us/download/details.aspx?id=4865
ネットワーク状況
いちおうパケットも見ときましょうか。キャプチャフィルタで最初から絞り込むのではなく、表示フィルタで結果を絞り込むほうが良いです。
入出力グラフを見ると、 NTPの通信だけでだいたい秒間1500~2000Bytesくらい。これはリクエストとレスポンス両方含んでます。60秒くらいから安定しているのは、ランプアップ期間が60秒に設定したので、このあたりで全スレッド起動したからですね。
まとめ
「300台から時刻同期されても問題ないですか?」
問題ないです。
参考
JMeterでNTP負荷テストを行う
https://dev.to/qainsights/network-time-protocol-performance-testing-using-apache-jmeter-1197
JMeter UDPプラグイン入手先
https://jmeter-plugins.org/wiki/UDPRequest/
JMeter基本的な使い方
https://devlog.arksystems.co.jp/2019/01/23/6596/
JMeterをコマンドラインで実行する
https://qiita.com/tatesuke/items/827e6190753964e46814
Windowsパフォーマンスモニタのカウンタについて
https://www.ashisuto.co.jp/product/category/quality/loadrunner/technical/list/1195227_3454.html
Windowsの時刻同期をもう少し詳しく知りたい人へ
http://kfujieda.hatenablog.com/entry/2020/03/14/214544