📜 ⬆️ ⬇️

Modeling PHP flight on the wings of Erlang

This article outlines the thoughts and fantasies on the topic "how to combine Erlang and PHP to make universal happiness happen", and not a description of the finished technology or product. However, we intend to implement it, most likely, in the form of an open-source project, unless, of course, the respected habra audience dissuade :) Actually, one of the main tasks of this article is to understand how interesting the idea is and potentially useful to the wider PHP community . By the way, some of the problems discussed in the article are also valid for other popular scripting languages ​​(I mean Ruby and Python here), so the proposed solution may also be relevant for them.

Prehistory

Due to certain objective and subjective circumstances, PHP is used as a language for server programming in Megaplan . Over time, we began to embarrass and annoy some of the limitations of PHP, we began to miss some of the "advanced" features, such as: multithreading, delayed launch, message queues, etc. In addition, we are limited to using our own custom solutions for each problem, since Megaplan is not only a SaaS application, but also comes in the form of a cross-platform boxed version for three OS types: server Windows, Linux and FreeBSD. Adding the next custom component (even if there was a cross-platform solution) significantly complicates the installation and support of the boxes. Even the lack of a normal standard crond in Windows is annoying.

In general, there is a need to "pump up" PHP. There is, of course, an alternative radical solution - to move to Java, but for us this is not an option - too much of the worst code has already been written in several years. Besides, I'm not sure that you can elegantly solve the problem of a large-scale comet on JVM. And PHP is too early to write off - it is still the most popular language for web development (at least in Russia), programmers are easier to find than for other languages.

On the basis of a ripe need and the fact that at a certain moment I caught sight of and very much liked Erlang, the idea of ​​solving problems matured - to build an Erlang virtual machine into our standard environment and compensate for the shortcomings of PHP with the unique capabilities of this functional language.
')
First, I’ll talk about what tasks with the help of “clean” PHP are made with difficulty and what features we lack, and then I will describe the proposed solution. So…

Problems

In this article, I assume that long-running processes in PHP are an exceptionally unreliable crutch, under which you need to substitute another crutch so that it somehow lives. It does not inspire optimism even the fact that in PHP 5.3 there appeared a normal garbage collector . PhpDaemon does not convince, which many people like, but is tied to libevent, therefore it will not work under Windows. Currently, there is no normal native and, most importantly, reliable way to "demonize" PHP programs. And even if you try to go to work with FastCGI , you still need a controller, who will restart the process regularly. In short, in my opinion, the only PHP production mode is the classic FastCGI (or apache + prefork + mod_php under unix-like systems).

Almost all the restrictions that will be discussed are associated with this circumstance.

Background launch


I think many developers who wrote in PHP a little more than “Hello World!” Faced the problem of delayed launch, for example, with the simplest task of sending email in response to some user action. In PHP, there are 2 solutions for such a task (both ugly):
Familiar? You will probably argue that there are other ways, for example, such a perversion: to form a new process using pcntl. But here I will answer that this is at least not cross-platform, and generally looks like a hack. And you want to have a beautiful and reliable solution.

Comet


All the newfangled tasty things like long-polling, websockets, etc., of course, can be done in pure PHP, but this is only at the cost of a whole long-standing php process for each connection. On any serious amount of clients of resources you will not save enough on such luxury.
I hear someone in the far ranks give a hint about mod_php (worker) mod_pp with a couple of. Guys, do not use thread-safe php in production, this is wrong. Moreover, on really serious loads, even this will not save.
And we really want to have a common event space between the client and the server. Well, imagine this fairy tale: the server initiates an event:

<?php
    Event::publish( 'common.users.onlinecountchanged', array('count' => 10) );
?>

:

Event.subscribe( 'common.users.onlinecountchanged', function(data) {
    $('#onlinecount').html(data.count);
} );

, web-jabber-, .

cron


Cron- PHP-, cron' :
. , , , « cron' — - », , , PHP-.

,

(message queue)


— . , , , . , « » .

, , .

, PHP , , Erlang.

Erlang?
, , PHP- CMS YAWS (YAWS — -, Erlang') PHP Erlang', — , , , ! :)


, .

:
, .

— RabbitMQ


— , . « » , .

AMQP. , . , : . , PHP: , .

(pub-sub)


RabbitMQ pub-sub . , PHP , - . PHP ( PECL AMQP):

<?php
//   RabbitMQ
    $cnn = new AMQPConnection();
    $cnn->connect();
//  ,     
    $ex = new AMQPExchange( $cnn );
    $ex->declare( 'event-exchange', AMQP_EX_TYPE_TOPIC );
//  
    $ex->publish( 'message', 'some.object.event' );
?>

, - Erlang', some.object.event REST: http://example.com/example-action. Erlang, , ( -PHP, ):

//    
    amqp_declare_exchange( 'event-exchange', AMQP_EX_TYPE_TOPIC );
    amqp_declare_queue( 'external-app-queue' );
//         
    amqp_bind( 'external-app-queue', 'event-exchange', 'some.object.*' );
//     
    amqp_subscribe( 'external-app-queue' );
// ,       
    while ( 1 )
    {
        $msg = receive_message();
        file_get_contents( "http://example.com/example-action?msg=$msg" );
    }

, PHP- event-exchange some.object.event, , external-app-queue , some.object.event, . , , Erlang-, , callback' ( — REST- HTTP).
, :)

FastCGI


FastCGI- Erlang'? - . , php-fpm Windows, , , , , . - PHP, LAMP.

, , , .

- Comet


- Erlang' — (long-polling) — Erlang' . , comet -, .

Comet , , Erlang-- -, long-polling , http- push- . :
  1. Javascript- , .
  2. Erlang-, RabbitMQ , . , , .
  3. PHP- RabbitMQ, comet-, .
  4. , . push-.
  5. callback push- .
  6. Push- ( long-polling).


, , , , : , . :

Cron


Erlang. , . , , . Erlang' , , , (. ), . , AMQP, REST API .

, cron', , , ( , - ), , PHP (, ), , , PHP-.

, :)
, , :
, :)

? Welcome!

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


All Articles