[转帖]Tuxedo 服务器挂起模式_MQ, Tuxedo及OLTP讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MQ, Tuxedo及OLTP讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4267 | 回复: 0   主题: [转帖]Tuxedo 服务器挂起模式        下一篇 
鲲鹏展翅
注册用户
等级:少校
经验:1148
发帖:79
精华:9
注册:2012-11-19
状态:离线
发送短消息息给鲲鹏展翅 加好友    发送短消息息给鲲鹏展翅 发消息
发表于: IP:您无权察看 2012-11-21 15:00:55 | [全部帖] [楼主帖] 楼主

问题描述
在 Tuxedo 应用程序中,Tuxedo 中的进程无法完成它们的当前工作、不响应新的请求且通常还会占用少量的 CPU 资源。对于异常高 CPU 占用率问题,请参考“异常高 CPU 占用率支持模式”。

故障排除

为什么发生此问题?
通常服务器挂起是因为缺少某些资源。由于缺少资源或资源上有互斥锁,进程无法获取所需的资源,也就不能对新请求做出响应。例如,一个想要使用共享内存的进程会等待,直到某个进程通过发出信号释放锁定,如果没有释放,等待的进程就会挂起。

可能的原因:

死锁

资源阻塞

休眠循环

超时

异常高 CPU 占用率 -- 请参考“异常高 CPU 占用率支持模式”。

故障探查
此故障探查的目的是搜索挂起服务器的堆栈信息,然后对其进行分析以找出服务器挂起的原因。

如何确定服务器是否挂起?故障探查的步骤将是:
  • 使用 Tuxedo 管理工具“tmadmin”。

  • 使用命令“pq”检查 Tuxedo 队列中的请求。

  • 使用命令“psr”检查 Tuxedo 服务器的状态。

  • 使用操作系统专有的实用程序检查此 Tuxedo 服务器在操作系统中的 CPU 占用情况。

  • 使用操作系统调试工具(如 truss、strace、gdb、dbx 等)查明服务器具体是在哪一个系统调用或 API 上挂起的。

  • 或通过“kill”到进程的“SIGABRT”信号生成挂起服务器的二进制核心文件转储。通过使用调试工具调试二进制核心文件可以查明进程在何处挂起。请参考二进制核心文件转储支持模式。
对于有关收集服务器挂起的数据的特定操作信息,请根据您的操作系统执行以下步骤。

Solaris
  1. 运行“tmadmin”来检查服务器状态。

1) 使用“pq”来收集请求队列中的请求信息。

例如:echo pq tmadmin

可以使用下列 Shell 脚本来协助进行数据收集:
pq.sh t [n]   (将按 n 个 t 秒的间隔输出结果)。

#!/usr/bin/sh
if test -z "$1"
then
    sleep_time=0
else
    sleep_time=$1
fi

if test -z "$2"
then
    loopnum=1
else
    loopnum=$2
fi
num=0
while [ $num -lt $loopnum ]
do
    num=`echo "$num + 1" | bc`
    echo pq | tmadmin 2>/dev/null
    sleep $sleep_time
done

输出将会是:


$ 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
>

查看“#Queued”列的值时您会发现,某些服务器在很长时间内只增不降。请记录这些服务器的队列名称。


上例中,可疑的服务器是 simpserv,队列名称为:00001.00100。

2) 使用“psr”检查服务器状态。

echo psr -q queue_name tmadmin 2>/dev/null grep process_name

$ echo psr -q 00001.00100 | tmadmin 2>/dev/null | grep simpserv

simpserv   00001.00100   GROUP1   100   0   0   TOUPPER

这样可以显示正在处理客户端请求的服务器。第四列为服务器的 SRV_ID。


在本例中,simpserv 正在处理“TOUPPER”服务,其 SRV_ID 为 100。

3) 运行“tmadmin”,将 verbose 设置为开启并使用 SRV_ID 探查服务器。

$ tmadmin

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

Verbose now on.

> psr -i 100

Group ID: GROUP1, Server ID: 100

Machine ID: simple

Process ID: 16979 , Request Qaddr: 905, Reply Qaddr: 905

Server Type: USER

Prog Name: /home/yhuang/apps/simpapp/simpserv

Queue Name: 00001.00100

Options: ( none )

Generation: 1, Max message type: 1073741824

Creation time: Fri Sep 24 00:44:42 2004

Up time: 0:06:26

Requests done: 0

Load done: 0

Current Service: TOUPPER

然后即可获取可疑的 Tuxedo 服务器的进程 ID。其 PID 为 16979。

  1. 运行 ps 命令来确认 Tuxedo 服务器的 PID。

$ 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 -
  1. 运行 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
  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
  1. 运行 tmadmin 命令来检查服务器状态。(与 Solaris 上相同。)
  1. 运行 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   失效进程(“僵”进程)

  1. 运行 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
  1. 运行 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
  1. 运行 tmadmin 命令来检查服务器状态。(与 Solaris 上相同。)
  1. 运行 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
  1. 运行 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
  1. 运行 tmadmin 命令来检查服务器状态。(与 Solaris 上相同。)

  1. 运行 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/

输出的第二列为 PID。其值为 17054。

  1. 运行 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   增长中

  1. 运行 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

  1. 运行 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。

  1. 运行 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。

  1. 运行 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
  1. 运行 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 请求的函数将把意愿转换为系统调用读写。

死锁:不同服务器中的服务相互调用

  • 情况
    1. 假设有两个名为 SVR_A 和 SVR_B 的 Tuxedo 服务器,而且它们都有许多服务。例如,SVR_A 包括两个名为 SVCA1 和 SVCA2 的服务。SVR_B 包括两个名为 SVCB1 和 SVCB2 的服务。

    1. 在我们的 Tuxedo 应用程序中,服务 SVCA1 tpcall SVCB1,服务 SVCB2 tpcall SVCA2。

    1. 如果只 tmboot 一个服务器 (SVR_A) 且只有一个服务器 (SVR_B) 和我们的 Tuxedo 客户端应用程序在同时 tpcall SVCA1 和 SVCB2,则服务器 SVR_A 和 SVR_B 都可能会挂起。

  • 分析

    正如我们所知,客户端 tpcall 服务器时,请求消息将被发送到服务器的请求队列中。随后调用 msgrecv() 的进程将使此消息出队并处理请求。在此进程调用 tpreturn 前,没有服务器会监听请求队列。

    不过,在本例中,客户端应用程序同时 tpcall SVR_A 和 SVR_B。它们可能会具有下列状态。SVR_A 已做好处理消息的准备,但需要 tpcall SVR_B(例如,SVCA1 tpcall SVCB1),同时 SVR_B 也做好了处理消息的准备,但需要 tpcall SVR_A(例如,SVCB2 tpcall SVCA2)。因此,SVR_A 向 SVR_B 发送消息时会发生阻塞,直至其得到 SVR_B 的响应为止。与此同时,SVR_B 向 SVR_A 发送消息时也会发生阻塞,直至其得到 SVR_A 的响应为止。我们只想 tmboot 一个 SVR_A 和一个 SVR_B,而现在二者都发生了阻塞。显然,SVR_B 无法处理 SVR_A 的请求,SVR_A 也无法处理 SVR_B 的请求。因此,SVR_A 和 SVR_B 都会挂起或陷入死锁状态。

  • 解决办法

    将服务 SVCA2 和 SVCB1 嵌入到两个新服务器中,确保它们互不依存。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论