Can I compile my PHP script into a faster executable format?

I have a PHP script that acts like a JSON API for my database.

Meaning, you send him an HTTP request, for example: http://example.com/json/?a=1&b=2&c=3 ... it will return a json object with a result set from my database.

PHP is great for this, because literally about 10 lines of code.

But I also know that PHP is slow, and it is an API that calls about 40 times per second from time to time, and PHP struggles to keep up.

Is there a way so that I can compile my PHP script into a faster executable format? I already use PHP-APC, which is a bytecode optimization for PHP, as well as FastCGI.

Or does anyone recommend a language that I am rewriting a script so that Apache can still handle example.com/json/ requests?

thanks

UPDATE . I just performed some tests:

  • PHP script takes 0.6 seconds to complete
  • If I use the generated SQL from the PHP script above and run the query from the same web server, but directly from the MySQL team, which means that latency is still in the game - the selected result set takes only 0.09 seconds to complete .

As you can see, PHP literally generates 1 order slower results. In this case, the network is not the main bottleneck, although I agree that it is the main reason.

+3
source share
9

- , , . 10 ( ), , . , script. , script.

: , .

(APC). . , , , .

. ( 20 ), : . , 9 10 .

, , - : memcached, beanstalkd ..

, , 20 , -, .

+8

PHP, memcached nginx memcache . - URL-

URL:

/widgets.json?a=1&b=2&c=3

PHP:

<?
$widgets_cache_key = $_SERVER['REQUEST_URI'];

// connect to memcache (requires memcache pecl module)
$m = new Memcache;
$m->connect('127.0.0.1', 11211);

// try to get data from cache
$data = $m->get($widgets_cache_key);
if(empty($data)){
    // data is not in cache. grab it.
    $r = mysql_query("SELECT * FROM widgets WHERE ...;");
    while($row = mysql_fetch_assoc($r)){
        $data[] = $row;
    }
    // now store data for next time.
    $m->set($widgets_cache_key, $data);
}

var_dump(json_encode($data));
?>

. nginx front-end Apache ( Apache 8080 nginx 80), nginx:

worker_processes  2;

events {
    worker_connections  1024;
}

http {
    include  mime.types;
    default_type  application/octet-stream;

    access_log  off;
    sendfile  on;
    keepalive_timeout  5;
    tcp_nodelay  on;
    gzip  on;

    upstream apache {
        server  127.0.0.1:8080;
    }

    server {
        listen  80;
        server_name  _;

        location / {
            if ($request_method = POST) {
                proxy_pass  http://apache;
                break;
            }
            set  $memcached_key $uri;
            memcached_pass  127.0.0.1:11211;
            default_type  text/html;
            proxy_intercept_errors  on;
            error_page  404 502 = /fallback;
        }

        location /fallback {
            internal;
            proxy_pass  http://apache;
            break;
        }
    }
}

set $memcached_key $uri;. memcached, REQUEST_URI , PHP . , nginx , , PHP Apache. .

memcache Apache. , nginx, .

+3

- , . - , , . . .

PHP . . PHP C. , - , , , .

+1

( , ), , memcached .

URL :

/widgets.json?a=1&b=2&c=3

- GET . , widgets. :

<?
// a function to provide a consistent cache key for your resource
function cache_key($type, $params = array()){
 if(empty($type)){
  return false;
 }
 // order your parameters alphabetically by key.
 ksort($params);
 return sha1($type . serialize($params));
}

// you get the same cache key no matter the order of parameters
var_dump(cache_key('widgets', array('a' => 3, 'b' => 7, 'c' => 5)));
var_dump(cache_key('widgets', array('b' => 7, 'a' => 3, 'c' => 5)));


// now let use some GET parameters.
// you'd probably want to sanitize your $_GET array, however you want.
$_GET = sanitize($_GET);

// assuming URL of /widgets.json?a=1&b=2&c=3 results in the following func call:
$widgets_cache_key = cache_key('widgets', $_GET);

// connect to memcache (requires memcache pecl module)
$m = new Memcache;
$m->connect('127.0.0.1', 11211);

// try to get data from cache
$data = $m->get($widgets_cache_key);
if(empty($data)){
 // data is not in cache. grab it.
 $r = mysql_query("SELECT * FROM widgets WHERE ...;");
 while($row = mysql_fetch_assoc($r)){
  $data[] = $row;
 }
 // now store data for next time.
 $m->set($widgets_cache_key, $data);
}

var_dump(json_encode($data));
?>
+1

APC-, . , - , :

1) - Squid -. , .

2) memcached .

0

, , MySQL - , . :

  • mytop dbserver
  • ab (apache bench) , ,
  • top vmstat -

:

  • , ( MyISAM)
  • - ( -)
  • -, , -, .
  • apache. /, . mysql_fetch_assoc() .

db , , , :

function query( $sql, $dbcon, $thresh ) {
    $delta['begin'] = microtime( true );
    $result = $dbcon->query( $sql );
    $delta['finish'] = microtime( true );
    $delta['t'] = $delta['finish'] - $delta['begin'];
    if( $delta['t'] > $thresh )
        error_log( "query took {$delta['t']} seconds; query: $sql" );
    return $result;
}

xcache APC, , .

. , . grep http- netstat cronjob log, .

mysql.

0

. . . , PHP ELF (, , FatELF). , Zend.

0

, PHP- . ?

, MySQL , , db?

0,60 php 0,0 MySQL CLI, , . PHP .

Think about it, depending on your env and your code, you will:

  • Allow MySQL server host name to IP address
  • Open server connection
  • Server Authentication
  • Finally run the query

Do you consider using persistent MySQL connections or pooling ? This effectively allows you to go straight to the query step above.

Caching is also great for performance. I think others already understood this well.

0
source

Source: https://habr.com/ru/post/1721463/


All Articles