This document discusses using PHP to distribute processing across multiple machines in parallel. It introduces pthreads, which allows creating multi-threaded PHP applications that are thread-safe. Stream sockets are also presented as a way for processes to communicate, such as a scraper process communicating with a client process. An example is given of how to split an XML document into pieces, send each piece to a scraper process using stream sockets, run the scraping in parallel threads, and collect the results.
3. EU USO LOAD BALANCER, MEU SISTEMA É DISTRIBUÍDO.
NÃO!
4. DISTRIBUIR ACESSOS NÃO É O MESMO QUE DISTRIBUIR PROCESSAMENTO.
LOAD BALANCER
SERVIDOR
APLICAÇÃO
SERVIDOR
APLICAÇÃO
SERVIDOR
APLICAÇÃO
5. O PROCESSAMENTO DA TAREFA É DISTRIBUÍDO EM PARALELO ENTRE MÁQUINAS DIFERENTES
APLICAÇÃO
SERVIDOR SERVIDOR SERVIDOR
SOLICITA TAREFA X
X PARTE 1 X PARTE 2 X PARTE 3
8. PTHREADS
PHP COMPILADO COM ZTS (THREAD SAFETY)
V3 : FOI REESCRITO E É 100% COMPATÍVEL COM PHP 7
PARA USAR COM PHP5: V2
É SEGURO
9. PTHREADS
class SimpleThreadExample extends Thread
{
/** @var int */
private $workerId = 0;
public function __construct($id)
{
$this->workerId = $id;
}
public function run()
{
echo "Thread " . $this->workerId . " começou a executar.n";
sleep(rand(0, 3));
echo "Thread " . $this->workerId . " parou de executar.n";
}
}
10. PTHREADS
$workerPool = [];
foreach (range(0, 10) as $id)
{
$workerPool[$id] = new SimpleThreadExample($id);
$workerPool[$id]->start();
}
foreach (range(0, 10) as $id)
{
$workerPool[$id]->join();
}
11. PTHREADS
Thread 0 começou a executar.
Thread 1 começou a executar.
Thread 2 começou a executar.
Thread 0 parou de executar.
Thread 3 começou a executar.
Thread 1 parou de executar.
Thread 4 começou a executar.
Thread 2 parou de executar.
Thread 3 parou de executar.
Thread 4 parou de executar.
13. DISTRIBUINDO O PROCESSAMENTO
NO EXEMPLO DO XML:
- UM SCRIPT DE SCRAPPING QUE RECEBE O PEDAÇO DE XML
class Scrapper
{
//código
public function run()
{
$server = stream_socket_server("tcp://$this->socket", $errorNum, $errorMsg);
while ($conn = stream_socket_accept($server)) {
// código de scrapping
}
fclose($server);
}
}
$scrapper= new Scrapper($argv);
$scrapper >run();
14. DISTRIBUINDO O PROCESSAMENTO
- O CLIENT QUE FAZ A REQUISIÇÃO
class Client
{
//código
private function sendFilePiecesToWorkers($xml)
{
//código
foreach ($this->scrappersAdderss as $scrapper) {
$this->senderPool[$scrapper] = new Sender($scrapper, $xml);
$this->senderPool[$ scrapper]->start();
}
foreach ($this->senderPool as $sender) {
$sender->join();
echo "Encerrando thread...n";
array_push($results, $sender->result);
}
}
}
15. DISTRIBUINDO O PROCESSAMENTO
- O SENDER, RESPONSÁVEL POR ENVIAR OS PEDAÇOS AOS SCRAPPERS
class Sender extends Thread
{
//código
public function run()
{
$client = stream_socket_client("tcp://$this->scrapperHost", $errorNum, $errorMsg, 10);
//código
foreach ($this->scrappersAdderss as $scrapper) {
//código
$this->result = stream_get_contents($client);
}
fclose($client);
}
}