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.

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); } }