Мы наблюдаем огромные проблемы с производительностью веб-приложения и пытаемся найти узкое место. Я не системный администратор, поэтому кое-что мне не совсем понятно. Некоторое базовое исследование показывает, что ЦП простаивает, доступно много памяти, без подкачки, без ввода-вывода, но с высокой средней нагрузкой.
Программный стек на этом сервере выглядит так:
Приложения, работающие на этом сервере, взаимодействуют с базой данных Oracle на другом сервере.
Этот сервер имеет 32 ГБ оперативной памяти и 10 процессоров (я думаю).
Бег 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
Я понимаю, что процессор в основном простаивает, но средняя нагрузка высока, что для меня довольно странно. Память не кажется проблемой.
Бег 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
Я понимаю, что ЦП в основном простаивает, в очереди нет процессов, ожидающих выполнения, происходит небольшая подкачка.
Бег 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
Что мне не хватает?
При дальнейшем исследовании выясняется, что проблема с производительностью в основном связана с большим количеством сетевых вызовов между двумя системами (Oracle SSXA и UCM). Вызовы бывают быстрыми, но многочисленными и сериализованными, отсюда и низкая загрузка ЦП (в основном ожидание ввода-вывода), высокая средняя нагрузка (многие вызовы, ожидающие обработки) и особенно длительное время отклика (накопление небольшого времени отклика).
Спасибо за понимание этой проблемы!
Когда вы говорите «Высокая средняя нагрузка», я предполагаю, что вы имеете в виду, что prstat показывает «среднюю нагрузку» внизу выходных значений
Total: 135 processes, 3167 lwps, load averages: 54.48, 62.50, 63.11
Эти числа похожи на те, которые предоставляет top, и, вероятно, означают средний размер очереди запущенного процесса. Это не процент используемого процессорного времени, а то, сколько «вещей» беспокоят ЦП на время для работы. По общему признанию, они выглядят довольно высокими, но все зависит от приложения, которое вы запускаете; процессы могут фактически не делать много, как только они получат свой слот. Видеть Вот за хорошее объяснение относительно вершины.
Я не знаком с WebLogic, но заметил, что, как правило, с Apache Tomcat многие потоки Java могут быть созданы одновременно для того, что кажется небольшим количеством запросов. Это могло быть причиной высоких средних значений нагрузки. Убедитесь, что вы используете пул соединений, где это необходимо для подключения к бэкэнду, и рассмотрите возможность увеличения количества незанятых потоков, доступных вашему приложению для обработки подключений (не уверен, как вы это делаете в WebLogic; Tomcat имеет пул потоков для каждого соединителя или пул потоков общего исполнителя). Если вы этого не сделаете, то для обработки запросов могут быть созданы новые потоки.
Что касается производительности, нужно прибить какие часть вашего приложения страдает. Это обработка, которая происходит на стороне WebLogic / Java, доступ к базе данных, поиск DNS (если они по какой-то причине выполняются ...), проблемы с сетью или что-то в ОС.
В 99% случаев это будет ваш код и то, как он взаимодействует с базой данных, которая задерживает работу. Затем будет настройка веб-приложения. После этого вы будете работать над тем, чтобы выжать из своего приложения последние миллисекунды, или над тем, чтобы обеспечить более высокий уровень параллелизма с тем же оборудованием. Для более тонкой настройки производительности вам нужны метрики.
Для Java я предлагаю установить Java Melody. Он может предоставить много информации о том, что делает ваша программа, и помочь сузить круг вопросов, на которые она тратит время. Я использовал его только с Tomcat, но он должен нормально работать с любыми контейнерами / сервлетами Java EE.
Существует несколько способов настройки Java, поэтому ознакомьтесь с их рекомендациями по производительности (я уверен, что у вас есть) и убедитесь, что вы устанавливаете правильный размер кучи и т. Д., Подходящий для вашей программы. Java Melody может помочь вам отследить размер кучи Java, которую вы используете, а также то, насколько усердно работает сборщик мусора / как часто он прерывает вашу программу для очистки объектов.
Я надеюсь, что это было полезно. Если вы предоставите дополнительную информацию, я, возможно, смогу обновить этот ответ и отточить его в большей степени для ваших нужд.
В качестве побочного примечания, средняя загрузка также включает в себя вещи, ожидающие активности диска (то есть беспокоящие диск), а также ожидающие процессора, это сумма обоих ... так что у вас могут быть проблемы с одним или другим.
Видеть http://en.wikipedia.org/wiki/Load_(computing) «Linux также включает [в свою среднюю нагрузку] процессы, находящиеся в состоянии непрерывного сна (обычно ожидающие активности диска)»
В качестве примечания: конкретная проблема, с которой я столкнулся, заключалась в том, что у меня была высокая средняя загрузка, но также было много простаивающих ЦП и низкое использование диска.
Похоже, что, по крайней мере, в моем случае, иногда потоки / процессы, ожидающие ввода-вывода, отображаются в средней нагрузке, но делают не вызвать увеличение столбца "ожидание". Но они по-прежнему привязаны к вводу-выводу.
Вы можете сказать, что это относится к следующему коду, если вы запустите его в jruby (всего 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
Итак, вы можете видеть, что у него много простаивающих ЦП, 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) средняя загрузка включает в себя каждый поток отдельно в целом.
Была такая же проблема сегодня. После некоторых исследований и диагностики я понял, что мой маленький VPS был заканчивается диск.
В оболочке / приглашении (Linux / Unix) введите
df -h
чтобы увидеть диск свободен на вашей машине. Если у вас заканчивается диск, это может быть проблемой.
Еще один полезный инструмент, который поможет в этой ситуации, - это nmon.
Он включает в себя множество способов просмотра одних и тех же данных, представленных другими инструментами, в одном небольшом пакете.
Если это контент, который нельзя кэшировать, я бы порекомендовал разместить несколько серверов за балансировщиком нагрузки, таким как haproxy, в режиме TCP для распределения нагрузки.
Чтобы добавить к этому, некоторые специальные инструменты Solaris, которые не были упомянуты, которые полезны при отладке таких проблем, - это «intrstat», «mpstat» и «lockstat». Испытывая подобную проблему раньше на хосте, на котором выполняются большие нагрузки ETL, mpstat обнаружил большое количество прерываний, связанных с большим количеством операций ввода-вывода, которые намекали на проблему.
В то время на T4-4 с mpstat мы видели, как vcpus обрабатывает более 30000 прерываний за короткий цикл мониторинга, после чего производительность начинает падать. В этом случае единственным обходным решением было увеличить нагрузку на процессор, однако впоследствии была проведена работа по улучшению кода.
Брендан Грегг много лет писал о производительности, особенно о вводе-выводе, и стоит поискать его, если вы хотите узнать больше.