PHP-AGI high load errors

Hi everyone,

we are developing a platform based on Asterisk for Telecom services.
The architecture includes 2 opensips, 3 asterisk and PJSIP.
The dialplans are written in simple asterisk conf files and for more complex functionality, we have employed PHP-AGI scripts.
However, at high traffic, we observed high CUP load, delays of message processing, task processor queues getting filled and finally the end of service. Issue is fixed via a service restart.
After stress test we concluded to the following:
In case of a simple dialplan consisting of a simple Playback(Hello-World) on asterisk conf files (dialplan), we can support huge incoming rates (>300 calls per second).
If we add an extra line of calling a PHP-AGI script, that does a simple variable assignment, the max incoming rate that we can support is about 30calls per second.
It is obvious that the call of the PHP-AGI script is a significant factor that causes the observed errors.
Our question is how we can solve this problem? What is the most optimal way to replace the existing PHP-AGI scripts? We think of fast-AGI and PHP script, but we really need an expert advice on this topic.
(Asterisk Gateway Interface (AGI) - Asterisk Project - Asterisk Project Wiki)

Thank you in advance for your time.

FastAGI, but make sure that the process is not run from inetd each time, but rather issues a listen() and doesn’t exec anything.

Normal AGI involves launching a copy of the interpreter for your scripting language, each time so is obviously going to be much slower than built in dialplan operations.

A FastAGI server implemented correctly (ie, ‘multithreaded’ see above) is the ultimate AGI performance boost. But, it is more difficult to implement and introduces operational issues as well – you must restart the FastAGI server to upgrade vs just copying an executable / script to the correct directory.

I usually write AGIs in C, which doesn’t eliminate the ‘create a process’ overhead, but eliminates the script parsing and include/require processing inherent in scripting languages.

Here’s a comparison between a PHP script and a C executable. This was executed on a RaspberryPi 3b+.

Language Seconds
PHP 458
C 51

The dialplan consisted of:

;       same = n,                       set(agi=null-agi.php)
        same = n,                       set(agi=null-agi)
        same = n,                       verbose(1,start = ${EPOCH})
        same = n,                       agi(${agi})
(repeating the line above 998 times)
        same = n,                       agi(${agi})
        same = n,                       verbose(1,end   = ${EPOCH})
        same = n,                       hangup()

The call ‘load’ was created by copying 4 (because the Pi has 4 cores?) instances of a call file containing:

# leg 1
channel:		local/*@newline

# leg 2
application:	wait
data:			600

The PHP source looks like:

#!/usr/bin/php -q
<?php

        require('phpagi-2.20/phpagi.php');
        $agi = new AGI();

// set a variable
        $agi->set_variable('test-variable', 'testing');
        exit(0);
?>

The C source looks like:

#include	"agi.h"
int				main
	(
	  int		argc
	, char		**argv
	)
	{
// set a variable
	agi_set_variable("test-variable", "testing");
	exit(0);
	}

So, the little RPi handles 4,000 (1,000 * 4 ‘AGIs’) in 458 seconds in PHP (about 9 per second) and 51 seconds in C (almost 80 per second) – about 9 times as many AGIs per second.

I’m assuming you’re using something more powerful than an RPi :slight_smile:

I’m curious why you’re only getting 30 calls per second.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.