Revision a4bd0c54
Von Moritz Bunkus vor etwa 9 Jahren hinzugefügt
config/kivitendo.conf.default | ||
---|---|---|
65 | 65 |
# and "en" (English, not perfect) are available. |
66 | 66 |
language = de |
67 | 67 |
|
68 |
# The memory limits given here determine the maximum process size |
|
69 |
# (vsz, the total amount of memory this process uses including memory |
|
70 |
# swapped out or shared with other processes) or resident set size |
|
71 |
# (rss, the amount of memory not swapped out/shared with other |
|
72 |
# processes). If either limit is reached at the end of the request |
|
73 |
# then the kivitendo process will exit. |
|
74 |
# |
|
75 |
# This only makes sense when running under FCGI. The FCGI manager will |
|
76 |
# then automatically start a new process. |
|
77 |
# |
|
78 |
# Numbers can be postfixed with KB, MB, GB. If no number is given or |
|
79 |
# the number is 0 then no checking will be performed. |
|
80 |
memory_limit_rss = |
|
81 |
memory_limit_vsz = |
|
82 |
|
|
68 | 83 |
[paths] |
69 | 84 |
# path to temporary files (must be writeable by the web server) |
70 | 85 |
userspath = users |
dispatcher.fpl | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
|
5 | 5 |
use FCGI; |
6 |
use IO::File; |
|
6 | 7 |
use SL::Dispatcher; |
7 | 8 |
use SL::FCGIFixes; |
9 |
use SL::LXDebug; |
|
10 |
|
|
11 |
sub _parse_number_with_unit { |
|
12 |
my ($number) = @_; |
|
13 |
|
|
14 |
return undef unless defined $number; |
|
15 |
return $number unless $number =~ m{^ \s* (\d+) \s* ([kmg])b \s* $}xi; |
|
16 |
|
|
17 |
my %factors = (K => 1024, M => 1024 * 1024, G => 1024 * 1024 * 1024); |
|
18 |
|
|
19 |
return $1 * $factors{uc $2}; |
|
20 |
} |
|
21 |
|
|
22 |
sub _memory_usage_is_too_high { |
|
23 |
return undef unless $::lx_office_conf{system}; |
|
24 |
|
|
25 |
my %limits = ( |
|
26 |
rss => _parse_number_with_unit($::lx_office_conf{system}->{memory_limit_rss}), |
|
27 |
size => _parse_number_with_unit($::lx_office_conf{system}->{memory_limit_vsz}), |
|
28 |
); |
|
29 |
|
|
30 |
# $::lxdebug->dump(0, "limits", \%limits); |
|
31 |
|
|
32 |
return undef unless $limits{rss} || $limits{vsz}; |
|
33 |
|
|
34 |
my %usage; |
|
35 |
|
|
36 |
my $in = IO::File->new("/proc/$$/status", "r") or return undef; |
|
37 |
|
|
38 |
while (<$in>) { |
|
39 |
chomp; |
|
40 |
$usage{lc $1} = _parse_number_with_unit($2) if m{^ vm(rss|size): \s* (\d+ \s* [kmg]b) \s* $}ix; |
|
41 |
} |
|
42 |
|
|
43 |
$in->close; |
|
44 |
|
|
45 |
# $::lxdebug->dump(0, "usage", \%usage); |
|
46 |
|
|
47 |
foreach my $type (keys %limits) { |
|
48 |
next if !$limits{$type}; |
|
49 |
next if $limits{$type} >= ($usage{$type} // 0); |
|
50 |
|
|
51 |
$::lxdebug->message(LXDebug::WARN(), "Exiting due to memory size limit reached for type '${type}': limit " . $limits{$type} . " bytes, usage " . $usage{$type} . " bytes"); |
|
52 |
|
|
53 |
return 1; |
|
54 |
} |
|
55 |
|
|
56 |
return 0; |
|
57 |
} |
|
8 | 58 |
|
9 | 59 |
our $dispatcher = SL::Dispatcher->new('FastCGI'); |
10 | 60 |
$dispatcher->pre_startup_setup; |
... | ... | |
12 | 62 |
$dispatcher->pre_startup_checks; |
13 | 63 |
|
14 | 64 |
my $request = FCGI::Request(); |
15 |
$dispatcher->handle_request($request) while $request->Accept() >= 0; |
|
65 |
while ($request->Accept() >= 0) { |
|
66 |
$dispatcher->handle_request($request); |
|
67 |
exit if _memory_usage_is_too_high(); |
|
68 |
} |
|
16 | 69 |
|
17 | 70 |
1; |
Auch abrufbar als: Unified diff
FCGI: Prozess nach Request beenden, falls belegter Speicher größer als konfigurierbares Limit
Perl gibt Speicher nicht wieder ans Betriebssystem zurück. Um zu
erreichen, dass nach einigen sehr speicherintensiven Aktionen der Server
nicht zu swappen anfangen muss, kann der Administrator nun in der
Konfigurationsdatei Limits für den Speicherverbrauch definieren.
Werden diese Limits erreicht, so beendet sich der aktuelle
Prozess. Diese Prüfung wird erst nach vollständiger Abarbeitung eines
Requests durchgeführt. Der FCGI-Manager startet dann bei der nächsten
Anfrage automatisch einen neuen Prozess.