$ pq.sh 5 3 > Prog Name  Queue Name   # Serve Wk Queued   # Queued Ave. Len Machine
--------- ------------------- --------- -------- -------- -------
simpserv   00001.00100   1  100  2    0.0   simple
BBL           222222     1   0   0    0.0   simple
>
> Prog Name  Queue Name   # Serve Wk Queued   # Queued Ave. Len Machine
--------- ------------------- --------- -------- -------- -------
simpserv   00001.00100   1  250   5   0.0   simple
BBL          222222      1   0    0    0.0   simple
>
> Prog Name  Queue Name   # Serve Wk Queued   # Queued Ave. Len Machine
--------- ------------------- --------- -------- -------- -------
simpserv    00001.00100   1  400   8    0.0   simple
BBL            222222     1   0    0    0.0   simple
>
tmadmin - Copyright (c) 1996-1999 BEA Systems, Inc.
Portions * Copyright 1986-1997 RSA Data Security, Inc.
All Rights Reserved.
Distributed under license by BEA Systems, Inc.
Tuxedo is a registered trademark.
Verbose now on.
$ ps -ef grep simpserv
yhuang 16979 1 0 22:56:28 pts/10 0:00 simpserv -C dom=simpapp -g 1 -i 1 -u slsol3 -U /home/yhuang/apps/simpapp/ULOG - - 运行 prstat 来探查此进程的 CPU 占用率: 
 prstat -L -p <PID> 1 1 
$ prstat -L -p 16979 1 1 
    PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWPID
16134  yhuang  6256K  3520K  sleep  59  0  0:00.00  0.0%  simpserv/5
16134  yhuang  6256K  3520K  sleep  58  0  0:00.00  0.0%  simpserv/4
16134  yhuang  6256K  3520K  sleep  45  0  0:00.00  0.0%  simpserv/3
16134  yhuang  6256K  3520K  sleep  56  0  0:00.00  0.0%  simpserv/2
16134  yhuang  6256K  3520K  sleep  58  0  0:00.00  0.0%  simpserv/1 - 运行 pstack 命令来检查线程堆栈信息。 
pstack 命令可以列出特定进程的线程堆栈信息。堆栈中的“main”函数将是运行时系统调用的起始点,而且堆栈可以协助您确定 Tuxedo 服务器具体是在哪一个系统调用或 API 上挂起的。
例如,可以在以下堆栈信息中了解到,服务器是在系统调用“sleep”中挂起的。
$ pstack 16979
16979: simpserv -C dom=simpapp -g 1 -i 1 -u slsol3 -U /home/yhuang/apps/simpa
----------------- lwp# 1 / thread# 1 --------------------
fef1f004 lwp_sema_wait (20fe0)
fee39ac4 _park (20fe0, fee5e000, 0, 20f20, 24d84, 0) + 114
fee3978c _swtch (20f20, 0, fee5e000, 5, 1000, 0) + 424
fee37e10 cond_reltimedwait (0, 0, 0, 1, 0, 0) + 1f8
fee496c4 sleep (0, fe28c6e8, 44340, ff3e7fe8, fee5e000, fef273d0) + 17c
00010a78 TOUPPER (2d20c, ffbef7ec, ffbef7ee, 3, 0, 5) + 68
ff24f8f0 _tmsvcdsp (215c8, ffbef8d4, 0, c0000000, 80000, 1) + e58
ff272454 _tmrunserver (2bd20, ff129430, 0, 0, 27d70, 22c10) + 1064
ff24e668 _tmstartserver (e, ffbefa04, 20ce8, fee9bbd0, 31ea0, 0) + 1b0
00010990 main (e, ffbefa04, ffbefa40, 20c00, 0, 0) + 20
000108f8 _start (0, 0, 0, 0, 0, 0) + 108
Linux
- 运行 tmadmin 命令来检查服务器状态。(与 Solaris 上相同。) 
- 运行 ps 命令来检查服务器状态。 
ps -e -o pid,user,sz,pcpu,state,args grep <process_name> 或 <PID>
$ ps -e -o pid,user,sz,pcpu,state,args | grep simpserv
PID USER SZ %CPU S COMMAND
17553 bea   1098   0.0   S   simpserv -C dom=site1 -g 2 -i 100 -u dell40 -U /usr/ 列 4“%CPU”表示服务器的 CPU 占用率。
列 5“S”列出进程状态,详细含义如下:
D   无法中断的休眠(通常为 IO)
R   可运行(在运行队列上)
S   休眠中
T   已跟踪或已停止
Z   失效进程(“僵”进程) 
- 运行 top 命令,列出服务器进程的 CPU 占用率。  
 top -p <PID> -n 20 
$ top -p 17553 -n 10
PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME COMMAND
17553  qimz   15   0   2116   2116   1504   S  0.0  0.0   0:00   simpserv - 运行 gdb 命令来获取进程堆栈信息  
gdb <prog_path> <PID>
prog_path:可执行文件的路径。 
$ gdb simpserv 17553
(gdb) where
#0 0x402b8cb1 in nanosleep () from /lib/libc.so.6
#1 0x402b8b31 in sleep () from /lib/libc.so.6
#2 0x08048971 in TOUPPER (rqst=0x0) at simpserv.c:41
#3 0x40074775 in _tmrunserver () from /usr/tuxedo/tuxedo8.0/lib/libtux.so
#4 0x400574f5 in _tmstartserver () from /usr/tuxedo/tuxedo8.0/lib/libtux.so
#5 0x0804892a in main ()
#6 0x40219727 in __libc_start_main () from /lib/libc.so.6
(gdb) detach
(gdb) quit 
也可以运行 strace 命令来探查系统调用。
例如:strace -o outfile -p <PID> 
$ strace -o strace.out -p 17553
$ cat strace.out
rt_sigprocmask(SIG_BLOCK, [CHLD], [RTMIN], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [RTMIN], NULL, 8) = 0
nanosleep({1000, 0}, <unfinished ...> 
AIX
- 运行 tmadmin 命令来检查服务器状态。(与 Solaris 上相同。) 
- 运行 ps 命令,获取进程 ID 和进程的 CPU 占用率: 
ps -auxwww grep process_name
$ ps aux | head -n 1; ps aux | grep simpserv
USER   PID   %CPU   %MEM   SZ   RSS   TTY   STAT   STIME   TIME   COMMAND
qimz   3908  0.0  0.0   904   1036   pts/2   A   17:15:26   0:00   simpserv -C dom=A - 运行 dbx 命令,获取进程堆栈信息。 
运行 dbx 命令来探查挂起服务器。进入 dbx,然后输入 where,这样将会输出堆栈信息。在从 dbx 退出前输入 detach,从进程中分离,然后退出 dbx。(只有 AIX5L 提供 truss 工具。)
dbx -a <PID>
$ dbx -a 3908
stopped in _p_nsleep at 0xd0013b34 ($t1)
0xd0013b34 (_p_nsleep+0x10) 80410014 lwz r2,0x14(r1)
(dbx) where
_p_nsleep(??, ??) at 0xd0013b34
raise.nsleep(??, ??) at 0xd018560c
sleep(??) at 0xd01e0250
TOUPPER(0x2002a38c), line 45 in "simpserv.c"
_tmsvcdsp() at 0xd3741b48
_tmrunserver() at 0xd36f30c4
_tmstartserver() at 0xd37a5e94
main(0x12, 0x2ff227bc) at 0x100003f0
(dbx)deatch
HP-UX
- 运行 tmadmin 命令来检查服务器状态。(与 Solaris 上相同。)
 
 
- 运行 ps 命令,获取服务器的进程 ID (PID) 
 ps -ef grep <process_name> 
 下面是输出示例: 
$ ps -ef | gep simpserv
bea   17054  1   0   15:31:24   ?   0:00   simpserv -C dom=tux_ora -g 2 -i 100 -u bea-cs -U /home/qimz/ - 运行 ps 命令,探查服务器进程的状态。 
设置环境变量:export UNIX95=XPG4。
示例:ps -e -o pid,user,sz,pcpu,state,args grep <process_name> 或 <PID>
$ ps -e -o pid,user,sz,pcpu,state,args grep 17054
PID USER SZ %CPU S COMMAND
17054   bea   73   0.02   S   simpserv -C dom=tux_ora -g 2 -i 100 -u bea-cs -U /home/qimz/ 
列 4“%CPU”表示服务器的 CPU 占用率。
列 5“S”列出进程状态,详细含义如下:
0   不存在
S   休眠中
W  等待中
R   运行中
I    中间
Z   已终止
T   已停止
X   增长中 
- 运行 tusc 命令,探查进程的系统调用。 
可从以下 url 下载 HP Unix 上的工具“tusc”:
http://www.hp.com/workstations/segments/mcad/dassault/plmcc/perf_tools.html
使用 tusc 可以获取有关进程系统调用的所有信息。HP UNIX 还提供了使用 tusc 打包的“truss”,其命令行格式如下:
truss -d -o <outfile> -p <pid>
“-d”参数表示列出所有具有时间戳的系统调用。
查看下面的 truss 输出时您可以发现:
服务器进程先是阻塞在 API sigtimedwait 中,一秒钟后,一个信号(返回到 EAGAIN)中断了此系统调用,接着系统函数“time”取得了当前时间,然后调用 sigtimedwait 函数,开始下一个循环。这时您就知道了,进程是在函数“sleep”的循环中挂起的。 
$ truss -o 17054 .out -p 17054
Attached to process 17054 ("simpserv -C dom=tux_ora -g 2 -i 100 -u bea-cs -U /home/qimz/") [32-bit] )
0.0000 sigtimedwait(0x7b040ef0, NULL, 0x7b040f10) [sleeping]
0.8234 sigtimedwait(0x7b040ef0, NULL, 0x7b040f10) ERR#11 EAGAIN
0.8239 time(NULL) = 1032847337
0.8240 time(NULL) = 1032847337
1.8334 sigtimedwait(0x7b040ef0, NULL, 0x7b040f10) ERR#11 EAGAIN
1.8336 time(NULL) = 1032847338
1.8337 time(NULL) = 1032847338
2.8435 sigtimedwait(0x7b040ef0, NULL, 0x7b040f10) ERR#11 EAGAIN
2.8490 time(NULL) = 1032847339
2.8680 time(NULL) = 1032847339
3.8734 sigtimedwait(0x7b040ef0, NULL, 0x7b040f10) ERR#11 EAGAIN
3.8736 time(NULL) = 1032847340
3.8738 time(NULL) = 1032847340
4.8906 sigtimedwait(0x7b040ef0, NULL, 0x7b040f10) ERR#11 EAGAIN
4.8908 time(NULL) = 1032847341
4.8910 time(NULL) = 1032847341 
Windows
- 运行 ipcs 命令,探查队列中的消息。  
 示例:ipcs -qob     (输出 QNUM 的第 7 列列出了消息编号) 
D:\Projects\testcase\simpapp>ipcs -qob
IPCS status from BEA_segV8.1 as of Sat Sep 25 01:18:18 2004
T   ID   KEY   MODE   OWNER   GROUP   CBYTES   QNUM   QBYTES
Message Queues:
q   2305   0x0001e242   -Rrw-rw-rw-   0   0   0   0   65536
q   3074   0x00000000   --rw-rw-rw-   0   0   292   1   65536
q   3843   0x00000000   -Rrw-rw-rw-   0   0   292   1   65536
q   5636   0x00000000   --rw-rw-rw-   0   0   292   1   65536
q   2309   0x00000000   -Rrw-rw-rw-   0   0   292   1   6553
 查明只增不降的 QNUM 的消息队列 ID。 
- 运行 tmadmin 命令,探查此消息队列 ID 的服务器。 
tmadmin < psr.txt
psr.txt 将包含像下面这样的两行:
verbose
psr
verbose 开启时,psr 命令可以列出 Tuxedo 服务器的详细信息,其中包括进程 ID。 
D:\Projects\testcase\simpapp> tmadmin < psr.txt findstr 3843
Process ID: 2008 , Request Qaddr: 3074, Reply Qaddr: 3843 
 获取的 PID 为 2008。 
- 运行 prstat 命令,获取此服务器的 PID 和 CPU 占用率。 可以在 Windows 中使用 pslist 工具,获取挂起进程的“CPU Time”。可以从以下网址下载“pslist”命令工具:http://www.sysinternals.com/ntw2k/freeware/pslist.shtml
 
 
 示例:pslist <PID> 或 <进程名称> 
>pslist 2008
Name   Pid   Pri   Thd   Hnd   Priv   CPU Time Elapsed Time
simpserv   2008   8   1   128   780   0:00:00.040   0:38:55.348
- 运行 strace 命令,探查进程堆栈信息。可从以下网址下载“strace”命令工具:http://www.bindview.com/Support/RAZOR/Utilities/Windows/strace_readme.cfm。
 
 strace -p <PID>
>strace -p 2008
1   356   324   NtDelayExecution (0, {-100000000, -1}, ... ) == 0x0
2   356   324   NtDelayExecution (0, {-100000000, -1}, ... ) == 0x0
3   356   324   NtDelayExecution (0, {-100000000, -1}, ... ) == 0x0
4   356   324 NtDelayExecution (0, {-100000000, -1}, ... ) == 0x0
5   356   324   NtDelayExecution (0, {-100000000, -1}, ... ) == 0x0 
故障排除策略
• 分析服务器挂起时的进程堆栈信息。
• 分析和调试源代码。
• 检查资源缺乏情况。
• 在源代码中添加更多的调试代码。
• 检查操作系统的补丁是否正确。
以下是探查此问题时可能会发生挂起的三种示例情况:
1. 服务器进程在休眠循环中挂起。
2. 服务器进程在等待涉及大量数据的数据库查询的结果。
3. 死锁:不同服务器中的服务相互调用。
返回页首
服务器进程在休眠循环中挂起
运行 truss 或 strace 来探查此问题。使用这些工具可以发现:
系统函数 sleep 调用了另一个系统调用,而该系统调用处于阻塞状态。(在 HP UNIX 中,该系统调用是 sigtimedwait()。)
休眠超时后操作系统将向进程发送一个信号,接着该系统调用被中断并返回错误。错误编号为 EAGAI。
如果运行 gdb 或 dbx 来探查进程,则可在由“where”产生的输出的堆栈信息中找到调用的 sleep 命令。
服务器进程在等待涉及大量数据的数据库查询的结果
- 如果在同一主机中部署数据库和 Tuxedo,则它们将通过 IPC 进行通信,因此可能会出现进程在有关 IPC 的系统调用处阻塞。 
- 如果 Tuxedo 通过套接字访问数据库,则预编译时将把 select、insert、update 这样的 SQL 语句编译到数据库函数中。因此发送 SQL 请求的函数将把意愿转换为系统调用读写。 
死锁:不同服务器中的服务相互调用