View Full Version : C/C++ FastCGI
Hello,
Is it possible to run such?
I tried to put "echo" example from http://www.fastcgi.com/dist/fcgi.tar.gz to lsws/DEFAULT/cgi-bin but I have get:
lscgid: execve(): Exec format error
So, is it possible and how can I make it?
mistwang
06-01-2005, 09:27 AM
File "echo" under examples/ directory is a shell script wrapper, you should looking for real executable binary under examples/.libs/ .
ok I got .libs and "echo". Where should I put it now so it could be lunched as FastCGI.
I appreciate your help!
I've put it in cgi-bin but recieved:
lscgid: execve(): No such file or directory
mistwang
06-01-2005, 10:18 AM
Not sure why you get that message, if you overwrote the wrapper script with real binary, it should work.
Have you tried executing echo from command line?
If you run the wrapper under examples/ directory, a file called lt-echo will be created under .libs/ dir, maybe you should try that one.
George
I took echo from fcgi-2.4.0/examples/.libs and put it in lsws/DEFAULT/cgi-bin.
I've also restarted lsws. Whats wrong? Could you test it at your env? I would appreciate it. I spend whole my working day trying to lunch fastcgi c by lsws...
mistwang
06-01-2005, 11:09 AM
Are you trying to run echo as cgi or fast cgi? it can be started in both mode.
You need to make sure echo works in command line first.
For configure a FastCGI application, please follow:
http://www.litespeedtech.com/docs/HowTo_QA.html#qa_extapp
Ok, I'm lost, can't make it.
Could you help me and tell how to define External App / Script Handler in Server Configuration panel for fastcgi/examples/.lib/echo script from FastCGI package (www.fastcgi.com)?
Where to put it and how to configure/run it?
I'm crushed...
I can run echo as cgi with: localhost/cgi-bin/echo.
I've found out also that remaining scripts doesn't seem to work: size, log-dump.
It reports "500 Internal Server Error".
No matter!
Just want to know - how to run echo as fcgi???
I've even tried to set cgi-fcgi handler for .fcgi files and rename echo to echo.fcgi and lunch it from lsws/DEFAULT/html but got: " 503 Service Unavailable"
mistwang
06-02-2005, 10:14 AM
Well, maybe you need to read the document throughly.
Use the phpFCGI external application as an example.
You can make it. :-)
Do I need to set Handler?
Does it mean that I have to define EACH fcgi script as Externall App???
Just don't get it. :( :( :(
From localhost/cgi-bin/echo runs as CGI - it spowns new pid every new request.
The goal is to run it as FastCGI - within one pid.
Can't make it. Pleas help guys...
mistwang
06-02-2005, 12:08 PM
Yes, you need to define a external app for each fast cgi application. It is a bad idea to write too many fcgi, which only do one simple task like a CGI, you should combine features as you could.
In the case of /fcgi-bin/echo, you should not define a script handler, instead, you need to define a FCGI context with URL "fcgi-bin/echo" or what ever URL you want to access the fcgi app.
In the case of /fcgi-bin/echo, you should not define a script handler, instead, you need to define a FCGI context with URL "fcgi-bin/echo" or what ever URL you want to access the fcgi app.
Big thanks for your answer. How can I make that contex?
mistwang
06-02-2005, 01:47 PM
click the name of the virtual host, then "context" tab, then "add"
Thank you for your answer. I have just found your great documentation about context.
I realised my silly questions was annoying for you. Sory for that. I appreciate your patience.
You are GREAT guys @ lsws!!
Can't make it work. Check this out guys please - what's wrong?
Script
http://img166.echo.cx/img166/5762/snapshot36cd.png
External Apps
http://img234.echo.cx/img234/9550/snapshot42vp.png
Contex
http://img166.echo.cx/img166/7504/snapshot51xl.png
EAecho running
http://img166.echo.cx/img166/8756/snapshot67fm.png
Lunch it - ERROR
http://img166.echo.cx/img166/4319/snapshot85ji.png
Log
http://img166.echo.cx/img166/4553/snapshot70nw.png
Ok, I've solved it!!
The reason was: lack of header informations in my script ("content...").
Everything works fine now.
Cheers!
BTW is it possible to have such results:
simple-test-script.php
lsws (with fastCGI php): ~700req/s
apache2 (pure php): ~700req/s
simple-test-script.c
lsws, apache2 (both as fastCGI): ~1600req/s
mistwang
06-13-2005, 09:31 PM
It doesn't looks right, I don't think the performance of lsws and Apache is in the same class, especially for the fcgi test.
Would you mind prividing more detail information about how the test is performed? What is the simple-test_script does? hardware, software used.
Sure.
simple-test-script.php
<html><head><title>CGI C Example #3</title></head>
<body><h1>CGI C Example #3</h1>
<table border=2>
<?
$db = mysql_pconnect("localhost","root","") or die('konnekt');
mysql_select_db("ht3") or die('db');
$r = mysql_query("SELECT * FROM pages");
if ($r)
{
$nrows = mysql_num_rows($r);
$num_fields = mysql_num_fields($r);
printf("rows: %i, cols: %i
\n",$nrows,$num_fields);
printf("<table border=2>\n");
while ( $row = mysql_fetch_array($r) )
{
printf("<tr>");
for($j = 0; $j < $num_fields; $j++)
{
printf("<td>%s</td>", $row[$j] ? $row[$j] : NULL");
}
printf("</tr>");
printf("\n");
}
printf("</table></body></html>\n");
mysql_free_result($r);
}
mysql_close($db);
?>
</table></body></html>
simple-test-script.c
#include <stdio.h>
#include <mysql.h>
#include "fcgi_config.h"
#include <stdlib.h>
#include "fcgi_stdio.h"
int main ()
{
int err = 0;
MYSQL dbase;
if (mysql_init(&dbase) == NULL) err = 1;
else
{
if(mysql_real_connect(&dbase,"localhost","root","","ht3",0,NULL,0) == NULL) err = 1;
}
if(err)
{
printf("
Error connecting to database</body></html>\n");
exit(0);
}
//
// B E G I N R E Q U E S T
//
while (FCGI_Accept() >= 0)
{
char sqlbuff[255];
MYSQL_RES *result;
printf("Content-type: text/html\r\n\r\n");
printf("<html><head><title>CGI C Example #3</title></head>\n");
printf("<body><h1>CGI C Example #3: %i</h1>\n",getpid());
sprintf(sqlbuff,"SELECT * FROM pages");
if(mysql_real_query(&dbase,sqlbuff,strlen(sqlbuff)))
{
printf("
SQL error</body></html>\n");
exit(1);
}
result = mysql_store_result(&dbase);
if(result)
{
int i, j, num_fields, nrows;
MYSQL_ROW row;;
nrows = mysql_num_rows(result);
num_fields = mysql_num_fields(result);
printf("rows: %i, cols: %i
\n",nrows,num_fields);
printf("<table border=2>\n");
while ( row = mysql_fetch_row(result) )
{
printf("<tr>");
for(j = 0; j < num_fields; j++)
{
printf("<td>%s</td>", row[j] ? row[j] : "NULL");
}
printf("</tr>");
printf("\n");
}
printf("</table></body></html>\n");
mysql_free_result(result);
free(result);
}
else
{
printf("No entries</body></html>\n");
}
} /* while */
mysql_close(&dbase);
return 0;
}
"SELECT * FROM pages" returns 4 rows / 5 short columns each.
I got ubuntu:
root@fryk:/var/www # uname -a
Linux fryk 2.6.10-5-386 #1 Tue Apr 5 12:12:40 UTC 2005 i686 GNU/Linux
on p4 2.xghz 512ram
Apache2 run just from apt-get install + mod_php + mod_fastcgi (-processes 10 - same as lsws).
Lsws standard with c fastcgi as described in previous posts (php fastcgi is built in - as I get it).
I typically measured it with
ab -n 20000 -c 50 PATH
mistwang
06-14-2005, 10:18 AM
I think your test case is DB bounded.
Even though, lsws should be slightly faster than Apache, you may want to try tuning the concurrent level of lsws fcgi. In your test, Apache made 50 concurrent queries to MySQL, but lsws fcgi only made 10, according to your configuration posted in previous post. Change the "instances" to match "max connections", try different value between 10-50.
The C fastCGI could be optimized a little bit:
To use prepared SQL statement if you are using MySQL 4.1.X
To combime multiple printf to one, or buffer the result in a buffer with snprintf.
To cache the result if it does not change very often.
All in all, the faster you make the FCGI run, the bigger difference you will see between lsws and Apache.
1) Add db_close to line right before exit(1). Just making sure the db connects are freed or are in clean state for the load test.
2) This test result you would get for this is only realistic in a clean-room environment. Even if you have mysql query cache disabled, subsequent reqsults will be purely from myisam/innodb buffer and or linux buffer ram so after the first few requests, you are dealing with mysql through pure memory non disk i/o calls.
I would suggest that the scripts are run with a companion program which modifies a record in the page table once every second. This forces mysql cache flush and gives you a more accurate data on how your performance is when injected with index/cache busting write queries.
In addition, instead of pure select * from pages. You should use a more common compounded query such as select * from pages where pageid = value order by priority asc, etc.
3) Don't how it applies to C but in javascript, it is magnitudes faster to buffer output like so..
var buffer = new Array();
buffer[buffer.length] = "<html>";
buffer[buffer.length] = "</html>";
document.write(buffer.join(''));
A) one big write = faster
B) Intead of appending growing data to a string, use an dynamic array and
join the data at the end = faster
the buffer.join appends all the elements into one string separated by the separator, empty char in this case.
Not sure how to do this in C but the same concept shoudl apply to most languages.