별표 서버에 높은 로드 평균을 나타내는 문제가 있습니다. 설명할 수 없습니다. 뉴욕 설정은 다음과 같습니다.
- 별표 13.1.0
- 리눅스 3.13.0-24(우분투 서버)
- 듀얼 소켓(Xeon E5-2620) 서버, HT 지원 - 총 24개 코어; 32G RAM
별표는 음성 메시지를 보내는 데 사용됩니다. 업스트림 SIP 공급자가 하나 있고 하드웨어 전화 통신 카드가 없습니다. sip.conf에는 alaw/ulaw만 허용됩니다.
통화를 시작하기 위해 AMI Originate 명령을 사용합니다. 그런 다음 미리 녹음된 음성 메시지(로컬 ext4 FS의 ulaw 파일)를 보내기 위해 Playback()을 실행합니다. 수신자와 다른 상호 작용, IVR 메뉴, 통화 녹음이 없습니다. 몇 가지 매우 간단한 Perl AGI 스크립트는 호출 결과를 DB(MySQL 및 MSSQL(Perl Sybase를 통해))에 저장합니다. 일반적으로 Originate당 1~2개의 AGI 호출이 있습니다. 또한 확장 시에는 처리가 거의 없습니다. 문자 그대로 CDR()에 대한 사전 설정 검증 가능 항목이 20줄이고 몇 가지 AGI 호출이 있습니다. 모든 호출을 시작하는 데 사용하는 AMI 연결은 단 하나뿐입니다.
구체적인 점은 대부분의 전화에 응답하지 않는다는 것입니다. 초당 최대 50통의 전화를 걸지만 실제로는 5~10통만 전화를 받고 듣습니다.
문제는 CPU 사용량이 매우 낮지만 LA는 매우 높다는 것입니다. 20-25cps - 20-24 LA로 시작했는데 50cps까지 늘리려고 하면 LA는 90+까지 올라갑니다. ~50LA 이후에는 오디오 품질에 문제가 있습니다(그리고 그 이유를 이해할 수 있습니다).
대부분의 Asterisk 사용자는 덜 강력한 하드웨어로 통화량이 훨씬 더 많다고 주장합니다.
# uptime
12:56:36 up 9 days, 15:52, 1 user, load average: 32,10, 33,45, 33,10
#vmstat -w 1
procs ---------------memory-------------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 0 30322760 199176 832452 0 0 0 0 237471 38738 5 8 87 0 0
3 0 0 30319148 199176 832500 0 0 0 0 188340 38960 4 6 90 0 0
3 0 0 30325528 199176 832564 0 0 0 26 319903 43916 6 10 83 0 0
105 0 0 30270288 199176 832568 0 0 0 14 175216 39014 4 6 90 0 0
16 0 0 30307908 199176 832572 0 0 0 0 323598 43428 11 12 77 0 0
# mpstat 1
Linux 3.13.0-24-generic (asterisk2) 25.02.2015 _x86_64_ (24 CPU)
13:18:09 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
13:18:10 all 5,77 0,00 7,90 0,00 0,17 0,00 0,00 0,00 0,00 86,16
13:18:11 all 5,56 0,00 8,83 0,00 0,21 0,00 0,00 0,00 0,00 85,40
13:18:12 all 10,29 0,00 11,42 0,00 0,25 0,00 0,00 0,00 0,00 78,03
13:18:13 all 9,70 0,00 10,75 0,00 0,21 0,00 0,00 0,00 0,00 79,34
# uname -a
Linux asterisk2 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
# cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 45
model name : Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz
stepping : 7
microcode : 0x70d
cpu MHz : 2000.216
cache size : 15360 KB
physical id : 0
siblings : 12
core id : 0
cpu cores : 6
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid
bogomips : 4000.43
clflush size : 64
cache_alignment : 64
address sizes : 46 bits physical, 48 bits virtual
...
processor : 23
vendor_id : GenuineIntel
cpu family : 6
model : 45
model name : Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz
stepping : 7
microcode : 0x70d
cpu MHz : 2000.216
cache size : 15360 KB
physical id : 1
siblings : 12
core id : 5
cpu cores : 6
apicid : 43
initial apicid : 43
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid
bogomips : 4001.85
clflush size : 64
cache_alignment : 64
address sizes : 46 bits physical, 48 bits virtual
# cat /proc/interrupts
CPU02 CPU23
0: 24 0 IR-IO-APIC-edge timer
8: 1 0 IR-IO-APIC-edge rtc0
9: 2 0 IR-IO-APIC-fasteoi acpi
16: 33 0 IR-IO-APIC-fasteoi ehci_hcd:usb1
23: 107 0 IR-IO-APIC-fasteoi ehci_hcd:usb2
88: 0 0 DMAR_MSI-edge dmar0
89: 0 0 DMAR_MSI-edge dmar1
90: 1855369 0 IR-PCI-MSI-edge ahci
91: 1 0 IR-PCI-MSI-edge eth0
92: 11296 0 IR-PCI-MSI-edge eth0-TxRx-0
93: 790 0 IR-PCI-MSI-edge eth0-TxRx-1
94: 85066770 0 IR-PCI-MSI-edge eth0-TxRx-2
95: 6851 0 IR-PCI-MSI-edge eth0-TxRx-3
96: 174614 0 IR-PCI-MSI-edge eth0-TxRx-4
97: 4846139 0 IR-PCI-MSI-edge eth0-TxRx-5
98: 136593 0 IR-PCI-MSI-edge eth0-TxRx-6
99: 1294090 0 IR-PCI-MSI-edge eth0-TxRx-7
109: 2 0 IR-PCI-MSI-edge ioat-msix
110: 2 0 IR-PCI-MSI-edge ioat-msix
111: 2 0 IR-PCI-MSI-edge ioat-msix
112: 2 0 IR-PCI-MSI-edge ioat-msix
113: 2 0 IR-PCI-MSI-edge ioat-msix
114: 2 0 IR-PCI-MSI-edge ioat-msix
115: 2 0 IR-PCI-MSI-edge ioat-msix
116: 2 0 IR-PCI-MSI-edge ioat-msix
117: 0 0 IR-PCI-MSI-edge ioat-msix
118: 0 0 IR-PCI-MSI-edge ioat-msix
119: 0 0 IR-PCI-MSI-edge ioat-msix
120: 0 0 IR-PCI-MSI-edge ioat-msix
121: 0 0 IR-PCI-MSI-edge ioat-msix
122: 0 0 IR-PCI-MSI-edge ioat-msix
123: 0 0 IR-PCI-MSI-edge ioat-msix
124: 0 0 IR-PCI-MSI-edge ioat-msix
NMI: 3642 1990 Non-maskable interrupts
LOC: 53207172 19108700 Local timer interrupts
SPU: 0 0 Spurious interrupts
PMI: 3642 1990 Performance monitoring interrupts
IWI: 804483 60489 IRQ work interrupts
RTR: 0 0 APIC ICR read retries
RES: 60096784 31495629 Rescheduling interrupts
CAL: 4046461325 4101338127 Function call interrupts
TLB: 2390847639 1479027286 TLB shootdowns
TRM: 0 0 Thermal event interrupts
THR: 0 0 Threshold APIC interrupts
MCE: 0 0 Machine check exceptions
MCP: 2501 2501 Machine check polls
ERR: 0
MIS: 0
# atop
CPL | avg1 22.45 | avg5 22.65 | | avg15 22.74 | | csw 379728 | intr 1612164 | | | numcpu 24 |
MEM | tot 31.4G | free 28.4G | cache 829.3M | dirty 0.0M | buff 194.7M | slab 188.0M | | | | |
SWP | tot 32.0G | free 32.0G | | | | | | | vmcom 737.1M | vmlim 47.7G |
MDD | md0 | busy 0% | read 0 | write 12 | KiB/r 0 | KiB/w 4 | MBr/s 0.00 | MBw/s 0.01 | avq 0.00 | avio 0.00 ms |
DSK | sda | busy 1% | read 0 | write 11 | KiB/r 0 | KiB/w 5 | MBr/s 0.00 | MBw/s 0.01 | avq 1.00 | avio 12.7 ms |
DSK | sdb | busy 1% | read 0 | write 11 | KiB/r 0 | KiB/w 5 | MBr/s 0.00 | MBw/s 0.01 | avq 1.00 | avio 11.6 ms |
NET | transport | tcpi 1994 | tcpo 2452 | udpi 17159 | udpo 14811 | tcpao 117 | tcppo 1 | tcprs 0 | tcpie 0 | udpip 0 |
NET | network | ipi 19235 | ipo 17268 | ipfrw 0 | deliv 19235 | | | | icmpi 7 | icmpo 0 |
NET | eth0 0% | pcki 19345 | pcko 17272 | si 3256 Kbps | so 2954 Kbps | coll 0 | erri 0 | erro 0 | drpi 0 | drpo 0 |
보시다시피 cs 및 vmstat 필드에는 매우 높은 숫자가 있습니다. 나는 그것들을 설명할 수 없다.
따라서 내가 아는 한 매우 짧은 시간 내에 실행 가능한 스레드 버스트가 있습니다(vmstat 출력에서 이러한 버스트 중 하나를 볼 수 있습니다). 하지만 내 설정에서 그런 일이 발생할 수 있습니까?
나는 시도했다:
- sip.conf에서 코덱 패킷화를 사용합니다(마이크로 패킷이 너무 많이 전송된다는 생각이 있었습니다).
- 재생 파일 형식 변경;
- AGI 스크립트 호출을 완전히 비활성화합니다(extensions.conf에서 주석 처리).
- AMI 채널 사용 방식 변경(간격 및 버스트 양을 변경하여 로드 평준화)
하지만 아무것도 도움이 되지 않았습니다.
제가 생각할 수 있는 모든 것을 확인했습니다. 이 서버에는 디스크 IO도 없고 다른 앱도 없습니다. mailllist에도 비슷한 문제를 안고 있는 분들이 있는데 해결되지 않고 꽤 오래 전 일이었습니다.
한 가지 더 생각해 보세요. 매우 유사한 하드웨어와 Asterisk 구성으로 동일한 문제가 있는 서버가 하나 더 있지만 거기에는 Asterisk 1.8(FreePBX)과 CentOS가 사용되고 있습니다. 나는 이것이 나의 특별한 사용법으로 이어진다고 생각합니다.
어쩌면 이것이 AMI의 핵심 문제이므로 대량 초기화 호출을 위해 다른 것을 사용해야 할까요?
편집1: 내 LA 그래프는 다음과 같습니다.
편집2:여기 별표 추적이 있습니다. 높은 부하와 낮은 부하에서는 상대적으로 동일합니다. 저는 리눅스 프로그래머가 아니기 때문에 제대로 해석할 수 없습니다.
# strace -f -q -c -p 17150
^C% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
42.05 1595.370429 13209 120778 18231 futex
41.21 1563.521630 6304523 248 14 restart_syscall
15.96 605.470340 4726 128105 26 poll
0.23 8.811410 12037 732 nanosleep
0.16 5.903679 26 228693 22073 read
0.15 5.600020 66 85202 write
답변1
알았어, 알아냈어. 이것은 단지 해결 방법이지만 문제는 허용 가능한 수준으로 떨어졌습니다.
하루 중 원치 않는 재부팅 후에 로드 평균이 크게 떨어지는 것을 발견했습니다! 서버 모니터링 시스템을 확인해 보니 LA는 항상 3~4시간 연속(그리고 안정적인) 로드 속에서 조금씩 올라갔습니다. 전날 재부팅할 수 없었기 때문에 이는 눈에 띄지 않았습니다.
내가 말했듯이, 나는 애플리케이션을 통해 호출되는 몇 가지 Perl 스크립트를 가지고 있습니다 AGI()
. 그 중 하나는 h
확장 으로 호출됩니다 . 하나의 간단한 DB 쿼리만 실행합니다. 때때로 DB에 약간의 과부하가 발생하는 것으로 나타났습니다. 쿼리는 200-500ms 동안 기다려야 합니다. Asterisk는 Perl 스크립트가 완료될 때까지 기다려야 합니다.
그래서 나는 fork()
시작할 때 Perl 스크립트를 사용하여 AGI() 호출이 항상 즉시 반환되도록 했습니다. 이것은 많은 도움이 되었습니다! LA는 많이 안정되었습니다. 이것은 완전한 해결책은 아닙니다. Asterisk의 내부를 여전히 손상시키는 것처럼 보이지만 훨씬 느리기 때문에 거의 문제가 되지 않습니다.
바로 사용할 수 있는 코드 조각을 찾는 사람들의 경우( ing 후에는 fork()
액세스할 수 없으므로 ing 전에 모든 변수를 가져오는 것을 잊지 마세요 $AGI
):
my $AGI = new Asterisk::AGI;
# get all your variables here
my $var = $AGI->get_variable('var');
undef $AGI;
if (fork) { exit 0; };
open STDIN, '<', '/dev/null'; # dont forget to free your parent's file handles
open STDOUT, '>', '/dev/null';
open STDERR, '>&STDOUT';
버그인 것 같은데 왜 저 외에는 이런 문제를 겪는 사람이 없는지 궁금합니다.
편집1:음, 통화를 제거한 후 문제가 완전히 사라졌습니다 AGI
. 나는 단순히 비동기 처리를 위한 정보를 저장하는 몇 가지 사용자 정의 ODBC
함수( func_odbc.conf
)를 만들었습니다(나중에 별도의 Perl 데몬에 의해 처리됨). LA는 20-25에서 0.5-0.9(!)로 떨어졌습니다. AGI
이렇게 큰 부하가 발생할 수 있다고는 전혀 생각하지 못했습니다 .