Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision a4bd0c54

Von Moritz Bunkus vor etwa 9 Jahren hinzugefügt

  • ID a4bd0c541580678d108c383ab268f233ce44b25b
  • Vorgänger 07672867
  • Nachfolger 34e9758c

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.

Unterschiede anzeigen:

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