2010-01-07 52 views
7

Các kịch bản Perl khác nhau (Server Side Includes) đang gọi một mô-đun Perl với nhiều chức năng trên một trang web. EDIT: Các tập lệnh đang sử dụng sử dụng lib để tham chiếu các thư viện từ một thư mục. Trong thời gian bận rộn, các tập lệnh (không phải thư viện) trở thành zombie và quá tải máy chủ.Làm cách nào để tránh zombie trong các tập lệnh Perl CGI chạy dưới Apache 1.3?

Các danh sách server:

319 ?  Z  0:00 [scriptname1.pl] <defunct>  
320 ?  Z  0:00 [scriptname2.pl] <defunct>  
321 ?  Z  0:00 [scriptname3.pl] <defunct> 

Tôi có hàng trăm trường hợp của mỗi người.

EDIT: Chúng tôi không sử dụng ngã ba, hệ thống hoặc exec, ngoài hình thành thị SSI

<!--#exec cgi="/cgi-bin/scriptname.pl"--> 

Theo như tôi biết, trong trường hợp này httpd chính nó sẽ là chủ sở hữu của quá trình. MaxRequestPerChild được đặt thành 0 không nên để cha mẹ chết trước khi quá trình con hoàn tất. Cho đến nay chúng tôi đã thấy rằng tạm thời đình chỉ một số tập lệnh giúp máy chủ đối phó với các quy trình không còn tồn tại và ngăn không cho nó rơi xuống, tuy nhiên các quy trình zombie vẫn đang hình thành mà không nghi ngờ gì. Rõ ràng gbacon dường như là gần nhất với sự thật với lý thuyết của mình rằng máy chủ không thể đối phó với tải.

Điều gì có thể dẫn đến httpd bỏ qua các quy trình này? Có cách nào tốt nhất để ngăn chặn những điều này xảy ra không?

Cảm ơn

Trả lời: Điểm đi vào Rob. Như ông nói, các kịch bản CGI tạo ra SSI sẽ không được xử lý bởi SSI. Việc đánh giá của SSI xảy ra trước khi hoạt động của CGI trong chu kỳ yêu cầu Apache 1.3. Điều này đã được sửa với Apache 2.0 và sau đó để CGI có thể tạo ra các lệnh SSI.

Vì chúng tôi đang chạy trên Apache 1.3, cho mỗi lần xem trang, SSI đã chuyển thành các quy trình không còn tồn tại. Mặc dù máy chủ đang cố gắng xóa chúng nhưng nó quá bận rộn với các tác vụ đang chạy để có thể thành công. Kết quả là, máy chủ rơi xuống và trở nên không phản hồi. Là một giải pháp ngắn hạn, chúng tôi đã xem xét tất cả SSI và chuyển một số quy trình sang phía máy khách để giải phóng tài nguyên máy chủ và dành thời gian để dọn dẹp. Sau đó chúng tôi nâng cấp lên Apache 2.2.

+9

bạn cần ném một quả bom ống –

+5

Bắn hai thùng cũng hoạt động tốt. – Nate

+0

Đừng để họ ăn não của bạn nữa. – Hai

Trả lời

2

Tôi vừa thấy nhận xét của bạn rằng bạn đang chạy Apache 1.3 và có thể liên quan đến sự cố của bạn.

SSI có thể chạy CGI. Nhưng các kịch bản CGI tạo ra SSI sẽ không được xử lý bởi SSI. Việc đánh giá của SSI xảy ra trước khi hoạt động của CGI trong chu kỳ yêu cầu Apache 1.3. Điều này đã được sửa với Apache 2.0 và sau đó để CGI có thể tạo ra các lệnh SSI.

Như tôi đã đề xuất ở trên, hãy thử chạy tập lệnh của bạn một mình và xem kết quả đầu ra. Họ có tạo ra SSI không?

Chỉnh sửa: Bạn đã thử khởi chạy một tập lệnh Perl CGI tầm thường để chỉ in ra một phản hồi HTTP kiểu Xin chào thế giới?

Sau đó, nếu công trình này thêm một tầm thường chỉ SSI như

<!--#printenv --> 

và xem những gì sẽ xảy ra.

Chỉnh sửa 2: Chỉ cần nhận ra điều gì có thể xảy ra. Zombies xảy ra khi một tiến trình con thoát ra và không bị gặt. Các quy trình này được treo xung quanh và từ từ sử dụng tài nguyên trong bảng quy trình. Một tiến trình không có cha mẹ là một quá trình mồ côi.

Bạn có đang tắt các quy trình trong tập lệnh Perl không? Nếu vậy, bạn đã thêm một cuộc gọi waitpid() cho phụ huynh chưa?

Bạn cũng đã thoát đúng trong tập lệnh chưa?

CORE::exit(0); 
+0

Tôi chạy tất cả các tập lệnh thông qua trình gỡ lỗi và đã xóa tất cả các lỗi và cảnh báo. Chúng tạo ra đầu ra đúng cách. Chúng tôi sắp nâng cấp lên 2.0. Bạn có nghĩ rằng sẽ giúp đỡ? –

+0

Ok. Làm việc tốt với trình gỡ lỗi để loại bỏ tất cả các lỗi và cảnh báo. Có bất kỳ CGL Perl nào của bạn đang chạy thành công để hoàn thành không? –

+0

Như tôi đã nói họ đang chạy tốt. Ngoài thực tế là họ trở thành zombie họ đang chạy hoàn hảo. –

7

More Band-Aid hơn thực hành tốt nhất, nhưng đôi khi bạn có thể nhận được ngay với đơn giản

$SIG{CHLD} = "IGNORE"; 

Theo perlipc documentation

Trên hầu hết các nền tảng Unix, các CHLD (đôi khi còn được gọi là CLD) tín hiệu có hành vi đặc biệt đối với giá trị 'IGNORE'. Đặt $SIG{CHLD} thành 'IGNORE' trên nền tảng như vậy có tác dụng không tạo quy trình zombie khi quy trình gốc không thành công theo số wait() về quy trình con của nó (tức là, quy trình con được tự động gặt hái). Gọi số wait() với $SIG{CHLD} được đặt thành 'IGNORE' thường trả về -1 trên các nền tảng như vậy.

Nếu bạn quan tâm đến các trạng thái thoát của tiến trình con, bạn cần phải thu thập chúng (thường được gọi là "gặt hái") bằng cách gọi wait hoặc waitpid. Mặc dù tên đáng sợ, một zombie chỉ là một quá trình con đã thoát nhưng tình trạng vẫn chưa được gặt hái.

Nếu các chương trình Perl của bạn là các quá trình con trở thành zombie, nghĩa là các phụ huynh (những người đang giả mạo và quên mã của bạn) cần phải tự dọn dẹp. Một quá trình không thể ngăn bản thân trở thành một zombie.

+0

Cảm ơn rất nhiều G. Tôi không nói rằng tôi hiểu cách thức hoạt động nhưng tôi sẽ đọc thêm về nó. Tôi cho rằng CHLD đi vào kịch bản gọi. Có đúng không? –

+5

waitpid (-1, WNOHANG) sẽ không chặn, vì vậy nó có thể được gọi định kỳ để thu thập trạng thái thoát trẻ em. Sử dụng một vòng lặp như thế này để gặt hái tất cả các thây ma của bạn: trong khi (($ pid = waitpid (-1, WNOHANG))> 0) ... –

+0

@G Berdal Các kịch bản của bạn được bắt đầu như thế nào? Bạn có kiểm soát mã đó không? –

0

Vì bạn có tất cả các bit chính mình, tôi khuyên bạn nên chạy từng tập lệnh riêng lẻ từ dòng lệnh để xem bạn có thể phát hiện ra các tập lệnh đang treo hay không.

Danh sách ps có hiển thị số lượng phiên bản của một tập lệnh cụ thể không?

Bạn có đang chạy CGI bằng mod_perl không?

Chỉnh sửa: Chỉ cần xem nhận xét của bạn về SSI. Đừng quên rằng chỉ thị SSI có thể tự chạy các tập lệnh Perl. Có một cái nhìn để xem những gì CGI đang cố gắng để chạy?

Chúng có phụ thuộc vào một máy chủ hoặc dịch vụ khác không?

+0

Tôi đã phát hiện ra những cái đang treo. Gần như tất cả các SSI trên trang web trở thành nhiều trường hợp zombie. Họ đang gọi một thư viện cho các chức năng. Những gì tôi không chắc chắn về những người được coi là một phụ huynh cho những? –

+0

Quá trình được gọi là SSI hoặc CGI là cha mẹ của nó. Bạn có thể thử sử dụng 'ps' để tìm kiếm ppid (id tiến trình cha) và sau đó nhìn thấy quá trình đó là gì, nhưng tôi không tích cực cho dù' ps' sẽ trả về ppid cho zombie. (Có vẻ như nó nên, kể từ khi zombie phải biết ai phải gặt hái nó, tôi chỉ không xác minh rằng nó hoạt động.) Đối với tôi, đầu ra của 'ps -l'bao gồm ppid; kiểm tra trang người đàn ông địa phương của bạn nếu 'ps' của bạn hoạt động khác nhau. –

+0

@Dave, khi một quá trình là một zombie, nó không có ppid theo định nghĩa. –

Các vấn đề liên quan