我在 AWS EC2 大型实例上有一个 <20MB pdf 文件的目录(每个 pdf 代表一个广告)。我正在尝试使用 ruby 和 DM-Paperclip 将每个 pdf 文件上传到 S3。
大多数文件都成功上传,但有些文件似乎需要几个小时才能使 CPU 挂在 100%。我通过在相关部分打印调试语句找到了导致问题的代码行。
# Takes an array of pdf file paths and uploads each to S3 using dm-paperclip
def save_pdfs(pdfs_files)
pdf_files.each do |path|
pdf = File.open(path)
ad = Ad.new
ad.pdf.assign(pdf) # <= Last debug statment is printed before this line
begin
ad.save
rescue => e
# log error
ensure
pdf.close
end
end
为了帮助解决问题,我在进程卡在 100% 时附加了 strace。结果是数十万行这样的:
...
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3543, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3543, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3543, ...}) = 0
... 500K lines
其次是几千:
...
brk(0x1224d0000) = 0x1224d0000
brk(0x1224f3000) = 0x1224f3000
brk(0x122514000) = 0x122514000
...
在不挂起的上传期间,strace 看起来像这样:
...
ppoll([{fd=12, events=POLLOUT}], 1, NULL, NULL, 8) = 1 ([{fd=12, revents=POLLOUT}])
fstat(12, {st_mode=S_IFSOCK|0777, st_size=0, ...}) = 0
fcntl(12, F_GETFL) = 0x2 (flags O_RDWR)
write(12, "%PDF-1.3\n%\342\343\317\323\n8 0 obj\n<</Filter"..., 4096) = 4096
ppoll([{fd=12, events=POLLOUT}], 1, NULL, NULL, 8) = 1 ([{fd=12, revents=POLLOUT}])
write(12, "S\34\367\23~\277u\272,h\204_\35\215\35\341\347\324\310\307u\370#\364\315\t~^\352\272\26\374"..., 4096) = 4096
ppoll([{fd=12, events=POLLOUT}], 1, NULL, NULL, 8) = 1 ([{fd=12, revents=POLLOUT}])
write(12, "\216%\267\2454`\350\177\4\36\315\211\7B\217g\33\217!e\347\207\256\264\245vy\377\304\256\307\375"..., 4096) = 4096
...
导致此问题的 pdf 文件似乎是随机的。它们都是有效的pdf文件,而且都比较小。它们在 ~100KB 到 ~50MB 之间变化。
看似过多的 stat 系统调用的 strace 是否与我的问题有关?