Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision a4bd0c54

Von Moritz Bunkus vor mehr als 8 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:

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