strace和lsof的学习
一、strace
该命令为了跟踪进程的系统调用情况。如果进程有问题,可以根据该命令去排查,看看哪里出现了问题。
一个例子:
我在command定义一个执行函数:
public function handle()
{
$re = CFDailyFinanceProcessor::getAllNeedDealGids();
var_dump($re);
}
该函数直接从Redis中读取数据。
strace -c -tt php artisan test:run
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
15.38 0.002556 3 857 mmap
12.67 0.002105 1 2534 3 fstat
11.95 0.001985 3 787 3 openat
11.48 0.001908 3 717 munmap
9.59 0.001593 8 192 mprotect
8.59 0.001427 2 880 11 stat
7.33 0.001217 2 797 close
6.54 0.001087 1 1047 6 lstat
4.04 0.000672 5 138 read
3.01 0.000500 2 224 65 access
2.74 0.000456 6 80 rt_sigaction
2.09 0.000348 2 142 getdents
1.00 0.000166 7 24 brk
0.93 0.000155 2 80 6 lseek
0.81 0.000134 3 41 37 ioctl
0.76 0.000126 5 23 futex
0.11 0.000019 19 1 1 connect
0.11 0.000019 6 3 getrandom
0.10 0.000016 5 3 poll
0.10 0.000016 8 2 readlink
0.09 0.000015 5 3 getcwd
0.08 0.000014 7 2 sendto
0.08 0.000013 4 3 write
0.07 0.000012 4 3 socket
0.07 0.000011 4 3 prlimit64
0.06 0.000010 2 6 fcntl
0.05 0.000008 3 3 getpid
0.04 0.000006 3 2 recvfrom
0.04 0.000006 6 1 sysinfo
0.02 0.000004 1 3 uname
0.02 0.000003 2 2 rt_sigprocmask
0.02 0.000003 3 1 getsockopt
0.01 0.000002 1 3 dup
0.01 0.000002 2 1 wait4
0.00 0.000000 0 2 pipe
0.00 0.000000 0 1 clone
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 arch_prctl
0.00 0.000000 0 1 set_tid_address
0.00 0.000000 0 1 set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00 0.016614 8615 132 total
直接不加参数:
strace -o /tmp/out.log php artisan test:run
lstat("/home/work/admin/config/resp_codes.php", {st_mode=S_IFREG|0664, st_size=656, ...}) = 0
stat("/home/work/admin/config/resp_codes.php", {st_mode=S_IFREG|0664, st_size=656, ...}) = 0
lstat("/home/work/admin/config/resp_codes.php", {st_mode=S_IFREG|0664, st_size=656, ...}) = 0
lstat("/home/work/admin/config/filesystems.php", {st_mode=S_IFREG|0664, st_size=2543, ...}) = 0
stat("/home/work/admin/config/filesystems.php", {st_mode=S_IFREG|0664, st_size=2543, ...}) = 0
lstat("/home/work/admin/config/filesystems.php", {st_mode=S_IFREG|0664, st_size=2543, ...}) = 0
lstat("/home/work/admin/config/permission.php", {st_mode=S_IFREG|0664, st_size=844, ...}) = 0
stat("/home/work/admin/config/permission.php", {st_mode=S_IFREG|0664, st_size=844, ...}) = 0
lstat("/home/work/admin/config/permission.php", {st_mode=S_IFREG|0664, st_size=844, ...}) = 0
lstat("/home/work/admin/config/app.php", {st_mode=S_IFREG|0664, st_size=9357, ...}) = 0
stat("/home/work/admin/config/app.php", {st_mode=S_IFREG|0664, st_size=9357, ...}) = 0
lstat("/home/work/admin/config/app.php", {st_mode=S_IFREG|0664, st_size=9357, ...}) = 0
lstat("/home/work/admin/config/session.php", {st_mode=S_IFREG|0664, st_size=6872, ...}) = 0
stat("/home/work/admin/config/session.php", {st_mode=S_IFREG|0664, st_size=6872, ...}) = 0
lstat("/home/work/admin/config/session.php", {st_mode=S_IFREG|0664, st_size=6872, ...}) = 0
lstat("/home/work/admin/config/database.php", {st_mode=S_IFREG|0664, st_size=9335, ...}) = 0
stat("/home/work/admin/config/database.php", {st_mode=S_IFREG|0664, st_size=9335, ...}) = 0
lstat("/home/work/admin/config/database.php", {st_mode=S_IFREG|0664, st_size=9335, ...}) = 0
lstat("/home/work/admin/config/cache.php", {st_mode=S_IFREG|0664, st_size=2682, ...}) = 0
stat("/home/work/admin/config/cache.php", {st_mode=S_IFREG|0664, st_size=2682, ...}) = 0
lstat("/home/work/admin/config/cache.php", {st_mode=S_IFREG|0664, st_size=2682, ...}) = 0
lstat("/home/work/admin/config/admin.php", {st_mode=S_IFREG|0664, st_size=4968, ...}) = 0
stat("/home/work/admin/config/admin.php", {st_mode=S_IFREG|0664, st_size=4968, ...}) = 0
lstat("/home/work/admin/config/admin.php", {st_mode=S_IFREG|0664, st_size=4968, ...}) = 0
lstat("/home/work/admin/config/auth.php", {st_mode=S_IFREG|0664, st_size=3351, ...}) = 0
stat("/home/work/admin/config/auth.php", {st_mode=S_IFREG|0664, st_size=3351, ...}) = 0
lstat("/home/work/admin/config/auth.php", {st_mode=S_IFREG|0664, st_size=3351, ...}) = 0
lstat("/home/work/admin/config/services.php", {st_mode=S_IFREG|0664, st_size=980, ...}) = 0
stat("/home/work/admin/config/services.php", {st_mode=S_IFREG|0664, st_size=980, ...}) = 0
lstat("/home/work/admin/config/services.php", {st_mode=S_IFREG|0664, st_size=980, ...}) = 0
lstat("/home/work/admin/config/queue.php", {st_mode=S_IFREG|0664, st_size=2617, ...}) = 0
stat("/home/work/admin/config/queue.php", {st_mode=S_IFREG|0664, st_size=2617, ...}) = 0
lstat("/home/work/admin/config/queue.php", {st_mode=S_IFREG|0664, st_size=2617, ...}) = 0
lstat("/home/work/admin/config/business.php", {st_mode=S_IFREG|0664, st_size=58, ...}) = 0
stat("/home/work/admin/config/business.php", {st_mode=S_IFREG|0664, st_size=58, ...}) = 0
lstat("/home/work/admin/config/business.php", {st_mode=S_IFREG|0664, st_size=58, ...}) = 0
lstat("/home/work/admin/config/broadcasting.php", {st_mode=S_IFREG|0664, st_size=1604, ...}) = 0
stat("/home/work/admin/config/broadcasting.php", {st_mode=S_IFREG|0664, st_size=1604, ...}) = 0
lstat("/home/work/admin/config/broadcasting.php", {st_mode=S_IFREG|0664, st_size=1604, ...}) = 0
lstat("/home/work/admin/config/view.php", {st_mode=S_IFREG|0664, st_size=1004, ...}) = 0
stat("/home/work/admin/config/view.php", {st_mode=S_IFREG|0664, st_size=1004, ...}) = 0
lstat("/home/work/admin/config/view.php", {st_mode=S_IFREG|0664, st_size=1004, ...}) = 0
lstat("/home/work/admin/config/order_type.php", {st_mode=S_IFREG|0664, st_size=4256, ...}) = 0
stat("/home/work/admin/config/order_type.php", {st_mode=S_IFREG|0664, st_size=4256, ...}) = 0
lstat("/home/work/admin/config/order_type.php", {st_mode=S_IFREG|0664, st_size=4256, ...}) = 0
lstat("/home/work/admin/config/image.php", {st_mode=S_IFREG|0664, st_size=508, ...}) = 0
stat("/home/work/admin/config/image.php", {st_mode=S_IFREG|0664, st_size=508, ...}) = 0
lstat("/home/work/admin/config/image.php", {st_mode=S_IFREG|0664, st_size=508, ...}) = 0
lstat("/home/work/admin/config/mer.php", {st_mode=S_IFREG|0664, st_size=4089, ...}) = 0
stat("/home/work/admin/config/mer.php", {st_mode=S_IFREG|0664, st_size=4089, ...}) = 0
lstat("/home/work/admin/config/mer.php", {st_mode=S_IFREG|0664, st_size=4089, ...}) = 0
lstat("/home/work/admin/config/mail.php", {st_mode=S_IFREG|0664, st_size=4212, ...}) = 0
stat("/home/work/admin/config/mail.php", {st_mode=S_IFREG|0664, st_size=4212, ...}) = 0
lstat("/home/work/admin/config/mail.php", {st_mode=S_IFREG|0664, st_size=4212, ...}) = 0
其实这只是部分文件,其实后面还有很多,也就是一个console命令,需要执行很多stat的调用。可以看上面都是laravel的配置文件。
最后才到了Redis部分,从建立socket开始
socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP) = 5
close(5) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 5
fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(5, {sa_family=AF_INET, sin_port=htons(6379), sin_addr=inet_addr("10.38.163.219")}, 16) = -1 EINPROGRESS (Operation now in progress)
poll([{fd=5, events=POLLIN|POLLOUT|POLLERR|POLLHUP}], 1, 5000) = 1 ([{fd=5, revents=POLLOUT}])
getsockopt(5, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
fcntl(5, F_SETFL, O_RDWR) = 0
lstat("/home/work/admin/vendor/composer/../predis/predis/src/Response/ResponseInterface.php", {st_mode=S_IFREG|0664, st_size=417, ...}) = 0
openat(AT_FDCWD, "/home/work/admin/vendor/predis/predis/src/Response/ResponseInterface.php", O_RDONLY) = 6
fstat(6, {st_mode=S_IFREG|0664, st_size=417, ...}) = 0
fstat(6, {st_mode=S_IFREG|0664, st_size=417, ...}) = 0
fstat(6, {st_mode=S_IFREG|0664, st_size=417, ...}) = 0
fstat(6, {st_mode=S_IFREG|0664, st_size=417, ...}) = 0
mmap(NULL, 417, PROT_READ, MAP_SHARED, 6, 0) = 0x7f43993c3000
munmap(0x7f43993c3000, 417) = 0
close(6) = 0
sendto(5, "*2\r\n$8\r\nSMEMBERS\r\n$22\r\nmerchant/"..., 47, 0, NULL, 0) = 47
poll([{fd=5, events=POLLIN|POLLERR|POLLHUP}], 1, -1) = 1 ([{fd=5, revents=POLLIN}])
recvfrom(5, "*1\r\n$6\r\n103512\r\n", 8192, 0, NULL, NULL) = 16
write(1, "array(1) {\n", 11array(1) {
) = 11
write(1, " [0]=>\n", 8 [0]=>
) = 8
write(1, " ", 2 ) = 2
write(1, "string(6) \"", 11string(6) ") = 11
write(1, "103512", 6103512) = 6
write(1, "\"\n", 2"
) = 2
write(1, "}\n", 2}
) = 2
lstat("/home/work/admin/vendor/composer/../laravel/framework/src/Illuminate/Console/Events/CommandFinished.php", {st_mode=S_IFREG|0664, st_size=1196, ...}) = 0
openat(AT_FDCWD, "/home/work/admin/vendor/laravel/framework/src/Illuminate/Console/Events/CommandFinished.php", O_RDONLY) = 6
fstat(6, {st_mode=S_IFREG|0664, st_size=1196, ...}) = 0
fstat(6, {st_mode=S_IFREG|0664, st_size=1196, ...}) = 0
fstat(6, {st_mode=S_IFREG|0664, st_size=1196, ...}) = 0
fstat(6, {st_mode=S_IFREG|0664, st_size=1196, ...}) = 0
mmap(NULL, 1196, PROT_READ, MAP_SHARED, 6, 0) = 0x7f43993c3000
除了可以在应用中使用,还可以直接指定进程 -p pid进程号。
1、strace较好的教程: strace使用教程
2、strace使用的几个场景: strace使用场景
二、lsof
通过man查看一下,其作用就是list all open files
lsof命令可以看到某个进程pid调用的所有资源,如果存在大量的can’t identify protocol,说明有socket泄漏,未正常关闭。
当然如果出现泄漏,那么也可以查看含有最多句柄的进程。
lsof -n|awk '{print $2}'| sort | uniq -c | sort -nr | head -n 20
当然,有时我们想清理磁盘空间,但是du却看不见。就可以看看有些大文件是不是处于deleted状态。
lsof |grep deleted
Linux中一切皆文件,block,reg,dir,ipv4等等都可以,因此我们也可以查看当前系统所建立的连接。
lsof -i
查看tcp: lsof -i tcp
例子:
java 4098 haibo 110u IPv6 6412279 0t0 TCP *:9092 (LISTEN)
java 4228 haibo 247u IPv6 6410736 0t0 TCP *:9300 (LISTEN)
java 4228 haibo 296u IPv6 6410745 0t0 TCP *:9500 (LISTEN)
java 4228 haibo 297u IPv6 6409105 0t0 TCP localhost:9500->localhost:57306 (ESTABLISHED)
java 4228 haibo 298u IPv6 6409107 0t0 TCP localhost:9500->localhost:57314 (ESTABLISHED)
java 4228 haibo 299u IPv6 6413823 0t0 TCP localhost:9500->localhost:57316 (ESTABLISHED)
java 4228 haibo 300u IPv6 6413824 0t0 TCP localhost:9500->localhost:57324 (ESTABLISHED)
java 4228 haibo 301u IPv6 6412755 0t0 TCP localhost:9500->localhost:57326 (ESTABLISHED)
java 4228 haibo 302u IPv6 6412756 0t0 TCP localhost:9500->localhost:57328 (ESTABLISHED)
java 4228 haibo 303u IPv6 6410798 0t0 TCP localhost:9500->localhost:57330 (ESTABLISHED)
java 4228 haibo 312u IPv6 6418686 0t0 TCP localhost:9500->localhost:57340 (ESTABLISHED)
java 4228 haibo 313u IPv6 6414618 0t0 TCP localhost:9500->localhost:57342 (ESTABLISHED)
java 4228 haibo 314u IPv6 6412767 0t0 TCP localhost:9500->localhost:57344 (ESTABLISHED)
java 4228 haibo 315u IPv6 6403971 0t0 TCP localhost:9500->localhost:57346 (ESTABLISHED)
java 4228 haibo 316u IPv6 6403972 0t0 TCP localhost:9500->localhost:57348 (ESTABLISHED)
java 4228 haibo 317u IPv6 6413906 0t0 TCP localhost:9500->localhost:57350 (ESTABLISHED)
java 4228 haibo 318u IPv6 6409121 0t0 TCP localhost:9500->localhost:57352 (ESTABLISHED)
java 4228 haibo 319u IPv6 6409122 0t0 TCP localhost:9500->localhost:57354 (ESTABLISHED)
java 4228 haibo 320u IPv6 6418327 0t0 TCP localhost:9500->localhost:57356 (ESTABLISHED)
java 4228 haibo 321u IPv6 6409123 0t0 TCP localhost:9500->localhost:57358 (ESTABLISHED)
java 4228 haibo 322u IPv6 6412769 0t0 TCP localhost:9500->localhost:57360 (ESTABLISHED)
java 4228 haibo 327u IPv6 6413917 0t0 TCP localhost:9500->localhost:57374 (ESTABLISHED)
node 4229 haibo 18u IPv4 6418471 0t0 TCP *:5601 (LISTEN)
一般情况下,strace和lsof可以配合着使用。
微信分享/微信扫码阅读