如何解决高CPU +过多stat(“/ etc / localtime”)和clock_gettime(CLOCK_REALTIME)调用

我一直在Ruby on Rails应用程序上遇到了非常高的CPU(请参阅下面的堆栈),并试图诊断可能的原因无济于事。

堆栈:

  • ruby1.9.3
  • 导轨3.2.6
  • Apache / 2.2.21(Debian
  • Phusion Passenger 3.0.11

每当我对spiking Rack进程PID运行strace见下面的顶部摘录 ),我看到一吨stat("/etc/localtime")clock_gettime(CLOCK_REALTIME)调用,不知道如何停止这些。

摘录自顶部showin运行PID:

  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 11674 www-user 20 0 313m 182m 5076 R 99 2.3 63:04.60 Rack: /var/www/my_rails_app/current 11634 www-user 20 0 411m 216m 5144 S 10 2.7 197:55.63 Rack: /var/www/my_rails_app/current 

下面的Strace片段:

 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 141474018}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 141577456}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 143073982}) = 0 [pid 11674] poll([{fd=15, events=POLLIN|POLLPRI}], 1, 0) = 0 (Timeout) [pid 11674] write(15, "b\0\0\0\3SELECT `images`.* FROM `ima"..., 102) = 102 [pid 11674] read(15, "\1\0\0\1\0229\0\0\2\3def\23myappy_productio"..., 16384) = 2063 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 144138035}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 ... [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=118, ...}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 154076443}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 154189429}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 157185700}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 157298770}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 165076003}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 165212572}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 167542679}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354058955, 167683436}) = 0 .... [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 62052248}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 62182486}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 62919948}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 63057266}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 63751707}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 73730686}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 75874687}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 76077133}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 78205019}) = 0 ... [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 89370879}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 89583247}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 91637614}) = 0 [pid 11674] clock_gettime(CLOCK_REALTIME, {1354060036, 91782149}) = 0 

有谷歌已经周围,并遇到了一些我已经尝试没有成功的build议。

事情到目前为止:

  1. 尝试按照这里推荐的设置时区
    没有区别,问题依然存在。
    我的/ etc / localtime的内容:

    TZif2UTCTZif2UTC
    UTC0

  2. 已经尝试了build议的修补程序来解决这个问题:

    date – 'date'

迄今为止没有喜乐。

我刚刚出来的想法,所以任何帮助/build议如何诊断或解决将不胜感激。

我发现过多的统计到/ etc / localtime是由于缺less环境variables。

尝试这个:

 echo $TZ 

如果它是空白的,然后将variables设置在正确的位置(即/home/apache/.bash_profile)。 您需要为负责运行您的Web服务器的用户进行设置,然后重新加载守护进程(apachectl graceful等)。

 TZ='Europe/London'; export TZ 

或者是你所在地区的正确时区( http://en.wikipedia.org/wiki/List_of_tz_database_time_zones )。

导出TZ =:/ etc / localtime也可以工作 – 它将在启动时读取文件,而不会再次 – 这意味着守护进程将需要重新启动,如果你改变了这个文件的内容。

但是,像你一样,我们也在我们所有的服务器上运行UTC,所以它永远不会改变。

不能帮助你在“clock_gettime” – 但是,我会说在VM上我们发现time()是非常昂贵的,所以我们有一个守护进程,分配一些共享内存,并把时间放在那里,然后所有进程想知道时间附加到并读取共享内存,而不是使用time() fn。