Return-Path: Delivered-To: apmail-perl-modperl-cvs-archive@www.apache.org Received: (qmail 3535 invoked from network); 28 Jun 2006 15:55:02 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 28 Jun 2006 15:55:02 -0000 Received: (qmail 87920 invoked by uid 500); 28 Jun 2006 15:55:02 -0000 Delivered-To: apmail-perl-modperl-cvs-archive@perl.apache.org Received: (qmail 87845 invoked by uid 500); 28 Jun 2006 15:55:02 -0000 Mailing-List: contact modperl-cvs-help@perl.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@perl.apache.org List-Id: Delivered-To: mailing list modperl-cvs@perl.apache.org Received: (qmail 87834 invoked by uid 99); 28 Jun 2006 15:55:02 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Jun 2006 08:55:02 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Jun 2006 08:55:01 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 45DC01A983A; Wed, 28 Jun 2006 08:54:41 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r417801 - /perl/Apache-SizeLimit/trunk/README Date: Wed, 28 Jun 2006 15:54:40 -0000 To: modperl-cvs@perl.apache.org From: geoff@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20060628155441.45DC01A983A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: geoff Date: Wed Jun 28 08:54:40 2006 New Revision: 417801 URL: http://svn.apache.org/viewvc?rev=417801&view=rev Log: stick in SizeLimit.pm pod Modified: perl/Apache-SizeLimit/trunk/README Modified: perl/Apache-SizeLimit/trunk/README URL: http://svn.apache.org/viewvc/perl/Apache-SizeLimit/trunk/README?rev=417801&r1=417800&r2=417801&view=diff ============================================================================== --- perl/Apache-SizeLimit/trunk/README (original) +++ perl/Apache-SizeLimit/trunk/README Wed Jun 28 08:54:40 2006 @@ -0,0 +1,293 @@ +NAME + +Apache::SizeLimit - Because size does matter. + +SYNOPSIS + + + $Apache::SizeLimit::MAX_UNSHARED_SIZE = 120000; # 120MB + + + PerlCleanupHandler Apache::SizeLimit + +DESCRIPTION + +This module allows you to kill off Apache httpd processes if they grow +too large. You can make the decision to kill a process based on its +overall size, by setting a minimum limit on shared memory, or a +maximum on unshared memory. + +You can set limits for each of these sizes, and if any limit is not +met, the process will be killed. + +You can also limit the frequency that these sizes are checked so that +this module only checks every N requests. + +This module is highly platform dependent, please read the CAVEATS +section. + +API + +You can set set the size limits from a Perl module or script loaded by +Apache: + + use Apache::SizeLimit; + + Apache::SizeLimit::setmax(150_000); # Max size in KB + Apache::SizeLimit::setmin(10_000); # Min share in KB + Apache::SizeLimit::setmax_unshared(120_000); # Max unshared size in KB + +Then in your Apache configuration, make Apache::SizeLimit a +C: + + PerlCleanupHandler Apache::SizeLimit + +If you want to use C from a registry script, you +must call one of the above functions for every request: + + use Apache::SizeLimit + + main(); + + sub { + Apache::SizeLimit::setmax(150_000); + + # handle request + }; + +Calling any one of C, C, or C +will install C as a cleanup handler, if it's not +already installed. + +If you want to combine this module with a cleanup handler of your own, +make sure that C is the last handler run: + + PerlCleanupHandler Apache::SizeLimit My::CleanupHandler + +Remember, mod_perl will run stacked handlers from right to left, as +they're defined in your configuration. + +You can explicitly call the C function +from your own handler: + + package My::CleanupHandler + + sub handler { + my $r = shift; + + # do my thing + + return Apache::SizeLimit::handler($r); + } + +Since checking the process size can take a few system calls on some +platforms (e.g. linux), you may want to only check the process size +every N times. To do so, simple set the +C<$Apache::SizeLimit::CHECK_EVERY_N_REQUESTS> global. + + $Apache::SizeLimit::CHECK_EVERY_N_REQUESTS = 2; + +Now C will only check the process size on every +other request. + +Deprecated API + +Previous versions of this module documented three globals for defining +memory size limits: + + $Apache::SizeLimit::MAX_PROCESS_SIZE + + $Apache::SizeLimit::MIN_SHARE_SIZE + + $Apache::SizeLimit::MAX_UNSHARED_SIZE + +Direct use of these globals is deprecated, but will continue to work +for the foreseeable future. + +ABOUT THIS MODULE + +This module was written in response to questions on the mod_perl +mailing list on how to tell the httpd process to exit if it gets too +big. + +Actually, there are two big reasons your httpd children will grow. +First, your code could have a bug that causes the process to increase +in size very quickly. Second, you could just be doing operations that +require a lot of memory for each request. Since Perl does not give +memory back to the system after using it, the process size can grow +quite large. + +This module will not really help you with the first problem. For that +you should probably look into C or some other means +of setting a limit on the data size of your program. BSD-ish systems +have C, which will kill your memory gobbling processes. +However, it is a little violent, terminating your process in +mid-request. + +This module attempts to solve the second situation, where your process +slowly grows over time. It checks memory usage after every request, +and if it exceeds a threshold, exits gracefully. + +By using this module, you should be able to discontinue using the +Apache configuration directive B, although for +some folks, using both in combination does the job. + +SHARED MEMORY OPTIONS + +In addition to simply checking the total size of a process, this +module can factor in how much of the memory used by the process is +actually being shared by copy-on-write. If you don't understand how +memory is shared in this way, take a look at the mod_perl Guide at +http://perl.apache.org/guide/. + +You can take advantage of the shared memory information by setting a +minimum shared size and/or a maximum unshared size. Experience on one +heavily trafficked mod_perl site showed that setting maximum unshared +size and leaving the others unset is the most effective policy. This +is because it only kills off processes that are truly using too much +physical RAM, allowing most processes to live longer and reducing the +process churn rate. + +CAVEATS + +This module is highly platform dependent, since finding the size of a +process is different for each OS, and some platforms may not be +supported. In particular, the limits on minimum shared memory and +maximum shared memory are currently only supported on Linux and BSD. +If you can contribute support for another OS, patches are very +welcome. + +Currently supported OSes: + +linux + +For linux we read the process size out of F. This +is a little slow, but usually not too bad. If you are worried about +performance, try only setting up the the exit handler inside CGIs +(with the C function), and see if the CHECK_EVERY_N_REQUESTS +option is of benefit. + +Since linux 2.6 F does not report the amount of +memory shared by the copy-on-write mechanism as shared memory. Hence +decisions made on the basis of C or +C are inherently wrong. + +To correct this situation, as of the 2.6.14 release of the kernel, +there is F entry for each +process. F reports various sizes for each memory +segment of a process and allows us to count the amount of shared +memory correctly. + +If C detects a kernel that supports +F and if the C module is installed it +will use them instead of F. You can prevent +C from using F and turn on the +old behaviour by setting C<$Apache::SizeLimit::USE_SMAPS> to 0. + +C itself will C<$Apache::SizeLimit::USE_SMAPS> to 0 +if it cannot load C or if your kernel does not support +F. Thus, you can check it to determine what is +actually used. + +NOTE: Reading F is expensive compared to +F. It must look at each page table entry of a process. +Further, on multiprocessor systems the access is synchronized with +spinlocks. Hence, you are encouraged to set the C +option. + +The following example shows the effect of copy-on-write: + + + require Apache::SizeLimit; + package X; + use strict; + use Apache::Constants qw(OK); + + my $x= "a" x (1024*1024); + + sub handler { + my $r = shift; + my ($size, $shared) = $Apache::SizeLimit::check_size(); + $x =~ tr/a/b/; + my ($size2, $shared2) = $Apache::SizeLimit::check_size(); + $r->content_type('text/plain'); + $r->print("1: size=$size shared=$shared\n"); + $r->print("2: size=$size2 shared=$shared2\n"); + return OK; + } + + + + SetHandler modperl + PerlResponseHandler X + + +The parent apache allocates a megabyte for the string in C<$x>. The +C-command then overwrites all "a" with "b" if the handler is +called with an argument. This write is done in place, thus, the +process size doesn't change. Only C<$x> is not shared anymore by +means of copy-on-write between the parent and the child. + +If F is available curl shows: + + r2@s93:~/work/mp2> curl http://localhost:8181/X + 1: size=13452 shared=7456 + 2: size=13452 shared=6432 + +Shared memory has lost 1024 kB. The process' overall size remains unchanged. + +Without F it says: + + r2@s93:~/work/mp2> curl http://localhost:8181/X + 1: size=13052 shared=3628 + 2: size=13052 shared=3636 + +One can see the kernel lies about the shared memory. It simply doesn't +count copy-on-write pages as shared. + +solaris 2.6 and above + +For solaris we simply retrieve the size of F, which +contains the address-space image of the process, and convert to KB. +Shared memory calculations are not supported. + +NOTE: This is only known to work for solaris 2.6 and above. Evidently +the F filesystem has changed between 2.5.1 and 2.6. Can anyone +confirm or deny? + +*bsd* + +Uses C to determine process size. This is +pretty efficient (a lot more efficient than reading it from the +F fs anyway). + +AIX? + +Uses C to determine process size. Not +sure if the shared memory calculations will work or not. AIX users? + +Win32 + +Uses C to access process memory information. +C can be installed under ActiveState perl using the +supplied ppm utility. + +If your platform is not supported, then please send a patch to check +the process size. The more portable/efficient/correct the solution the +better, of course. + +AUTHOR + +Doug Bagley , channeling Procrustes. + +Brian Moseley : Solaris 2.6 support + +Doug Steinwand and Perrin Harkins : added support + for shared memory and additional diagnostic info + +Matt Phillips and Mohamed Hendawi +: Win32 support + +Dave Rolsky , maintenance and fixes outside of +mod_perl tree (0.06). +