Apache Tomcat ทำการเชื่อมต่อหลังจาก 300 คน


16

เรามีเว็บเซิร์ฟเวอร์ apache หน้า Tomcat ที่โฮสต์บน EC2 ประเภทอินสแตนซ์มีขนาดใหญ่เป็นพิเศษพร้อมหน่วยความจำ 34GB

แอปพลิเคชันของเรามีเว็บเซอร์วิสภายนอกจำนวนมากและเรามีเว็บเซอร์ภายนอกที่น่ารังเกียจซึ่งใช้เวลาเกือบ 300 วินาทีในการตอบสนองต่อคำขอระหว่างชั่วโมงเร่งด่วน

ในช่วงชั่วโมงเร่งด่วนเซิร์ฟเวอร์จะทำการประมวลผลที่ httpd เพียงประมาณ 300 กระบวนการ ps -ef | grep httpd | wc -l = 300

ฉัน googled และพบข้อเสนอแนะมากมาย แต่ดูเหมือนว่าจะไม่มีอะไรทำงาน .. ต่อไปนี้คือการกำหนดค่าบางอย่างที่ฉันทำซึ่งนำมาจากแหล่งข้อมูลออนไลน์โดยตรง

ฉันเพิ่มขีด จำกัด ของการเชื่อมต่อสูงสุดและไคลเอนต์สูงสุดทั้งใน apache และ tomcat นี่คือรายละเอียดการกำหนดค่า:

// Apache

   <IfModule prefork.c>
    StartServers 100
    MinSpareServers 10
    MaxSpareServers 10
    ServerLimit 50000
    MaxClients 50000
    MaxRequestsPerChild 2000
    </IfModule>

// คราว

    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
           connectionTimeout="600000"
           redirectPort="8443"
           enableLookups="false" maxThreads="1500"
           compressableMimeType="text/html,text/xml,text/plain,text/css,application/x-javascript,text/vnd.wap.wml,text/vnd.wap.wmlscript,application/xhtml+xml,application/xml-dtd,application/xslt+xml"
           compression="on"/>

//Sysctl.conf

 net.ipv4.tcp_tw_reuse=1
 net.ipv4.tcp_tw_recycle=1
 fs.file-max = 5049800
 vm.min_free_kbytes = 204800
 vm.page-cluster = 20
 vm.swappiness = 90
 net.ipv4.tcp_rfc1337=1
 net.ipv4.tcp_max_orphans = 65536
 net.ipv4.ip_local_port_range = 5000 65000
 net.core.somaxconn = 1024

ฉันลองใช้คำแนะนำมากมาย แต่มันก็ไร้ประโยชน์ .. จะแก้ไขได้อย่างไร? ฉันแน่ใจว่าเซิร์ฟเวอร์ m2x large ควรให้บริการมากกว่า 300 คำขอบางทีฉันอาจจะผิดกับการกำหนดค่าของฉัน

เซิร์ฟเวอร์จะสำลักเฉพาะในช่วงชั่วโมงเร่งด่วนและเมื่อมีการร้องขอพร้อมกัน 300 คำขอที่รอให้เว็บเซอร์ [300 วินาทีล่าช้า] ตอบกลับ

ฉันเพิ่งตรวจสอบการเชื่อมต่อ tcp กับ netstat

ฉันพบการเชื่อมต่อประมาณ 1,000 ครั้งในสถานะ TIME_WAIT ไม่ทราบว่าจะหมายถึงอะไรในแง่ของประสิทธิภาพฉันแน่ใจว่าจะต้องเพิ่มปัญหา

การส่งออกของ TOP

 8902  root      25   0 19.6g 3.0g  12m S  3.3  8.8  13:35.77 java
 24907 membase   25   0  753m 634m 2528 S  2.7  1.8 285:18.88 beam.smp
 24999 membase   15   0  266m 121m 3160 S  0.7  0.3  51:30.37 memcached
 27578 apache    15   0  230m 6300 1536 S  0.7  0.0   0:00.03 httpd
 28551 root      15   0 11124 1492  892 R  0.3  0.0   0:00.25 top


 Output of free -m
 total       used       free     shared    buffers    cached
 35007       8470       26536    0          1         61
 8407        26599
 15999       15         15984

 output of iostat
 avg-cpu:  %user   %nice %system %iowait  %steal   %idle
      26.21    0.00    0.48    0.13    0.02   73.15

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda1             14.36         4.77       329.37    9005402  622367592
sdb               0.00         0.00         0.00       1210         48

เวลาสูงสุดมีการเชื่อมต่อ tcp ประมาณ 10-15k กับเซิร์ฟเวอร์ membase [ท้องถิ่น]

ข้อผิดพลาดบางอย่างในการเข้าสู่ระบบ MODJK ฉันหวังว่านี้จะโยนแสงในปัญหา ..

[Wed Jul 11 14:39:10.853 2012] [8365:46912560456400] [error]         ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:18.627 2012] [8322:46912560456400] [error] ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:21.358 2012] [8351:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)
[Wed Jul 11 14:39:22.640 2012] [8348:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)

~

Worker.properties
workers.tomcat_home=/usr/local/tomcat/
worker.list=loadbalancer
worker.tom1.port=8009
worker.tom1.host=localhost
worker.tom1.type=ajp13
worker.tom1.socket_keepalive=True
worker.tom1.connection_pool_timeout=600
worker.tom2.port=8109
worker.tom2.host=localhost
worker.tom2.type=ajp13
worker.tom2.socket_keepalive=True
worker.tom2.connection_pool_timeout=600
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tom1,tom2
worker.loadbalancer.sticky_session=True
worker.tom1.lbfactor=1
worker.tom1.socket_timeout=600
worker.tom2.lbfactor=1
worker.tom2.socket_timeout=600

// แก้ไข

ขอบคุณสำหรับคำแนะนำที่มีค่าของคุณ .. ฉันพลาดการตั้งค่า maxThreads สำหรับตัวเชื่อมต่อ AJP 1.3 .. ตอนนี้ทุกอย่างดูเหมือนจะอยู่ภายใต้การควบคุม

ฉันจะเริ่มดูเซิร์ฟเวอร์ที่ใช้งานง่ายเช่น nginx


การตั้งค่า Keepalive ของคุณเป็นอย่างไร?
Tom O'Connor

ลูกค้าทำอะไรผิดพลาดกลับมาอีกครั้งเมื่อพยายามโหลดหน้า?
เชนแมดเดน

1
คุณเพิ่มคำอธิบายไฟล์แบบเปิดสูงสุดที่อนุญาตสำหรับผู้ใช้ apache / httpd หรือไม่?
golja

@Tom การตั้งค่า Keep Keep AliveTimeout 10 ใน httpd.conf
john titus

3
ผลลัพธ์ของtopหน้าตาเป็นอย่างไรในช่วงเวลาเหล่านี้? แล้วไงfree -mล่ะ และในที่สุดiostat?
Zypher

คำตอบ:


13

คุณเพิ่ม maxThreads ใน AJP 1.3 Connector ที่พอร์ต 8009 หรือไม่?


1,500 คือสิ่งที่ฉันมีต่ออินสแตนซ์ Tomcat
john titus

@ จอห์นคุณจะบอกว่าสำหรับทุกการเชื่อมต่อคุณได้ระบุ maxThreads = "1500"? คุณสามารถโพสต์บทเพลงสำหรับตัวเชื่อมต่อ AJP 1.3 (พอร์ต 8009) ได้หรือไม่?
HTTP500

ขอบคุณที่ชี้นำสิ่งนี้ .. ไม่มีการตั้งค่า maxThreads สำหรับ AJP1.3 เลย .. นี่อาจเป็นเหตุผลหรือไม่
john titus

1
ใช่เพิ่ม maxThreads ไปยัง stanza สำหรับตัวเชื่อมต่อนั้น ค่าเริ่มต้นคือ 200
HTTP500

6

พิจารณาตั้งค่าเว็บเซิร์ฟเวอร์พรอกซีแบบอะซิงโครนัสเช่นnginxหรือlighttpdต่อหน้า Apache Apache ให้บริการเนื้อหาแบบซิงโครนัสเพื่อให้คนงานถูกบล็อกจนกว่าลูกค้าจะดาวน์โหลดเนื้อหาที่สร้างเต็ม (รายละเอียดเพิ่มเติมที่นี่ ) การตั้งค่าพร็อกซีแบบอะซิงโครนัส (ไม่ปิดกั้น) มักจะปรับปรุงสถานการณ์อย่างมาก (ฉันใช้เพื่อลดจำนวนผู้ใช้ Apache ที่ทำงานพร้อมกันจาก 30 เป็น 3-5 โดยใช้nginxเป็นพร็อกซีส่วนหน้า)


5

ฉันสงสัยว่าปัญหาของคุณอยู่ใน Tomcat ไม่ apache จากบันทึกที่คุณได้แสดงต่อไป เมื่อคุณได้รับ 'ข้อผิดพลาด 110' พยายามเชื่อมต่อกลับเข้าสู่โพงมันหมายความว่าคุณมีคิวของการเชื่อมต่อที่รอการให้บริการซึ่งจะไม่มีอีกต่อไปที่จะเข้าสู่การตั้งค่าฟังก์ชั่น Backlog สำหรับซ็อกเก็ตการฟังในโพง

From the listen manpage:
   The  backlog  parameter defines the maximum length the queue of pending 
   connections may grow to.  If a connection request arrives with
   the queue full the client may receive an error with an indication
   of ECONNREFUSED or, if the underlying protocol supports  
   retransmission, the request may be ignored so that retries succeed.

ถ้าฉันต้องเดาฉันจะสงสัยว่าคำขอ HTTP ส่วนใหญ่เมื่อเซิร์ฟเวอร์ "สำลัก" ถูกบล็อกรอบางสิ่งที่จะกลับมาจากแมวตัวผู้ ฉันพนันได้เลยว่าคุณพยายามที่จะดึงเนื้อหาแบบคงที่ที่ apache ให้บริการโดยตรง (แทนที่จะเป็นพร็อกซีไปยังโพงแคท) ว่าวิธีนี้จะใช้ได้แม้ว่าจะเป็น 'สำลัก' ก็ตาม

ฉันไม่คุ้นเคยกับแมวตัวผู้โชคร้าย แต่มีวิธีจัดการการตั้งค่าพร้อมกันของสิ่งนี้แทนหรือไม่?

โอ้และคุณอาจจะต้องมีการพิจารณาความเป็นไปได้ว่า thats บริการเครือข่ายภายนอก จำกัด จำนวนการเชื่อมต่อว่ามันจะทำกับคุณลงไปที่ 300 จึงทำให้ไม่แตกต่างกับวิธีการจัดการกับเห็นพ้องมากที่คุณกำลังทำอยู่ทางด้านหน้าของคุณ หากการเชื่อมต่อทุกครั้งที่คุณใช้บริการตอบกลับจากเว็บภายนอก

ในหนึ่งในความคิดเห็นของคุณที่คุณกล่าวถึงข้อมูลจะค้างหลังจาก 2 นาที ฉันขอแนะนำให้แคชการตอบสนองที่คุณได้รับจากบริการนี้เป็นเวลาสองนาทีเพื่อลดจำนวนการเชื่อมต่อพร้อมกันที่คุณกำลังขับรถไปยังบริการเว็บภายนอก


2

ขั้นตอนแรกในการแก้ไขปัญหานี้คือการเปิดใช้mod_statusของ Apache และศึกษารายงานของมัน - จนกว่าคุณจะทำสิ่งนี้จริง ๆ แล้วคุณกำลังเดินสุ่มสี่สุ่มห้า นั่นไม่ชอบธรรม ;-)

สิ่งที่สองที่จะกล่าวถึง (ผมด้วยตัวเองไม่ชอบที่จะบอกคำตอบสำหรับคำถามผมไม่ได้ถาม แต่ ... ) nginxจะใช้เซิร์ฟเวอร์ที่มีประสิทธิภาพมากขึ้นและพิเศษปลายด้านหน้าเช่น

นอกจากนี้คุณว่าrestartApache หรือเพียงแค่gracefulLy โหลดใหม่ได้หรือไม่ :)


Apache เริ่มต้นใหม่ .. ไม่ใช่การโหลดซ้ำอย่างสง่างาม
john titus

@johntitus ดีmod_statusเพื่อนของคุณยังไงก็ตาม :)
poige

1

สำหรับการปรับใช้ระดับองค์กรใด ๆ prefork MPM เป็นเพียงตัวเลือกที่แย่ที่สุดที่คุณสามารถทำได้: มันกลืนกินทรัพยากรอย่างไม่มีใครทำธุรกิจ

อย่างน้อยเปลี่ยนเป็นMPM ของผู้ปฏิบัติงาน (apache 2.2 ขึ้นไป) หรือ - ดีขึ้น แต่ยัง - อัพเกรดเป็นเวอร์ชั่นที่เสถียรในปัจจุบัน 2.4.2 ด้วยMPM ของเหตุการณ์เริ่มต้น

ทั้งสองอย่างนี้จะจัดการการเชื่อมต่อพร้อมกันหลายพันที่มีค่าใช้จ่ายน้อยมาก


ขอบคุณ .. พยายามเช่นนั้น .. ไม่มีโชค การเชื่อมต่อ TIME_WAIT เพิ่มขึ้นเรื่อย ๆ เซิร์ฟเวอร์หยุดตอบสนองเมื่อการเชื่อมต่อ 350 ครั้ง
john titus

1
ฉันไม่เห็นด้วยว่าเป็นตัวเลือกที่แย่ที่สุด - เป็นตัวเลือกที่แย่สำหรับบริบทนี้และเป็นไปได้ว่าปัญหาจะคลี่คลายลงโดยใช้เซิร์ฟเวอร์เธรด แต่ทางออกที่ดีกว่าคือการใช้เซิร์ฟเวอร์ที่ใช้เหตุการณ์ (nginx หรือ lighttpd) Apache ที่ใช้งานเหตุการณ์นั้นยังไม่เต็มที่พอที่จะพิจารณาจากการปรับใช้องค์กร IMHO
symcbean

1

ฉันรู้ว่ามันเป็นเรื่องเก่า แต่ฉันมี 2 ข้อ

มีขีด จำกัด การเข้ารหัสอย่างหนักสำหรับServerLimit Directive http://httpd.apache.org/docs/2.2/mod/mpm_common.html#serverlimitคุณจะเห็นว่ามันมีค่าสูงสุด 20000 / 200K

มีข้อ จำกัด อย่างหนักของ ServerLimit 20000 ที่คอมไพล์ลงในเซิร์ฟเวอร์ (สำหรับ prefork MPM 200000) สิ่งนี้มีวัตถุประสงค์เพื่อหลีกเลี่ยงผลที่น่ารังเกียจที่เกิดจากการพิมพ์ผิด

อันดับที่ 2 เห็นได้ชัดว่า nodybo กล่าวว่าการตั้งค่า 2 ต่อหนึ่งเป็นความคิดที่ไม่ดีมาก :

net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1

หมายความว่าคุณนำเวลามาใช้ใหม่ก่อนกำหนดเดาอะไร เซิร์ฟเวอร์อาจพูดคุยกับลูกค้าผิดภายใต้ภาระหนัก

ฉันพบบทความที่ดีมากอธิบายว่า แต่ - เป็นภาษาฝรั่งเศส ;-) http://vincent.bernat.im/fr/blog/2014-tcp-time-wait-state-linux.html


0

ขนาดใหญ่พิเศษพร้อมหน่วยความจำ 34GB

เหล็กขนาดใหญ่ไม่ใช่วิธีที่จะขยายขนาดการให้บริการเว็บคุณกำลังจะย้ายคอขวดไปรอบ ๆ แต่ถึงแม้จะมีหน่วยความจำขนาดใหญ่นี้ฉันก็ยังสงสัยว่าการเชื่อมต่อ 50,000 ครั้งกำลังผลักดันสิ่งที่ระบบสามารถทำได้โดยเฉพาะถ้า:

ในช่วงชั่วโมงเร่งด่วนเซิร์ฟเวอร์จะทำการประมวลผลที่ httpd เพียงประมาณ 300 กระบวนการ

มันจะมีประโยชน์ถ้าคุณอธิบายว่าคุณหมายถึง "เซิร์ฟเวอร์โช้ก"

มันแปลกมากที่มีขีด จำกัด สูงสำหรับการเชื่อมต่อ แต่ขีด จำกัด ต่ำมากสำหรับ hysteresis (เซิร์ฟเวอร์สำรองขั้นต่ำ / สูงสุด)

แม้ว่าการแยกข้อผิดพลาดที่คุณระบุไม่ได้แสดง 'ไฟล์ที่เปิดมากเกินไป' ฉันก็เริ่มต้นด้วยการดูจำนวนตัวอธิบายไฟล์ที่เปิดและการตั้งค่า ulimit


โช้ก Server เป็นในมันไม่ตอบสนองต่อการไฟล์ HTML ปกติแม้ ..
จอห์นติตัส

ฉันเปลี่ยน maxClients เป็น 3000 ตอนนี้ .. ยังเป็นปัญหาเดิมอยู่
john titus

0

บางทีผู้ใช้ Apache ใช้งานไฟล์ที่ไม่ได้รับอนุญาต คุณไม่ได้พูดถึงพวกเขาเลยในโพสต์ของคุณ ปัจจุบันมีกี่ไฟล์ที่ Apache ได้รับอนุญาตให้มี


ตัวจัดการไฟล์ 128192
john titus

0

นี่เป็นเหมือนความเห็น แต่ไม่สามารถทำได้เพราะฉันมีชื่อเสียงน้อยกว่า มาพบกับปัญหาที่คล้ายกันอย่างที่ @john titus มี

เราทำให้ตัวเชื่อมต่อ AJP MaxThreadsใกล้กับขีด จำกัด Apache Thread ของเราเพื่อแก้ไขปัญหา

สำหรับการตรวจสอบสิ่งนี้เรามองหาความSYN_SENT ช่วยเหลือสถานะพอร์ต netstat ด้วยคำสั่ง netstat บนพอร์ต AJP ของเรา

netstat -an | grep :8102 | grep SYN_SENT | wc -l

ค่านี้ลดลงเป็น 0 ซึ่งมักเป็นจำนวนมากก่อนกำหนดขีด จำกัด MaxThread บน AJP Connector

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.