Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHP distribuído e paralelo: multithread + strea...

PHP distribuído e paralelo: multithread + stream sockets

Todo mundo sabe que hoje em dia a distribuição de um sistema pode ser um fator chave de sucesso e escalabilidade. Nós falamos de micro-serviços, load balancers, assincronismo e por aí vai. Apesar de serem conceitos extremamente importantes, a idéia aqui é tentar algo diferente: vamos usar o php como uma linguagem multithread para paralelizar a execução e stream sockets para distribuir esse processamento. Por quê? Porque podemos, porque é divertido e porque é sempre bom saber maneiras diferentes de executar tarefas complexas.

Avatar for Diana Arnos

Diana Arnos

March 28, 2017
Tweet

More Decks by Diana Arnos

Other Decks in Programming

Transcript

  1. DISTRIBUIR ACESSOS NÃO É O MESMO QUE DISTRIBUIR PROCESSAMENTO. LOAD

    BALANCER SERVIDOR APLICAÇÃO SERVIDOR APLICAÇÃO SERVIDOR APLICAÇÃO
  2. 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
  3. PTHREADS PHP COMPILADO COM ZTS (THREAD SAFETY) V3 : FOI

    REESCRITO E É 100% COMPATÍVEL COM PHP 7 PARA USAR COM PHP5: V2 É SEGURO
  4. 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"; } }
  5. 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(); }
  6. 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.
  7. STREAM SOCKETS SOCKETS: MECANISMO DE COMUNICAÇÃO ENTRE PROCESSOS - EM

    MODELO CLIENTE/SERVIDOR => 1P + PORTA. EX.: 127.0.0.1:80 STREAM SOCKETS: $server = stream_socket_server(”tcp://192.168.33.99”, $errorNum, $errorMsg); while ($conn = stream_socket_accept($server)) { //código} $client = stream_socket_client("tcp://$this->workerHost", $errorNum, $errorMsg, 10); fclose($client); - fgets(), fclose(), fread(), ETC…
  8. 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();
  9. 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); } } }
  10. 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); } }