Smear PHP
The day will come, and you will understand that one thread in PHP is not enough for you.
First, you optimize the code, then you try to change your mind to an asynchronous reaction, but the whole PHP world does not want to understand this desire. You look at phthreads, but after java concurrency you feel that you have been "tricked" somewhere. And when you decide to leave the process and start choking on the forks of execs and signals, you will understand that you can’t dive further. And finally, popping up from all this, you will sail to the island of MOM (message-oriented middleware).
Ohhh, but what kind of Kirby sellers are there just now: RabbitMQ, ActiveMQ, Kafka, Kestrel, and even Redis pub / sub? And all is well: all the best, fast, trouble-free. But there is a small disaster - a step to the side and, hello, now you are among the crowd of whiners on stackoverflow in search of work-rounds and strange schemes. And this will continue until you find ZeroMQ.
What is this? ZeroMQ is a high-performance asynchronous messaging-oriented library aimed at use in scalable distributed or parallel applications. But unlike other messaging-oriented middleware, it is broke-free and works without a server, as such.
And then what do they offer then? And these guys offer a set of sockets on steroids optimized for the main message patterns and we can use them as we want. With their help, we can build a network with any topology and complexity.
They also have their own sectarian dock http://zguide.zeromq.org/page:all . It sets brains well in the right direction, regardless of whether you use 0mq or not, though if you can use multi-threaded programming, you can partially scroll through.
In the dry residue:
- Steroid Socket Set
- Damn fast
- Work through IPC, TCP, multicast, inproc
- Asynchronous
- Easy start
- Bindings for over 40 programming languages
It all sounds very cool! Enough of theories, go to www.gliffy.com and violently architect the system. And we want the following:
- Auth + task generator
Responsible for authorization on the server and distributes non-stop tasks for parsing. - Parse worker
Gets the authorization key and the task for parsing after completion returns the result to the generator. - Parsed data publisher
Having received the result from the worker, he will publish it to all subscriber. - Alert system subscriber
Receive data and send alerts, if necessary. - Upload system subscriber
Receive data and upload it to the server. - Data upload worker
Encode, zip and applaud data to the server. - System monitor
Collects system statistics in real time.
The architecture turned out to be simple, all components were written separately from the business logic, designed in a package for the composer and saved to the github:
https://github.com/limitium/zmq
To dig, you need (for example, Debian):
1. Install ZeroMQ
sudo apt-get update -qq
sudo apt-get install -y libzmq3-dev
2. Install php-zmq binding
git clone https://github.com/mkoppanen/php-zmq.git
sh -c "cd php-zmq && phpize && ./configure && make --silent && sudo make install"
echo "extension=zmq.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
3. Install lib through composer
composer require limitium/zmq
Then we take, for example, the psr-3 logger and see how it works:
Logger
$logger = new ZLogger('my_service_1', 'tcp://127.0.0.1:5555');
$logger->info("core is stable");
$logger->emergency("we're all going to die!");
Log collector
(new Concentrator('tcp://127.0.0.1:5555'))
->setReceiver(function ($logMsg) {
$serviceName = $logMsg[0];
$time = $logMsg[1];
$logLevel = $logMsg[2];
$logMsg = $logMsg[3];
})
->listen();
Everything is simple, and thanks to ZeroMQ buns, the logger can work both within the framework of one process and collect information from 100,500 servers.
Example of task generator and worker
Generator
(new Ventilator('tcp://127.0.0.1:5555'))
->setGenerator(function () {
sleep(1);
return rand();
})
->setResponder(function ($msg) {
echo $msg;
})
->listen();
Worker
(new Worker('tcp://127.0.0.1:5555'))
->setExecutor(function ($msg) {
return $msg + $msg;
})
->work();
And in the end, the banal pub / sub
Publisher
$pub = new Publisher('tcp://127.0.0.1:5555');
$pub->send('azaza');
Subscriber
(new Subscriber('tcp://127.0.0.1:5555'))
->setListener(function ($msg){
echo $msg;
})
->listen();
The only minus of ZeroMQ, which is worth noting, is that the more I want from the system, the more I will have to write code. But who cares when everything starts in 2 lines of code?