Hiệu suất Điều chỉnh Máy chủ Apache tải cao


12

Tôi đang tìm hiểu một số vấn đề về hiệu suất máy chủ mà tôi đang gặp phải với một máy chủ web tải nặng (đối với chúng tôi). Môi trường như sau:

  • Debian Lenny (tất cả các gói ổn định + được vá vào các bản cập nhật bảo mật)
  • Apache 2.2.9
  • PHP 5.2.6
  • Ví dụ lớn về Amazon EC2

Hành vi chúng ta đang thấy là web thường cảm thấy phản hồi, nhưng với một chút chậm trễ để bắt đầu xử lý yêu cầu - đôi khi chỉ là một phần của giây, đôi khi là 2-3 giây trong thời gian sử dụng cao nhất của chúng tôi. Tải thực tế trên máy chủ đang được báo cáo là rất cao - thường là 10.xx hoặc 20.xx như được báo cáo bởi top. Hơn nữa, chạy những thứ khác trên máy chủ trong những khoảng thời gian này (thậm chí vi) là rất chậm, vì vậy tải chắc chắn là ở đó. Thật kỳ lạ, Apache vẫn rất nhạy, ngoài sự chậm trễ ban đầu đó.

Chúng tôi đã cấu hình Apache như sau, sử dụng prefork:

StartServers          5
MinSpareServers       5
MaxSpareServers      10
MaxClients          150
MaxRequestsPerChild   0

Và KeepAlive như:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

Nhìn vào trang trạng thái máy chủ, ngay cả tại những thời điểm tải nặng này, chúng tôi hiếm khi đạt đến giới hạn máy khách, thường phục vụ từ 80 đến 100 yêu cầu và nhiều trong số đó ở trạng thái giữ. Điều đó bảo tôi loại trừ yêu cầu ban đầu chậm chạp là "chờ xử lý" nhưng tôi có thể sai.

Giám sát CloudWatch của Amazon cho tôi biết rằng ngay cả khi HĐH của chúng tôi báo cáo tải> 15, mức sử dụng CPU cá thể của chúng tôi nằm trong khoảng 75-80%.

Ví dụ đầu ra từ top:

top - 15:47:06 up 31 days,  1:38,  8 users,  load average: 11.46, 7.10, 6.56
Tasks: 221 total,  28 running, 193 sleeping,   0 stopped,   0 zombie
Cpu(s): 66.9%us, 22.1%sy,  0.0%ni,  2.6%id,  3.1%wa,  0.0%hi,  0.7%si,  4.5%st
Mem:   7871900k total,  7850624k used,    21276k free,    68728k buffers
Swap:        0k total,        0k used,        0k free,  3750664k cached

Phần lớn các quy trình trông giống như:

24720 www-data  15   0  202m  26m 4412 S    9  0.3   0:02.97 apache2                                                                       
24530 www-data  15   0  212m  35m 4544 S    7  0.5   0:03.05 apache2                                                                       
24846 www-data  15   0  209m  33m 4420 S    7  0.4   0:01.03 apache2                                                                       
24083 www-data  15   0  211m  35m 4484 S    7  0.5   0:07.14 apache2                                                                       
24615 www-data  15   0  212m  35m 4404 S    7  0.5   0:02.89 apache2            

Ví dụ đầu ra từ vmstatcùng lúc với ở trên:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 8  0      0 215084  68908 3774864    0    0   154   228    5    7 32 12 42  9
 6 21      0 198948  68936 3775740    0    0   676  2363 4022 1047 56 16  9 15
23  0      0 169460  68936 3776356    0    0   432  1372 3762  835 76 21  0  0
23  1      0 140412  68936 3776648    0    0   280     0 3157  827 70 25  0  0
20  1      0 115892  68936 3776792    0    0   188     8 2802  532 68 24  0  0
 6  1      0 133368  68936 3777780    0    0   752    71 3501  878 67 29  0  1
 0  1      0 146656  68944 3778064    0    0   308  2052 3312  850 38 17 19 24
 2  0      0 202104  68952 3778140    0    0    28    90 2617  700 44 13 33  5
 9  0      0 188960  68956 3778200    0    0     8     0 2226  475 59 17  6  2
 3  0      0 166364  68956 3778252    0    0     0    21 2288  386 65 19  1  0

Và cuối cùng, đầu ra từ Apache server-status:

Server uptime: 31 days 2 hours 18 minutes 31 seconds
Total accesses: 60102946 - Total Traffic: 974.5 GB
CPU Usage: u209.62 s75.19 cu0 cs0 - .0106% CPU load
22.4 requests/sec - 380.3 kB/second - 17.0 kB/request
107 requests currently being processed, 6 idle workers

C.KKKW..KWWKKWKW.KKKCKK..KKK.KKKK.KK._WK.K.K.KKKKK.K.R.KK..C.C.K
K.C.K..WK_K..KKW_CK.WK..W.KKKWKCKCKW.W_KKKKK.KKWKKKW._KKK.CKK...
KK_KWKKKWKCKCWKK.KKKCK..........................................
................................................................

Từ kinh nghiệm hạn chế của mình, tôi rút ra kết luận / câu hỏi sau:

  • Chúng tôi có thể cho phép quá nhiều KeepAliveyêu cầu

  • Tôi thấy có một khoảng thời gian chờ đợi IO trong vmstat mặc dù không nhất quán và không nhiều (tôi nghĩ vậy?) Nên tôi không chắc đây có phải là mối quan tâm lớn hay không, tôi ít kinh nghiệm với vmstat

  • Cũng trong vmstat, tôi thấy trong một số lần lặp, một số quy trình đang chờ được phục vụ, đó là điều tôi cho là sự chậm trễ tải trang ban đầu trên máy chủ web của chúng tôi, có thể là do nhầm lẫn

  • Chúng tôi phục vụ hỗn hợp nội dung tĩnh (75% trở lên) và nội dung tập lệnh và nội dung tập lệnh thường khá chuyên sâu về bộ xử lý, vì vậy việc tìm sự cân bằng phù hợp giữa hai nội dung là rất quan trọng; Về lâu dài, chúng tôi muốn chuyển trạng thái sang nơi khác để tối ưu hóa cả hai máy chủ nhưng phần mềm của chúng tôi chưa sẵn sàng cho điều đó ngày hôm nay

Tôi rất vui khi cung cấp thêm thông tin nếu có ai có ý tưởng nào, lưu ý khác là đây là bản cài đặt sản xuất có tính sẵn sàng cao nên tôi cảnh giác thực hiện chỉnh sửa sau khi chỉnh sửa và đó là lý do tại sao tôi không chơi với những thứ như KeepAlivegiá trị bản thân chưa.


+1 Câu hỏi tuyệt vời đẫm máu, diễn đạt tốt và suy nghĩ. Hy vọng bạn đã có câu trả lời xứng đáng!
Dave Rix

Câu trả lời:


7

Tôi sẽ bắt đầu bằng cách thừa nhận rằng tôi không quan tâm nhiều đến việc chạy các thứ trên đám mây - nhưng dựa trên kinh nghiệm của tôi ở nơi khác, tôi nói rằng cấu hình máy chủ web này phản ánh lưu lượng truy cập khá thấp. Rằng runqueue quá lớn cho thấy rằng không có đủ CPU có sẵn để đối phó với nó. Những gì khác là trong runqueue?

Chúng tôi có thể cho phép quá nhiều yêu cầu KeepAlive

Không - keeplive vẫn cải thiện hiệu suất, các trình duyệt hiện đại rất thông minh về việc biết khi nào nên xử lý song song và khi nào chạy yêu cầu song song, mặc dù thời gian chờ là 5 giây vẫn còn khá cao và bạn đã có RẤT NHIỀU máy chủ đang chờ - trừ khi bạn Có vấn đề về độ trễ HUGE tôi khuyên bạn nên giảm xuống còn 2-3. Điều này sẽ rút ngắn runqueue một chút.

Nếu bạn chưa cài đặt mod_deflate trên máy chủ web - thì tôi khuyên bạn nên làm như vậy - và thêm ob_gzhandler () vào tập lệnh PHP của bạn. Bạn có thể làm điều này như một khoản tự động trả trước:

if(!ob_start("ob_gzhandler")) ob_start();

(vâng, việc nén sử dụng nhiều CPU hơn - nhưng bạn nên tiết kiệm tổng thể CPU bằng cách đưa máy chủ ra khỏi đường chạy nhanh hơn / xử lý ít gói TCP hơn - và như một phần thưởng, trang web của bạn cũng nhanh hơn).

Tôi khuyên bạn nên đặt giới hạn trên cho MaxRequestsPerChild - giả sử khoảng 500. Điều này chỉ cho phép một số doanh thu trên các quy trình trong trường hợp bạn bị rò rỉ bộ nhớ ở đâu đó. Các quy trình httpd của bạn trông rất LỚN - đảm bảo bạn đã xóa bất kỳ mô-đun apache nào bạn không cần và đảm bảo rằng bạn đang phục vụ nội dung tĩnh với thông tin bộ đệm tốt.

Nếu bạn vẫn gặp vấn đề, thì vấn đề có thể nằm trong mã PHP (nếu bạn chuyển sang sử dụng fastCGI, điều này sẽ rõ ràng mà không có bất kỳ hình phạt hiệu suất lớn nào).

cập nhật

Nếu nội dung tĩnh không thay đổi nhiều trên các trang, thì nó cũng có thể đáng để thử nghiệm:

if (count($_COOKIE)) {
    header('Connection: close');
}

trên các kịch bản PHP quá.


Trong số rất nhiều câu trả lời hay, tôi đánh dấu đây là câu trả lời được chấp nhận vì bạn nói rõ rằng đây là vấn đề liên quan đến CPU (phần lớn là do ứng dụng kém mà chúng tôi đang chạy) và đó chắc chắn là trường hợp. Tôi đã triển khai lại mọi thứ trên các phiên bản EC2 2 lần (tăng từ mức lớn) và hầu hết các vấn đề đã biến mất, mặc dù nhiều đặc điểm hiệu suất khác vẫn còn đó. Chúng tôi chỉ có một ứng dụng duy nhất chạy trên các máy chủ này và nó thật xấu xí.
tương lai

4

Bạn nên xem xét việc cài đặt proxy ngược không đồng bộ, vì một số quy trình ở trạng thái W cũng khá cao. Các quy trình Apache của bạn dường như dành nhiều thời gian để gửi nội dung đến các máy khách chậm trên mạng bị chặn trên đó. Nginx hoặc lighttpd như một lối vào máy chủ Apache của bạn có thể giảm đáng kể một số quy trình ở trạng thái W. Và có, bạn nên hạn chế một số yêu cầu giữ. Có lẽ nó đáng để cố gắng tắt.

BTW, 107 quy trình Apache quá cao cho 22 rps, tôi đã có thể phục vụ 100-120 rps chỉ bằng 5 quy trình Apache. Có lẽ, bước tiếp theo là hồ sơ ứng dụng của bạn.


Phải, chắc chắn đồng ý rằng ứng dụng là một phần lớn của vấn đề. Nó đã được thuê ngoài và từ đó đã phải chịu rất nhiều bản vá lỗi và điều đó chỉ làm cho nó tồi tệ hơn, và một nỗ lực thiết kế lại đang diễn ra. Tối nay tôi đã thử tắt KeepAlive để không có hiệu quả thực sự và bước tiếp theo của tôi là thử proxy ngược đó, có lẽ với nginx dựa trên tất cả những gì tôi đã đọc.
tương lai

Để theo dõi, tôi đã bắt đầu thử nghiệm proxy ngược và có thể sẽ triển khai nó trong sản xuất trong tương lai gần. Cảm ơn bạn (và những người khác đã đề xuất nó) cho ý tưởng này, đó không phải là điều tôi từng sửa đổi trước đây nhưng tôi nghĩ nó sẽ tạo ra ảnh hưởng cho đến khi chúng tôi có thể thiết kế lại toàn diện.
tương lai

1

Bạn có hai hàng trong vmstat cho thấy thời gian chờ CPU của bạn khá cao và xung quanh những hàng đó, bạn thực hiện một số lần ghi (io - bo) và chuyển đổi ngữ cảnh hợp lý. Tôi sẽ xem xét những gì các khối viết, và làm thế nào để loại bỏ sự chờ đợi đó. Tôi nghĩ rằng sự cải thiện nhất có thể được tìm thấy trong việc cải thiện IO đĩa của bạn. Kiểm tra syslog - đặt nó để viết async. Đảm bảo bộ đệm ghi của bộ điều khiển của bạn đang hoạt động (kiểm tra nó - bạn có thể có pin xấu).

Keepalive không gây ra sự cố hoàn hảo của bạn, nó giúp bạn tiết kiệm thời gian thiết lập kết nối nếu bạn không chạy bộ đệm trước mặt. Bạn có thể va chạm MaxSpareServers một chút để trong một cuộc khủng hoảng bạn không chờ đợi tất cả các dĩa.


Tôi không đủ quen thuộc với syslog để biết cách đặt nó cho ghi không đồng bộ trong Apache, mặc dù tôi chắc chắn sẽ tìm kiếm và tìm kiếm nó. Tôi đã thực hiện một số thay đổi tối nay liên quan đến KeepAlive và MaxSpareServers để không có hiệu quả thực sự, tôi đồng ý về việc để lại nhiều phụ tùng hơn, tôi đã bỏ lỡ điều đó. Một (chất lượng) kém của ứng dụng của chúng tôi là nó ghi rất nhiều vào các tệp phiên của người dùng (vâng, các tệp) là nơi tôi bắt đầu nghĩ rằng chúng ta đang chịu đựng. Tôi có tùy chọn di chuyển quản lý phiên vào cơ sở dữ liệu, mà tôi có khả năng sẽ thử tiếp theo.
tương lai

Có, tôi đồng ý rằng phiên ghi của bạn là nguồn gốc của vấn đề. Bạn có thể mất đĩa phiên ghi nếu bạn đang sử dụng phiên php - cài đặt memcache và đặt session.save_handler của PHP thành memcache và session.save_path thành tcp : //127.0.0.1: 11211 (hoặc bất cứ nơi nào bạn thiết lập memcache). Ghi nhật ký của Apache là không đồng bộ theo mặc định, nhưng đôi khi các ứng dụng web có thể sử dụng syslog hoặc syslog có thể là trò chuyện và nó đang thực hiện đồng bộ hóa cho mọi dòng. Rốt cuộc, có vẻ như đó không phải là vấn đề trong trường hợp của bạn. Bạn có thể tiền tố các dòng nhập tệp với '-' trong syslog.conf để bỏ qua đồng bộ hóa.
đậu

0

bạn nên cân nhắc tắt tắt như một lần thử đầu tiên ...

với 107 yêu cầu được xử lý, tôi sẽ giữ MaxSpareServers cao hơn những gì bạn đã đặt ...

IMHO trong nginx dài hạn như proxy ngược cho nội dung tĩnh nên được xem xét


0

Đề nghị đầu tiên: vô hiệu hóa thủ tục. Tôi chỉ cần nó khi tôi có thể xác định một tình huống cụ thể là hiệu suất tăng lên, nhưng trong các yêu cầu chung / giây giảm khi bật Keepalive.

Gợi ý thứ hai: Đặt MaxRequestsPerChild. Tôi lặp lại symcbean ở đây, nó sẽ giúp xử lý cuộn qua trong trường hợp rò rỉ bộ nhớ. 500 là một điểm khởi đầu tốt.

Gợi ý thứ ba: Tăng MaxCl Client. Một tính toán sân bóng cho điều này là (bộ nhớ vật lý - bộ nhớ được sử dụng bởi quy trình không httpd) / kích thước của mỗi quy trình httpd. Tùy thuộc vào cách httpd được biên dịch, con số này tối đa là 255. Tôi sử dụng 250 cho các máy chủ công cộng của mình để đối phó với google / yahoo / MS thu thập dữ liệu các hệ thống.

Đề xuất đáng tin cậy: Tăng MaxSpareServers: đại loại như 4-5x MinSpareServers.

Không thể thực hiện các đề xuất đó, tôi sẽ xem xét cân bằng tải với proxy ngược hoặc memcache cho DB.

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.