最近snmpdサービスに問題が発生しました。 CentOS 6.9を実行するLinuxボックスがあり、localhostでsnmpwalkを実行すると、通常はタイムアウトのみが発生します。その後、10秒のタイムアウトを追加しようとしましたが、結果は良かったですが、まだ痛いほど遅いです。私はstraceを使ってカーネルを調べることにしましたが、snmpdサービスがsnmpリクエストに応答する前にgettimeofdayを何度も呼び出そうとすることがわかりました。 Debian 8 や Centos 6.3 を実行している他の Linux システムとは異なり、snmpd サービスは gettimeofday をまったく呼び出すことはありません。これが私が得た結果です:
rpm --query centos-release
centos-release-6-9.el6.12.3.x86_64
service snmpd status
snmpd (pid 28244) is running...
strace -r -e trace=gettimeofday -p 28244
Process 28244 attached
0.000000 gettimeofday({1516589055, 372419}, NULL) = 0
0.000048 gettimeofday({1516589055, 372448}, NULL) = 0
0.000015 gettimeofday({1516589055, 372463}, NULL) = 0
0.000015 gettimeofday({1516589055, 372477}, NULL) = 0
0.003271 gettimeofday({1516589055, 375751}, NULL) = 0
0.000013 munmap(0x7f1950abf000, 4096) = 0
0.000086 open("/proc/sys/net/ipv6/conf/eth3/forwarding", O_RDONLY) = 11
0.000028 fstat(11, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
0.000015 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1950abf000
0.000015 read(11, "0\n", 1024) = 2
0.000017 close(11) = 0
0.000012 munmap(0x7f1950abf000, 4096) = 0
0.000017 open("/proc/sys/net/ipv6/neigh/eth3/base_reachable_time_ms", O_RDONLY) = 11
0.000017 fstat(11, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
0.000013 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1950abf000
0.000014 read(11, "30000\n", 1024) = 6
0.000016 close(11) = 0
0.000012 munmap(0x7f1950abf000, 4096) = 0
0.000015 read(9, "", 1024) = 0
0.000026 close(9) = 0
0.000015 munmap(0x7f1950ac0000, 4096) = 0
0.000014 close(10) = 0
0.000028 gettimeofday({1516099695, 497691}, NULL) = 0
0.000015 gettimeofday({1516099695, 497705}, NULL) = 0
0.000012 gettimeofday({1516099695, 497718}, NULL) = 0
0.000016 gettimeofday({1516099695, 497734}, NULL) = 0
0.000012 gettimeofday({1516099695, 497746}, NULL) = 0
0.000013 gettimeofday({1516099695, 497758}, NULL) = 0
CentOS 6.3を実行している他のLinuxシステムでsnmpdサービスのstrace結果を比較してみてください。
rpm --query centos-release
centos-release-6-3.el6.centos.9.x86_64
Process 4566 attached - interrupt to quit
0.000000 select(10, [4 6 7 9], [], [], {1, 160003}) = 0 (Timeout)
1.161298 open("/proc/diskstats", O_RDONLY) = 10
0.000109 fstat(10, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
0.000245 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e1d035000
0.000047 read(10, " 1 0 ram0 0 0 0 0 0 0 0 "..., 1024) = 1024
0.000109 read(10, "0 sda 240731 163874 8048386 2853"..., 1024) = 611
0.000061 read(10, "", 1024) = 0
0.000023 close(10) = 0
0.000064 munmap(0x7f6e1d035000, 4096) = 0
0.000036 open("/proc/stat", O_RDONLY) = 10
0.000034 read(10, "cpu 3775592 27347 3516548 70619"..., 4095) = 866
0.000056 close(10) = 0
0.000028 open("/proc/vmstat", O_RDONLY) = 10
0.000031 read(10, "nr_free_pages 75722\nnr_inactive_"..., 4095) = 1964
0.000042 close(10) = 0
0.000037 select(10, [4 6 7 9], [], [], {4, 999068}) = 0 (Timeout)
5.003442 open("/proc/diskstats", O_RDONLY) = 10
0.000082 fstat(10, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
0.000034 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e1d035000
0.000029 read(10, " 1 0 ram0 0 0 0 0 0 0 0 "..., 1024) = 1024
0.000126 read(10, "0 sda 240731 163874 8048386 2853"..., 1024) = 611
0.000045 read(10, "", 1024) = 0
0.000023 close(10) = 0
0.000076 munmap(0x7f6e1d035000, 4096) = 0
0.000036 open("/proc/stat", O_RDONLY) = 10
0.000037 read(10, "cpu 3775592 27347 3516551 70619"..., 4095) = 866
0.000084 close(10) = 0
0.000045 open("/proc/vmstat", O_RDONLY) = 10
0.000035 read(10, "nr_free_pages 75722\nnr_inactive_"..., 4095) = 1964
0.000100 close(10) = 0
0.000055 select(10, [4 6 7 9], [], [], {2, 88417}
snmpdサービスがリクエストに応答する前にgettimeofdayを何度も呼び出すようにする特定の設定はありますか?
よろしくお願いします。
答え1
明らかにいくつかの問題があります。 TZ変数を設定すると、問題を解決できます。数千時間ライブラリがエンコードされる方法によるシステムコール。
実際にあなたの質問に関連しているので、フィードバックが必要です。
~から何千ものシステムコールを防ぐためにTZ環境変数を設定する方法
タイムゾーンを更新しない(またはタイムゾーンの更新中にプロセスを再開できる)サーバープロセスへの追加のシステムコールを回避するには、TZ環境変数を/ etc / localtime(または他のタイムゾーンファイル)に設定するだけです。選択)))プロセスです。これにより、glibcが追加(および不要)システムコールを防ぐことができます。
glibcのlocaltime関数は、TZ環境変数が設定されていることを確認することがわかりました。設定されていない場合(テストした両方のUbuntuに設定されていない場合)、glibcはlocaltimeを呼び出すたびにstatシステムコールを使用します。
つまり、システムは、カーネルに切り替えるコストを避けるために、LinuxカーネルのvDSOを介したタイムアウトシステムコール呼び出しをサポートします。ただし、プログラムが time を呼び出すとすぐに localtime を呼び出し、とにかくシステム呼び出しを呼び出します。したがって、vDSOを使用してあるシステムコールを削除し、それを別のシステムコールに置き換えました。
ファイルアクセスはしばしば時間依存システムコールも使用することに注意してください。 SNMP構成ファイルの名前の代わりに数値MIBSを使用してみてください。 (最初にのみ影響し、snmpd
それ以降はあまり影響しません)。
新しいファイルアクセスは時間依存システムコールを利用するため、起動時にこれらのいくつかを見るのが一般的です。snmpd
MIBがインストールされていないシステムとMIBがインストールされている他のシステムとを比較できます。