我们发现 Web 应用程序存在严重的性能问题,我们正在尝试找出瓶颈。我不是系统管理员,所以有些东西我不太明白。一些基本调查显示 CPU 处于空闲状态,有大量内存可用,没有交换,没有 I/O,但平均负载很高。
该服务器上的软件堆栈如下所示:
- Solaris 10
- Java 1.6
- WebLogic 10.3.5(8 个域)
该服务器上运行的应用程序与另一台服务器上的 Oracle 数据库进行通信。
该服务器有 32GB 的 RAM 和 10 个 CPU(我认为)。
运行prstat -Z
结果如下:
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
3836 ducm0101 2119M 2074M cpu348 58 0 8:41:56 0.5% java/225
24196 ducm0101 1974M 1910M sleep 59 0 4:04:33 0.4% java/209
6765 ducm0102 1580M 1513M cpu330 1 0 1:21:48 0.1% java/291
16922 ducm0102 2115M 1961M sleep 58 0 6:37:08 0.0% java/193
18048 root 3048K 2440K sleep 59 0 0:06:02 0.0% sa_comm/4
26619 ducm0101 2588M 2368M sleep 59 0 8:21:17 0.0% java/231
19904 ducm0104 1713M 1390M sleep 59 0 1:15:29 0.0% java/151
27809 ducm0102 1547M 1426M sleep 59 0 0:38:19 0.0% java/186
2409 root 15M 11M sleep 59 0 0:00:00 0.0% pkgserv/3
27204 root 58M 54M sleep 59 0 9:11:38 0.0% stat_daemon/1
27256 root 12M 8312K sleep 59 0 7:16:40 0.0% kux_vmstat/1
29367 root 297M 286M sleep 59 0 11:02:13 0.0% dsmc/2
22128 root 13M 6768K sleep 59 0 0:10:51 0.0% sendmail/1
22133 smmsp 13M 1144K sleep 59 0 0:01:22 0.0% sendmail/1
22003 root 5896K 240K sleep 59 0 0:00:01 0.0% automountd/2
22074 root 4776K 1992K sleep 59 0 0:00:19 0.0% sshd/1
22005 root 6184K 2728K sleep 59 0 0:00:31 0.0% automountd/2
27201 root 6248K 344K sleep 59 0 0:00:01 0.0% mount_stat/1
20964 root 2912K 160K sleep 59 0 0:00:01 0.0% ttymon/1
20947 root 1784K 864K sleep 59 0 0:02:22 0.0% utmpd/1
20900 root 3048K 608K sleep 59 0 0:00:03 0.0% ttymon/1
20979 root 77M 18M sleep 59 0 0:14:13 0.0% inetd/4
20849 daemon 2856K 864K sleep 59 0 0:00:03 0.0% lockd/2
17794 root 80M 1232K sleep 59 0 0:06:19 0.0% svc.startd/12
17645 root 3080K 728K sleep 59 0 0:00:12 0.0% init/1
17849 root 13M 6800K sleep 59 0 0:13:04 0.0% svc.configd/15
20213 root 84M 81M sleep 59 0 0:47:17 0.0% nscd/46
20871 root 2568K 600K sleep 59 0 0:00:04 0.0% sac/1
3683 ducm0101 1904K 1640K sleep 56 0 0:00:00 0.0% startWebLogic.s/1
23937 ducm0101 1904K 1640K sleep 59 0 0:00:00 0.0% startWebLogic.s/1
20766 daemon 5328K 1536K sleep 59 0 0:00:36 0.0% nfsmapid/3
20141 daemon 5968K 3520K sleep 59 0 0:01:14 0.0% kcfd/4
20093 ducm0101 2000K 376K sleep 59 0 0:00:01 0.0% pfksh/1
20797 daemon 3256K 240K sleep 59 0 0:00:01 0.0% statd/1
6181 root 4864K 2872K sleep 59 0 0:01:34 0.0% syslogd/17
7220 ducm0104 1268M 1101M sleep 59 0 0:36:35 0.0% java/138
27597 ducm0102 1904K 1640K sleep 59 0 0:00:00 0.0% startWebLogic.s/1
27867 root 37M 4568K sleep 59 0 0:13:56 0.0% kcawd/7
12685 ducm0101 4080K 208K sleep 59 0 0:00:01 0.0% vncconfig/1
ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE
42 135 22G 19G 59% 87:27:59 1.2% dsuniucm01
Total: 135 processes, 3167 lwps, load averages: 54.48, 62.50, 63.11
我知道 CPU 大部分时间处于空闲状态,但平均负载很高,这对我来说很奇怪。内存似乎不是问题。
运行vmstat 15
结果如下:
kthr memory page disk faults cpu
r b w swap free re mf pi po fr de sr s0 s1 s4 sd in sy cs us sy id
0 0 0 32531400 105702272 317 1052 126 0 0 0 0 13 13 -0 8 9602 107680 10964 1 1 98
0 0 0 15053368 95930224 411 2323 0 0 0 0 0 0 0 0 0 23207 47679 29958 3 2 95
0 0 0 14498568 95801960 3072 3583 0 2 2 0 0 3 3 0 21 22648 66367 28587 4 4 92
0 0 0 14343008 95656752 3080 2857 0 0 0 0 0 3 3 0 18 22338 44374 29085 3 4 94
0 0 0 14646016 95485472 1726 3306 0 0 0 0 0 0 0 0 0 24702 47499 33034 3 3 94
我知道 CPU 大部分时间处于空闲状态,没有进程在队列中等待执行,很少发生交换。
运行iostat 15
结果如下:
tty sd0 sd1 sd4 ssd0 cpu
tin tout kps tps serv kps tps serv kps tps serv kps tps serv us sy wt id
0 676 324 13 8 322 13 8 0 0 0 159 8 0 1 1 0 98
1 1385 0 0 0 0 0 0 0 0 0 0 0 0 3 4 0 94
0 584 89 6 24 89 6 25 0 0 0 332 19 0 2 1 0 97
0 296 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 97
1 1290 43 5 24 43 5 22 0 0 0 297 20 1 3 3 0 94
运行netstat -i 15
结果如下:
input aggr26 output input (Total) output
packets errs packets errs colls packets errs packets errs colls
1500233798 0 1489316495 0 0 3608008314 0 3586173708 0 0
10646 0 10234 0 0 26206 0 25382 0 0
11227 0 10670 0 0 28562 0 27448 0 0
10353 0 9998 0 0 29117 0 28418 0 0
11443 0 12003 0 0 30385 0 31494 0 0
我错过了什么?
答案1
经过进一步调查,我们发现性能问题主要是由于两个系统(Oracle SSXA 和 UCM)之间的大量网络调用造成的。调用速度快,数量多,且是序列化的,因此 CPU 使用率低(大部分时间都在等待 I/O)、平均负载高(许多调用等待处理),响应时间尤其长(小响应时间累积而成)。
感谢您对这个问题的见解!
答案2
当您说“高平均负载”时,我假设您的意思是 prstat 在输出数字的底部显示“平均负载”
Total: 135 processes, 3167 lwps, load averages: 54.48, 62.50, 63.11
这些数字看起来与 top 提供的数字类似,可能表示正在运行的进程的平均队列大小。这不是处理器时间的百分比,而是多少“事物”在骚扰 CPU 以等待运行时间。不可否认,这些数字确实看起来很高,但这完全取决于您正在运行的应用程序;这些进程一旦获得其位置,实际上可能并没有做太多事情。请参阅这里关于顶部的一个很好的解释。
我不熟悉 WebLogic,但我注意到,通常,使用 Apache Tomcat 时,虽然请求并不多,但可以同时生成许多 Java 线程。这可能是导致平均负载数字如此之高的原因。确保在适当的情况下使用连接池来连接后端,并考虑增加应用程序可用于处理连接的空闲线程数(不确定如何在 WebLogic 上执行此操作;Tomcat 具有每个连接器线程池或通用执行器线程池)。如果不这样做,则可能会生成全新的线程来处理请求。
至于表现,你需要确定什么您的应用程序的一部分出了问题。是 WebLogic/Java 方面的处理问题、数据库访问问题、DNS 查找问题(如果出于某种原因而进行这些操作...)、网络问题还是操作系统的问题。
99% 的时间里,代码以及代码与数据库的通信方式都会阻碍事情的进展。然后是 Web 应用的配置。过了这个阶段,您将努力从应用中挤出最后几毫秒的时间,或者考虑使用相同的硬件提供更高的并发性。对于这种更细粒度的性能调整,您需要指标。
对于 Java,我建议安装Java 旋律。它可以提供大量有关程序正在做什么的信息,并帮助缩小程序花费时间的范围。我只在 Tomcat 中使用过它,但应该可以很好地与任何 Java EE 容器/servlet 配合使用。
有多种方法可以调整 Java,因此请查看它们的性能指南(我相信您可能已经看过了),并确保设置了适合您程序的正确堆大小等。Java Melody 可以帮助您追踪正在使用的 Java 堆的大小以及垃圾收集器的工作强度/它中断程序以清除对象的频率。
希望对您有所帮助。如果您提供更多信息,我可能会更新此答案并使其更符合您的需求。
答案3
附注:平均负载还包括等待磁盘活动(即骚扰磁盘)以及等待 CPU 的活动,它是两者的总和......因此您可能会在其中一个方面遇到问题。
看http://en.wikipedia.org/wiki/Load_(计算)“Linux 还包括处于不间断睡眠状态(通常等待磁盘活动)的进程”
顺便说一句,我遇到的具体问题是平均负载很高,但 CPU 也有很多空闲,磁盘使用率很低。
至少就我的情况而言,有时等待 I/O 的线程/进程会出现在平均负载中,但不是导致“await”列增加。但它们仍然受 I/O 限制。
如果您在 jruby 中运行以下代码(每个线程执行大量 I/O,仅执行 100 个线程),您可以判断情况确实如此:
100.times { Thread.new { loop { File.open('big', 'w') do |f| f.seek 10_000_000_000; f.puts 'a'; end}}}
其输出结果如下:
top - 17:45:32 up 38 days, 2:13, 3 users, load average: 95.18, 50.29, 23.83
Tasks: 181 total, 1 running, 180 sleeping, 0 stopped, 0 zombie
Cpu(s): 3.5%us, 11.3%sy, 0.0%ni, 85.1%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 32940904k total, 23239012k used, 9701892k free, 983644k buffers
Swap: 34989560k total, 0k used, 34989560k free, 5268548k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31866 packrd 18 0 19.9g 12g 11m S 117.0 41.3 4:43.85 java
912 root 11 -5 0 0 0 S 2.0 0.0 1:40.46 kjournald
所以你可以看到它有很多空闲的 CPU,0.0%wa,但是平均负载非常高。
iostat 类似地显示磁盘基本处于空闲状态:
avg-cpu: %user %nice %system %iowait %steal %idle
9.62 0.00 8.75 0.00 0.00 81.62
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 49.00 0.00 6.40 0.00 221.60 69.25 0.01 0.81 0.66 0.42
sda1 0.00 49.00 0.00 6.40 0.00 221.60 69.25 0.01 0.81 0.66 0.42
sda2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
也可以看看http://linuxgazette.net/141/misc/lg/tracking_load_average_issues.html
进一步说明一下,这似乎还意味着(至少在这种情况下 - 运行 CentOS)平均负载在总量中分别包含每个线程。
答案4
尝试 nmon
在这种情况下,另一个有用的工具是nmon
。
它包含多种方式来查看由其他工具在一个小的包中呈现的相同数据。
如果这是无法缓存的内容,我建议将多台服务器放置在 tcp 模式的负载均衡器(如 haproxy)后面以分配负载。