Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Performance comparison Apache/FastCGI/Plack vs Apache/FCGI vs Plack standalone vs Apache/mod_perl (was "New version of Mod_perl")

by adamarc (Initiate)
on Jan 29, 2015 at 16:02 UTC ( [id://1114930]=perlquestion: print w/replies, xml ) Need Help??

adamarc has asked for the wisdom of the Perl Monks concerning the following question:

thank you stonecolddevin & sundialsvc4.
You inspired me to look at other options, and I decided to load test all of them with a simple script that connects to a MySQL database to select some UTF8 data, and return it.
I did the test twice. I included a big Perl module (~650KB) in the second test to check if the compilation phase makes sense.
All of the configurations properly returned the UTF8 text.
I did the test on an 8-core Intel 3770 with 16GB of RAM (which was not a bottleneck). OS: FreeBSD 10.0.

I'm curious to hear about what your opinion is of the below results. I find the number of Apache 2.4/FCGI too good to be true, but could not find any errors. Maybe somebody can replicate the test?

100 concurrent requests with ~10KB script: Requests Correct Requests Error AVG_msec Apache 2.4/FCGI 202510 0 14 Apache 2.4/FastCGI/Plack 25584 0 116 Plack standalone 17012 0 175 Apache 2.2/mod_perl 1828 1128 185 100 concurrent requests with ~650KB script: Requests Correct Requests Error AVG_msec Apache 2.4/FCGI 55697 0 52 Apache 2.4/FastCGI/Plack 13971 0 213 Plack standalone 13042 0 228 Apache 2.5/mod_perl 1689 0 217

See here the used scripts, and configuration.

Apache/FCGI script
#!/usr/bin/perl # added to httpd.conf: # LoadModule fcgid_module libexec/apache24/mod_fcgid.so # <IfModule mod_fcgid.c> # AddHandler fcgid-script .fcgi # </IfModule> # # Load testing is done with the following command: # http_load -parallel 100 -seconds 30 ./URLs.txt use FCGI; use DBI; use Encode; $| = 1; binmode STDOUT, ":utf8"; my $request = FCGI::Request(); while($request->Accept() >= 0) { my ($dbh,$select,$body,@row); binmode STDOUT, ":utf8"; $body = "Content-type:text/html; charset=utf-8\r\n\r\n"; $body .= '<html><head><meta http-equiv="Content-Type" content="te +xt/html; charset=utf-8" /></head><body>'; $dbh = DBI->connect('DBI:mysql:database=testdatabase:host=<hostn +ame>:<port>:','root','<password>',{mysql_enable_utf8 => 1}) or die ' +Could not connect'; # connect to the database $select = $dbh->prepare('SELECT testvalue FROM utf8test'); $select->execute; while(@row = $select->fetchrow_array) { $body .= "$row[0]<br>\n"; } $body .= '</body></html>'; $body = encode_utf8($body); print $body; }

Apache/FastCGI/Plack script
#!/usr/bin/env plackup -s FCGI # lines added to httpd.conf: # LoadModule fastcgi_module libexec/apache24/mod_fastcgi.so # FastCgiExternalServer /directory/fcgiplack.fcgi -socket /tmp/fcgi.so +ck # Alias /myapp/ /directory/fcgiplack.fcgi # # plack command: # plackup -s FCGI --listen /tmp/fcgi.sock /directory/fcgiplack.fcgi # # URL used: http://<hostname>/myapp/ use FCGI; use DBI; use Encode; $| = 1; binmode STDOUT, ":utf8"; my $app = sub { my ($env,$dbh,$select,$body,@row); $env = shift; $body = '<html><head><meta http-equiv="Content-Type" content="tex +t/html; charset=utf-8" /></head><body>'; $dbh = DBI->connect('DBI:mysql:database=testdatabase:host=<hostn +ame>:<port>:','root','<password>',{mysql_enable_utf8 => 1}) or die ' +Could not connect'; # connect to the database $select = $dbh->prepare('SELECT testvalue FROM utf8test'); $select->execute; while(@row = $select->fetchrow_array) { $body .= "$row[0]<br>\n"; } $body .= '</body></html>'; $body = encode_utf8($body); return [200,['Content-Type' => 'text/html', charset => 'utf-8'],[$b +ody]]; };

Plack standalone: the same script as Apache/FastCGI/Plack
The command that I used to run it: perl ./fcgiplack.fcgi &> fcgiplack.log &

Apache/mod_perl:
#!/usr/bin/perl use DBI; use Encode; $| = 1; binmode STDOUT, ":utf8"; main(); sub main { my ($dbh,$select,$body,@row); binmode STDOUT, ":utf8"; $body = "Content-type:text/html; charset=utf-8\r\n\r\n"; $body .= '<html><head><meta http-equiv="Content-Type" content="tex +t/html; charset=utf-8" /></head><body>'; $dbh = DBI->connect('DBI:mysql:database=testdatabase:host=<hostn +ame>:<port>:','root','<password>',{mysql_enable_utf8 => 1}) or die ' +Could not connect'; # connect to the database $select = $dbh->prepare('SELECT testvalue FROM utf8test'); $select->execute; while(@row = $select->fetchrow_array) { $body .= "$row[0]<br>\n"; } $body .= '</body></html>'; #$body = encode_utf8($body); print $body; return 1; }

SQL script to create the used database:
/* MySQL 5.6 */ CREATE DATABASE IF NOT EXISTS `testdatabase` /*!40100 DEFAULT CHARACTE +R SET utf8 */; CREATE TABLE IF NOT EXISTS `utf8test` ( `testvalue` char(20) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40000 ALTER TABLE `utf8test` DISABLE KEYS */; INSERT INTO `utf8test` (`testvalue`) VALUES ('????'), ('???????'), ('?????????'), ('Ceština'), ('Türkçe');

Initial post with title: New version of Mod_perl Dear respected Perl monks,

I have a mod-perl site that I want to continue using, but my distro doesn't distribute the mod-perl package anymore because there is none available that works with Apache 2.4. It turns out that the loyal mod_perl development team cannot release a compatible version due to a lack of testers.

Can somebody help by assisting them in submitting a bug report?

Replies are listed 'Best First'.
Re: New version of Mod_perl
by stonecolddevin (Parson) on Jan 29, 2015 at 20:48 UTC

    How tightly coupled to mod_perl are you? In my experience, there are far, far better options out there, and the Perl community in general kind of winces when people bring up supporting mod_perl.

    Three thousand years of beautiful tradition, from Moses to Sandy Koufax, you're god damn right I'm living in the fucking past

      My site is a high traffic site that uses mod_perl only for the following reasons:
      - performance since all code is precompiled
      - persistent database connections (DBI is overloaded by Apache::DBI to do this)
      - good UTF8 support
      - code does not need to be rewritten. It overloads the CGI object

      I've considered the following modules:
      FCGI: does not support multi-byte chars properly (it is not Unicode aware and only characters within the range 0x00-0xFF are supported)
      FastCGI: no persistent database connections. UTF8 support?
      Plack: requires refactoring of the code. I couldn't find persistent database connection support in the man pages.

      Did I miss a solution? Thank you for your reply. I'm curious to find out about your thoughts.
Re: Performance comparison Apache/FastCGI/Plack vs Apache/FCGI vs Plack standalone vs Apache/mod_perl (was "New version of Mod_perl")
by vincent_veyron (Sexton) on Feb 02, 2015 at 23:25 UTC

    Yuk : Apache 2.2/mod_perl 1828 1128 185

    Not sure what those 1128 errors are, but your script does not make use of connection caching, so you are creating a new connection every time. You should use Apache::DBI or connect_cached to make use of persistent connections; the handler I pasted below generates 260 pages per second on my 3 year old laptop (3.8ms/request).

    You can also use a proxy (e.g. nginx) in front of mod_perl to serve pages to slow client; see : http://perl.apache.org/docs/1.0/guide/strategy.html (old doc but the principle is still valid).

    That still leaves the problem regarding apache 2.4. Is it not possible to install/build 2.2 on your distribution, while you wait for mod_perl to be ready?

    package Carnet::bench ; use lib qw(/home/lib); use strict ; use warnings ; use Apache2::Const -compile => qw( OK REDIRECT ) ; sub handler { my $r = shift ; my $dbh = DBI->connect_cached( "DBI:Pg:dbname=xyz", 'john', undef, + { PrintError => 1, RaiseError => 1, AutoCommit => 1, pg_bool_tf => 1 } ) or die "Cannot connect to db" ; my $sql = 'select name from names' ; my $data_set = $dbh->selectall_arrayref($sql) ; my $list ; for ( @{$data_set} ) { $list .= '<li>' . $_->[0] . '</li>' ; } my $content = '<html><body><ul>' . $list . '</ul></body></html>' ; $r->content_type('text/html; charset=utf-8') ; print $content ; return Apache2::Const::OK ; } 1 ;


    libremen.com : legal case, contract and insurance claim management software
Re: New version of Mod_perl
by sundialsvc4 (Abbot) on Jan 29, 2015 at 23:30 UTC

    adamarc, I have certainly not found your assertions in post #2 to be at all correct.   (DBCS, persistence, or heavy refactoring).   Indeed, I have successfully replaced mod_perl with Plack and found the process to be both quite straightforward and more efficient and versatile on today’s typical hardware configs.   Although some sites are guilty of “voodoo mod_perl coding” in an effort to squeeze the hardware a little harder, I have found that most conversions were almost “drop-in replacement.”

    Today, the biggest problem with mod_perl, IMHO, is precisely the result of how it was designed:   to embed the Perl interpreter that is running the web site, directly into the Apache service process that received the request.   Many companies do not want the web-server that is “out there on the front line” to actually be the one that’s doing the work:   they want there to be a FastCGI server somewhere else that, through a very tight firewall, VPN, etc., is actually responsible for evaluating the inputs and generating the response.   Load balancers and so-forth can distribute the workload, even distributing different requests to different FastCGI server-banks depending, say, on a portion of the URL.   The number of FastCGI providers might not equal the number of Apache processes.

    FastCGI service-processes do remain persistent (until they periodically commit hari-kiri), and therefore can and usually do maintain persistent database connections.   They become what you think of as being “the service providers,” while the (continually light-weight) Apache service processes are “the front-end interface providers.”   The FastCGI servers are more-trusted; the Apache servers, not much at all.

    In today’s environments of blade-servers arranged in “defense in depth,” I suggest that FastCGI / Plack is a better approach now, and I also suggest that the amount of work that you will actually incur to convert most applications is quite manageable.

      sundialsvc4, would you consider writing up your experience with replacing mod_perl with Plack sometime? I find very little in the web about the details of what needs to happen, only that it should be easy. The FAQ that stonecolddevin posted is light on the nitty-gritty, so when I come to do this exact task in a year or so, it'd be nice to have something to fall back on.

      cheers,

      Sometimes I can think of 6 impossible LDAP attributes before breakfast.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1114930]
Approved by Corion
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-03-19 10:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found