Apache Tomcat bị sặc sau 300 kết nối


16

Chúng tôi có một máy chủ web apache trước Tomcat được lưu trữ trên EC2, loại cá thể cực lớn với bộ nhớ 34GB.

Ứng dụng của chúng tôi xử lý nhiều dịch vụ web bên ngoài và chúng tôi có một dịch vụ web bên ngoài rất tệ hại, mất gần 300 giây để đáp ứng các yêu cầu trong giờ cao điểm.

Trong giờ cao điểm, máy chủ bị sặc ở khoảng 300 quy trình httpd. ps -ef | grep httpd | wc -l = 300

Tôi đã googled và tìm thấy nhiều đề xuất nhưng dường như không có gì hoạt động .. sau đây là một số cấu hình tôi đã thực hiện được lấy trực tiếp từ các tài nguyên trực tuyến.

Tôi đã tăng giới hạn kết nối tối đa và khách hàng tối đa trong cả apache và tomcat. Dưới đây là chi tiết cấu hình:

// apache

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

// mèo

    <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

Tôi đã cố gắng rất nhiều đề xuất nhưng vô ích .. làm thế nào để khắc phục điều này? Tôi chắc chắn máy chủ m2xlarge sẽ phục vụ nhiều yêu cầu hơn 300, có lẽ tôi có thể gặp trục trặc với cấu hình của mình ..

Máy chủ chỉ bị nghẹt trong giờ cao điểm và khi có 300 yêu cầu đồng thời chờ dịch vụ web [300 giây bị trì hoãn] phản hồi.

Tôi chỉ theo dõi các kết nối tcp với netstat

Tôi đã tìm thấy khoảng 1000 kết nối ở trạng thái TIME_WAIT, không biết điều đó có nghĩa gì về mặt hiệu suất, tôi chắc chắn rằng nó phải được thêm vào vấn đề.

Đầu ra của 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

Ngoài ra vào thời gian cao điểm, có khoảng 10-15k tcp kết nối đến máy chủ membase [cục bộ]

MỘT SỐ LRI TRONG ĐĂNG KÝ MODJK, tôi hy vọng điều này sẽ làm sáng tỏ vấn đề này ..

[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

// Đã giải quyết

tất cả các đề xuất có giá trị của bạn .. tôi đã bỏ lỡ các cài đặt maxThreads cho trình kết nối AJP 1.3 .. Bây giờ mọi thứ dường như được kiểm soát.

Tôi cũng sẽ bắt đầu nhìn vào các máy chủ thậm chí dựa trên nginx.


Cài đặt Keepalive của bạn như thế nào?
Tom O'Connor

Những loại lỗi nào mà khách hàng nhận được khi tải trang?
Shane Madden

1
Bạn đã tăng tối đa cho phép mô tả tệp mở cho người dùng apache / httpd chưa?
golja

@Tom Cài đặt Keep Alive của tôi là KeepAliveTimeout 10 trong httpd.conf
john Titus

3
Sản lượng của toptrông như thế nào trong thời gian này? Thế còn free -m? Và cuối cùng iostat?
Zypher

Câu trả lời:


13

Bạn đã tăng maxThread trong Trình kết nối AJP 1.3 trên cổng 8009 chưa?


1500 là những gì tôi có trên mỗi ví dụ tomcat
john Titus

@john, Bạn có nói rằng với mỗi Trình kết nối bạn đã chỉ định maxThreads = "1500" không? Bạn có thể đăng khổ thơ của mình cho Trình kết nối AJP 1.3 (cổng 8009) không?
HTTP500

cảm ơn vì đã chỉ ra điều này .. không có cài đặt maxThreads nào cho AJP1.3 cả .. đây có thể là lý do không?
john Titus

1
Có, thêm maxThread vào khổ thơ cho Trình kết nối đó. Mặc định là 200.
HTTP500

6

Xem xét việc thiết lập một máy chủ web ủy quyền không đồng bộ như nginxhoặc lighttpdtrước Apache. Apache phục vụ nội dung đồng bộ để nhân viên bị chặn cho đến khi khách hàng tải xuống nội dung được tạo đầy đủ (chi tiết hơn tại đây ). Thiết lập proxy không đồng bộ (không chặn) thường cải thiện đáng kể tình huống (tôi đã sử dụng để giảm số lượng nhân viên Apache đang chạy đồng thời từ 30 xuống còn 3-5 sử dụng nginxlàm proxy ủy quyền).


5

Tôi nghi ngờ vấn đề của bạn là ở tomcat chứ không phải apache, từ nhật ký bạn đã thể hiện. Khi bạn gặp 'lỗi 110' khi cố gắng kết nối lại vào tomcat, điều đó cho thấy bạn đã có một hàng đợi các kết nối đang chờ để được phục vụ mà không thể phù hợp hơn với thiết lập tồn đọng nghe cho ổ cắm nghe trong tomcat.

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.

Nếu tôi phải đoán, tôi sẽ nghi ngờ rằng phần lớn các yêu cầu HTTP khi máy chủ bị "nghẹt thở" bị chặn chờ đợi một cái gì đó quay trở lại từ tomcat. Tôi cá là nếu bạn đã cố gắng tìm nạp một số nội dung tĩnh được cung cấp trực tiếp bởi apache (thay vì được ủy quyền cho tomcat) thì điều này sẽ hoạt động ngay cả khi nó thường 'nghẹt thở'.

Thật không may, tôi không quen với tomcat, nhưng có cách nào để thao tác các cài đặt tương tranh của cái này không?

Ồ, và bạn cũng có thể cần xem xét khả năng các dịch vụ mạng bên ngoài giới hạn số lượng kết nối mà đang thực hiện với bạn xuống tới 300, do đó, sẽ không có gì khác biệt khi bạn thao tác đồng thời ở phía trước nếu thực tế mọi kết nối bạn thực hiện đều dựa vào phản hồi của dịch vụ web bên ngoài.

Trong một trong những bình luận của bạn, bạn đã đề cập đến dữ liệu sau 2 phút. Tôi khuyên bạn nên lưu bộ đệm phản hồi bạn nhận được từ dịch vụ này trong hai phút để giảm lượng kết nối đồng thời bạn đang lái xe sang dịch vụ web bên ngoài.


2

Bước đầu tiên để khắc phục sự cố này là cho phép mod_status của Apache và nghiên cứu báo cáo của nó - cho đến khi bạn thực hiện việc này, thực sự bạn đang đi bộ một cách mù quáng. Đó không phải là chính đáng. ;-)

Điều thứ hai cần đề cập (bản thân tôi không thích được trả lời các câu hỏi tôi không hỏi, nhưng ...) là sử dụng các máy chủ ngoại vi hiệu quả và đặc biệt hơn như thế nào nginx.

Ngoài ra, bạn đã chính xác restartapache, hoặc chỉ gracefully nạp lại nó? :)


Apache đã khởi động lại .. không phải là tải lại duyên dáng
john Titus

@johntitus, tốt mod_status, dù sao cũng là bạn của bạn. :)
poige

1

Đối với bất kỳ loại triển khai doanh nghiệp nào, MPM prefork chỉ là sự lựa chọn tồi tệ nhất mà bạn có thể thực hiện: nó ngấu nghiến tài nguyên như doanh nghiệp của bất kỳ ai và việc khởi động lại các chủ đề mất FOREVER so với các MPM khác.

Ít nhất là chuyển sang MPM worker (apache 2.2 trở lên) hoặc - tốt hơn nữa - nâng cấp lên phiên bản ổn định 2.4.2 hiện tại với MPM sự kiện mặc định của nó .

Cả hai sẽ dễ dàng xử lý hàng ngàn kết nối đồng thời với rất ít chi phí.


cảm ơn .. đã cố gắng quá .. không có may mắn. Kết nối TIME_WAIT tiếp tục tăng. Máy chủ dừng đáp ứng ở 350 kết nối
john Titus

1
Tôi không đồng ý rằng đó là lựa chọn tồi tệ nhất - đó là một lựa chọn tồi cho bối cảnh này và có khả năng các vấn đề sẽ được giảm bớt bằng cách sử dụng máy chủ luồng, nhưng giải pháp tốt hơn là sử dụng máy chủ dựa trên sự kiện (nginx hoặc lighttpd). Sự kiện dựa trên Apache chưa đủ chín chắn để được xem xét từ IMHO triển khai doanh nghiệp.
symcbean

1

Tôi biết đó là một câu chuyện cũ, nhưng tôi có 2 nhận xét.

Có một giới hạn được mã hóa cứng cho Chỉ thị ServerLimit . http://httpd.apache.org/docs/2.2/mod/mpm_common.html#serverlimit bạn sẽ thấy rằng nó tối đa 20000 / 200K.

Có giới hạn cứng của ServerLimit 20000 được biên dịch vào máy chủ (đối với MPM 200000 prefork). Điều này nhằm tránh các hiệu ứng khó chịu gây ra bởi lỗi chính tả.

Rõ ràng nodybo đã đề cập rằng đặt 2 thành một là một ý tưởng rất tồi :

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

nó có nghĩa là bạn sử dụng lại thời gian sớm, đoán xem? máy chủ có thể nói chuyện với máy khách sai dưới tải nặng.

Tôi tìm thấy một bài viết rất hay giải thích về điều đó nhưng - đó là tiếng Pháp ;-) http://vincent.bernat.im/fr/blog/2014-tcp-time-wait-state-linux.html


0

cực lớn với bộ nhớ 34GB.

Sắt lớn không phải là cách để mở rộng quy mô web mà bạn chỉ đang di chuyển các nút thắt xung quanh. Nhưng ngay cả với nhiều bộ nhớ này, tôi nghi ngờ rằng 50000 kết nối đang đẩy những gì hệ thống có khả năng đặc biệt nếu:

Trong giờ cao điểm, máy chủ bị sặc ở khoảng 300 quy trình httpd

Sẽ rất hữu ích nếu bạn giải thích ý của bạn là "máy chủ cuộn cảm".

Cũng rất kỳ quặc khi có giới hạn kết nối cao như vậy nhưng giới hạn rất thấp cho độ trễ (máy chủ dự phòng tối thiểu / tối đa).

Mặc dù trích xuất các lỗi bạn cung cấp không hiển thị thông báo 'quá nhiều tệp đang mở' Tôi sẽ bắt đầu bằng cách xem số lượng mô tả tệp mở và cài đặt ulimit.


Máy chủ CHokes như trong nó không đáp ứng với các tệp html thông thường ..
john Titus

Bây giờ tôi đã thay đổi maxClents thành 3000 .. vẫn là vấn đề tương tự
john Titus

0

Có lẽ người dùng Apache sắp hết xử lý tệp được cho phép? Bạn đã không đề cập đến tất cả trong bài viết của bạn. Có bao nhiêu tệp xử lý Apache hiện được phép có?


Xử lý tập tin 128192
john Titus

0

Điều này giống như một bình luận, nhưng không thể vì tôi có ít danh tiếng hơn. Đã giải quyết vấn đề chính xác tương tự như @john Titus.

Chúng tôi đã tạo trình kết nối AJP MaxThreadsgần với giới hạn Chủ đề Apache của chúng tôi để giải quyết vấn đề.

Để theo dõi điều này, chúng tôi đã tìm kiếm SYN_SENT trợ giúp về trạng thái cổng netstat bằng lệnh netstat trên cổng AJP của chúng tôi.

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

Điều này đã giảm xuống 0, luôn là một số lớn trước khi giới hạn MaxThread được đặt trên Trình kết nối AJP.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.