SlideShare una empresa de Scribd logo
1 de 50
Descargar para leer sin conexión
r                       /ib
                  we                     .m
                                           q

             n  s                      ro
                                     ze r
           a                       // be
                            42 ttp: ar
       h e                 4 h
                         /3 - nb
     t             r .in
                  e d om @ia
is             rb in .c -
             a jo ir t
           B // hp ne
          n p: /p p.
       Ia tt :/ ph
          h ttp @
           h nb
             ia
“0MQ is
unbelievably cool
– if you haven’t
got a project that
needs it, make
one up”
jon gifford - loggly
queue        esb


pipeline    async



pub/sub    gateway
request/response

$ctx = new ZMQContext();       rep.php
$server =
  new ZMQSocket($ctx, ZMQ::SOCKET_REP);
$server->bind("tcp://*:5454");

while(true) {
  $message = $server->recv();
  $server->send($message . " World");
}
request/response

$ctx = new ZMQContext();      req.php
$req =
  new ZMQSocket($ctx, ZMQ::SOCKET_REQ);
$req->connect("tcp://localhost:5454");

$req->send("Hello");
echo $req->recv();
import zmq                   rep.py
context = zmq.Context()
server = context.socket(zmq.REP)
server.connect("tcp://localhost:5455")

while True:
    message = server.recv()
    print "Sending", message, "Worldn"
    server.send(message + " World")
Image: http://flickr.com/photos/sebastian_bergmann/3318754086
wget http://repo.zero.mq/rpm/zeromq.repo
yum update
yum install zeromq


pear channel-discover pear.zero.mq
pecl install zero.mq/zmq-beta
echo "extension=zmq.so" > 
                    /etc/php.d/zmq.ini


http://download.zeromq.org/
http://github.com/zeromq/zeromq2-1
http://github.com/zeromq/libzmq
atomic   string   multipart



messaging
Post Office Image: http://www.flickr.com/photos/10804218@N00/4315282973
        Post Box Image: http://www.flickr.com/photos/kenjonbro/3027166169
queue
queue
$ctx   = new ZMQContext();
$front = $ctx->getSocket(ZMQ::SOCKET_XREP);
$back = $ctx->getSocket(ZMQ::SOCKET_XREQ);
$front->bind('tcp://*:5454');
$back->bind ('tcp://*:5455');

$poll = new ZMQPoll();
$poll->add($front, ZMQ::POLL_IN);
$poll->add($back, ZMQ::POLL_IN);
$read = $write = array();
$snd   = ZMQ::MODE_SNDMORE;
$rcv   = ZMQ::SOCKOPT_RCVMORE;
                                    queu e.php
while(true) {
 $events = $poll->poll($read, $write);
 foreach($read as $socket) {
  if($socket === $front) {
            $messages = $frontend->recvMulti();
            $backend->sendMulti($messages);
        } else if($socket === $back) {
            $messages = $backend->recvMulti();
            $frontend->sendMulti($messages);
        }
    }
}
0MQ1      0MQ2

Socket                    STDIN

            POLL




            events
$ctx = new ZMQContext();
$sock = $ctx->getSocket(ZMQ::SOCKET_PULL);
$sock->bind("tcp://*:5555");

$poll = new ZMQPoll();
$poll->add($sock, ZMQ::POLL_IN);
$poll->add(STDIN, ZMQ::POLL_IN);

while(true) {
  $events = $poll->poll($read, $write);
  if($read[0] === $sock) {
    echo "ZMQ: ", $read[0]->recv();
  } else {
    echo "STDIN: ", fgets($read[0]);
  }
}                                   poll.php
stable / unstable




  Image: http://www.flickr.com/photos/pelican/235461339/
pipeline
logging
processes




                local log
               ag gregators



  log writer
pipeline
<?php                          logger.php
$ctx = new ZMQContext();
$out = $ctx->getSocket(ZMQ::SOCKET_PUSH);
$out->connect("ipc:///tmp/logger");
$msg = array("time" => time());
$msg['msg'] = $_SERVER['argv'][1];
$out->send(json_encode($msg));
loglocal.php
$bufSz = 3; $messages = array();

$ctx = new ZMQContext();
$in = $ctx->getSocket(ZMQ::SOCKET_PULL);
$out = $ctx->getSocket(ZMQ::SOCKET_PUSH);
$in->bind("ipc:///tmp/logger");
$out->connect("tcp://loghost:5555");
while(true) {
  $messages[] = $in->recv();
  if(count($messages) == $bufferSize) {
    $out->sendMulti($messages);
    $messages = array();
  }
}
logserv.php
$ctx = new ZMQContext();
$in = $ctx->getSocket(ZMQ::SOCKET_PULL);
$in->bind("tcp://*:5555");
while(true) {
  $messages = $in->recvMulti();
  echo "Messages Received: ",
       count($messages), PHP_EOL;
  foreach($messages as $msg) {
    $a = json_decode($msg);
    echo date("Y-m-d h:i:s", $a->time),
         " ", $a->msg, PHP_EOL;
} }
pub/sub




  Image: http://www.flickr.com/photos/nikonvscanon/4519133003/
pub/sub
pub             send
                “h

         “hi”
                  i”
  i”
 “h


sub      sub           sub




                              i”
                              “h
ted      ann           ned
pub/sub

$ctx = new ZMQContext();
$pub = $ctx->getSocket(ZMQ::SOCKET_PUB);
$pub->bind('tcp://*:5566');
$pull = $ctx->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://*:5567');

while(true) {
    $message = $pull->recv();
    $pub->send($message);
}                               server.php
$name = htmlspecialchars($_POST['name']);
$msg =htmlspecialchars($_POST['message']);

$ctx = new ZMQContext();
$send = $ctx->getSocket(ZMQ::SOCKET_PUSH);
$send->connect('tcp://localhost:5567');

if($msg == 'm:joined') {
  $send->send(
     "<em>" . $name . " has joined</em>");
} else {
  $send->send($name . ': ' . $msg);
}

                            send.php
$ctx = new ZMQContext();
$sub = $ctx->getSocket(ZMQ::SOCKET_SUB);
$sub->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE,'');
$sub->connect('tcp://localhost:5566');
$poll = new ZMQPoll();
$poll->add($sub, ZMQ::POLL_IN);
$read = $wri = array();
while(true) {
  $ev = $poll->poll($read, $wri, 5000000);
  if($ev > 0) {
    echo "<script type='text/javascript'>
                     parent.updateChat('";
    echo $sub->recv() ."');</script>";
  }
  ob_flush();
  flush();
}                                ch at.php
sub          sub
 user         data



pub     pub    pub

web     web    web
$ctx = new ZMQContext();
$socket = $ctx->getSocket(ZMQ::SOCKET_PUB);
$socket->connect("ipc:///tmp/usercache");
$socket->connect("ipc:///tmp/datacache");
$type = array('users', 'data');

while(true) {
  $socket->send($type[array_rand($type)],
                         ZMQ::MODE_SNDMORE);
  $socket->send(rand(0, 12));
  sleep(rand(0,3));
}                              cach e.php
$ctx = new ZMQContext();
$socket = $ctx->getSocket(ZMQ::SOCKET_SUB);
$socket->setSockOpt(
          ZMQ::SOCKOPT_SUBSCRIBE, "users");
$socket->bind("ipc:///tmp/usercache");

while(true) {
    $cache = $socket->recv();
    $request = $socket->recv();
    echo "Clearing $cache $requestn";
}


                     userlistener.php
types of transport

     inproc         ipc




   tcp        pgm
distro   sub   web
client
                   sub   web
         sub

event
         sub       sub   web
 pub

          distro   sub   web
client
         sub       db
$ctx = new ZMQContext();
$out = $ctx->getSocket(ZMQ::SOCKET_PUB);
$out->setSockOpt(ZMQ::SOCKOPT_RATE, 10000);
$out->connect("epgm://;239.192.0.1:7601");

$in = $ctx->getSocket(ZMQ::SOCKET_PULL);
$in->bind("tcp://*:6767");

$device = new ZMQDevice(
         ZMQ::DEVICE_FORWARDER, $in, $out);



                      eventhub.php
$ctx = new ZMQContext();
$in = $ctx->getSocket(ZMQ::SOCKET_SUB);
$in->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, '');
$in->setSockOpt(ZMQ::SOCKOPT_RATE, 10000);
$in->connect("epgm://;239.192.0.1:7601");
$out = $ctx->getSocket(ZMQ::SOCKET_PUB);
$out->bind("ipc:///tmp/events");

$device = new ZMQDevice(
         ZMQ::DEVICE_FORWARDER, $in, $out);



                        distro.php
$ctx = new ZMQContext();
$in = $ctx->getSocket(ZMQ::SOCKET_SUB);
for($i = 0; $i<100; $i++) {
   $in->setSockOpt(
           ZMQ::SOCKOPT_SUBSCRIBE,
           rand(100000, 999999));
}
$in->connect("ipc:///tmp/events");
$i = 0;
while($i++ < 1000) {
  $who = $in->recv();
  $msg = $in->recv();
  printf("%s %s %s", $who, $msg, PHP_EOL);
}
                                cli ent.php
push   handler
  mongrel
                   pub

client client



mongrel 2
http://mongrel2.org/
$ctx = new ZMQContext();
$in = $ctx->getSocket(ZMQ::SOCKET_PULL);
$in->connect('tcp://localhost:9997');
$out = $ctx->getSocket(ZMQ::SOCKET_PUB);
$out->connect('tcp://localhost:9996');
$http = "HTTP/1.1 200 OKrnContent-Length:
%srnrn%s";

while(true) {
  $msg = $in->recv();
  list($uuid, $id, $path, $rest) =
                      explode(" ", $msg, 4);
  $res = $uuid." ".strlen($id).':'.$id.", ";
  $res .= sprintf($http, 6, "Hello!");
  $out->send($res);
}
                               handler.php
simple_handler = Handler(
  send_spec='tcp://*:9997',
  send_ident='ab206881-6f49-4276-9db1-1676bfae18b0',
  recv_spec='tcp://*:9996', recv_ident=''
)
main = Server(
  uuid="9e71cabf-6afb-4ee1-b550-7972245f7e0a",
  access_log="/logs/access.log",
  error_log="/logs/error.log",
  chroot="./",
  default_host="general.local",
  name="example",
  pid_file="/run/mongre2.pid",
  port=6767,
  hosts = [
    Host(name="general.local",
         routes={'/test':simple_handler})
  ]
)
settings = {"zeromq.threads": 1}
servers = [main]
namespace m2php;
$id ="82209006-86FF-4982-B5EA-D1E29E55D481";
$con = new m2phpConnection($id,
                    "tcp://127.0.0.1:9997",
                    "tcp://127.0.0.1:9996");
$ctx = new ZMQContext();
$in = $ctx->getSocket(ZMQ::SOCKET_SUB);
$in->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE,'');
$in->connect('tcp://localhost:5566');
$poll = new ZMQPoll();
$poll->add($sub, ZMQ::POLL_IN);
$poll->add($con->reqs, ZMQ::POLL_IN);
$read = $write = $ids = array(); $snd = '';
$h = "HTTP/1.1 200 OKrnContent-Type: text/
htmlrnTransfer-Encoding: chunkedrnrn";

     https://github.com/winks/m2php
while (true) {
 $ev = $poll->poll($read, $write);
 foreach($read as $r) {
  if($r !== $in) {
   $req = $con->recv(); $snd = $req->sender;
   if($req->is_disconnect()) {
     unset($ids[$req->conn_id]);
   } else {
     $ids[$req->conn_id] = $req->conn_id;
     $con->send($snd, $req->conn_id,$h);
   }
  } else {
   $m = "<script type='text/javascript'>
     parent.updateChat('".$in->recv()."');
   </script>rn";
   $con->send($snd, implode(' ', $ids),
         sprintf("%xrn%s",strlen($m),$m));
} } } }
Helpful Links
http://zero.mq
http://zguide.zero.mq
        Ian Barber
http://zero.mq/ib
        http://phpir.com
       ian.barber@gmail.com @ianbarber
http://joind.in/talk/view/3442



       thanks!

Más contenido relacionado

La actualidad más candente

Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHP
Thomas Weinert
 

La actualidad más candente (20)

C99.php
C99.phpC99.php
C99.php
 
Lua tech talk
Lua tech talkLua tech talk
Lua tech talk
 
React PHP: the NodeJS challenger
React PHP: the NodeJS challengerReact PHP: the NodeJS challenger
React PHP: the NodeJS challenger
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message Queue
 
Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHP
 
Malcon2017
Malcon2017Malcon2017
Malcon2017
 
Using ngx_lua in UPYUN
Using ngx_lua in UPYUNUsing ngx_lua in UPYUN
Using ngx_lua in UPYUN
 
Redis as a message queue
Redis as a message queueRedis as a message queue
Redis as a message queue
 
C99
C99C99
C99
 
Py conkr 20150829_docker-python
Py conkr 20150829_docker-pythonPy conkr 20150829_docker-python
Py conkr 20150829_docker-python
 
Keep it simple web development stack
Keep it simple web development stackKeep it simple web development stack
Keep it simple web development stack
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stack
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
How-to Integração Postfi
How-to Integração PostfiHow-to Integração Postfi
How-to Integração Postfi
 
HTTP For the Good or the Bad - FSEC Edition
HTTP For the Good or the Bad - FSEC EditionHTTP For the Good or the Bad - FSEC Edition
HTTP For the Good or the Bad - FSEC Edition
 
Http capturing
Http capturingHttp capturing
Http capturing
 
C99[2]
C99[2]C99[2]
C99[2]
 
SSH I/O Streaming via Redis-based Persistent Message Queue -Mani Tadayon
 SSH I/O Streaming via Redis-based Persistent Message Queue -Mani Tadayon SSH I/O Streaming via Redis-based Persistent Message Queue -Mani Tadayon
SSH I/O Streaming via Redis-based Persistent Message Queue -Mani Tadayon
 
Puppet Camp 2012
Puppet Camp 2012Puppet Camp 2012
Puppet Camp 2012
 

Similar a ZeroMQ Is The Answer: PHP Tek 11 Version

Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Masahiro Nagano
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Masahiro Nagano
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
Tatsuhiko Miyagawa
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
clkao
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
clkao
 
Yy
YyYy
Yy
yygh
 
Yy
YyYy
Yy
yygh
 
Nouveau document texte
Nouveau document texteNouveau document texte
Nouveau document texte
Sai Ef
 
Javascript Continues Integration in Jenkins with AngularJS
Javascript Continues Integration in Jenkins with AngularJSJavascript Continues Integration in Jenkins with AngularJS
Javascript Continues Integration in Jenkins with AngularJS
Ladislav Prskavec
 

Similar a ZeroMQ Is The Answer: PHP Tek 11 Version (20)

Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
 
Redis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your applicationRedis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your application
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
 
Redis for the Everyday Developer
Redis for the Everyday DeveloperRedis for the Everyday Developer
Redis for the Everyday Developer
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
ReactPHP
ReactPHPReactPHP
ReactPHP
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
Tatsumaki
TatsumakiTatsumaki
Tatsumaki
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Yy
YyYy
Yy
 
Yy
YyYy
Yy
 
Nouveau document texte
Nouveau document texteNouveau document texte
Nouveau document texte
 
Javascript Continues Integration in Jenkins with AngularJS
Javascript Continues Integration in Jenkins with AngularJSJavascript Continues Integration in Jenkins with AngularJS
Javascript Continues Integration in Jenkins with AngularJS
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 

Más de Ian Barber

Más de Ian Barber (9)

Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find Fraudsters
 
Debugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionDebugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 Version
 
Deployment Tactics
Deployment TacticsDeployment Tactics
Deployment Tactics
 
In Search Of: Integrating Site Search (PHP Barcelona)
In Search Of: Integrating Site Search (PHP Barcelona)In Search Of: Integrating Site Search (PHP Barcelona)
In Search Of: Integrating Site Search (PHP Barcelona)
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & Tools
 
In Search Of... (Dutch PHP Conference 2010)
In Search Of... (Dutch PHP Conference 2010)In Search Of... (Dutch PHP Conference 2010)
In Search Of... (Dutch PHP Conference 2010)
 
In Search Of... integrating site search
In Search Of... integrating site search In Search Of... integrating site search
In Search Of... integrating site search
 
Document Classification In PHP - Slight Return
Document Classification In PHP - Slight ReturnDocument Classification In PHP - Slight Return
Document Classification In PHP - Slight Return
 
Document Classification In PHP
Document Classification In PHPDocument Classification In PHP
Document Classification In PHP
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 

ZeroMQ Is The Answer: PHP Tek 11 Version

  • 1. r /ib we .m q n s ro ze r a // be 42 ttp: ar h e 4 h /3 - nb t r .in e d om @ia is rb in .c - a jo ir t B // hp ne n p: /p p. Ia tt :/ ph h ttp @ h nb ia
  • 2. “0MQ is unbelievably cool – if you haven’t got a project that needs it, make one up” jon gifford - loggly
  • 3.
  • 4.
  • 5.
  • 6. queue esb pipeline async pub/sub gateway
  • 7. request/response $ctx = new ZMQContext(); rep.php $server = new ZMQSocket($ctx, ZMQ::SOCKET_REP); $server->bind("tcp://*:5454"); while(true) { $message = $server->recv(); $server->send($message . " World"); }
  • 8. request/response $ctx = new ZMQContext(); req.php $req = new ZMQSocket($ctx, ZMQ::SOCKET_REQ); $req->connect("tcp://localhost:5454"); $req->send("Hello"); echo $req->recv();
  • 9.
  • 10. import zmq rep.py context = zmq.Context() server = context.socket(zmq.REP) server.connect("tcp://localhost:5455") while True: message = server.recv() print "Sending", message, "Worldn" server.send(message + " World")
  • 12. wget http://repo.zero.mq/rpm/zeromq.repo yum update yum install zeromq pear channel-discover pear.zero.mq pecl install zero.mq/zmq-beta echo "extension=zmq.so" > /etc/php.d/zmq.ini http://download.zeromq.org/ http://github.com/zeromq/zeromq2-1 http://github.com/zeromq/libzmq
  • 13. atomic string multipart messaging
  • 14. Post Office Image: http://www.flickr.com/photos/10804218@N00/4315282973 Post Box Image: http://www.flickr.com/photos/kenjonbro/3027166169
  • 15.
  • 16. queue
  • 17. queue $ctx = new ZMQContext(); $front = $ctx->getSocket(ZMQ::SOCKET_XREP); $back = $ctx->getSocket(ZMQ::SOCKET_XREQ); $front->bind('tcp://*:5454'); $back->bind ('tcp://*:5455'); $poll = new ZMQPoll(); $poll->add($front, ZMQ::POLL_IN); $poll->add($back, ZMQ::POLL_IN); $read = $write = array(); $snd = ZMQ::MODE_SNDMORE; $rcv = ZMQ::SOCKOPT_RCVMORE; queu e.php
  • 18. while(true) { $events = $poll->poll($read, $write); foreach($read as $socket) { if($socket === $front) { $messages = $frontend->recvMulti(); $backend->sendMulti($messages); } else if($socket === $back) { $messages = $backend->recvMulti(); $frontend->sendMulti($messages); } } }
  • 19. 0MQ1 0MQ2 Socket STDIN POLL events
  • 20. $ctx = new ZMQContext(); $sock = $ctx->getSocket(ZMQ::SOCKET_PULL); $sock->bind("tcp://*:5555"); $poll = new ZMQPoll(); $poll->add($sock, ZMQ::POLL_IN); $poll->add(STDIN, ZMQ::POLL_IN); while(true) { $events = $poll->poll($read, $write); if($read[0] === $sock) { echo "ZMQ: ", $read[0]->recv(); } else { echo "STDIN: ", fgets($read[0]); } } poll.php
  • 21.
  • 22. stable / unstable Image: http://www.flickr.com/photos/pelican/235461339/
  • 24. logging processes local log ag gregators log writer
  • 25. pipeline <?php logger.php $ctx = new ZMQContext(); $out = $ctx->getSocket(ZMQ::SOCKET_PUSH); $out->connect("ipc:///tmp/logger"); $msg = array("time" => time()); $msg['msg'] = $_SERVER['argv'][1]; $out->send(json_encode($msg));
  • 26. loglocal.php $bufSz = 3; $messages = array(); $ctx = new ZMQContext(); $in = $ctx->getSocket(ZMQ::SOCKET_PULL); $out = $ctx->getSocket(ZMQ::SOCKET_PUSH); $in->bind("ipc:///tmp/logger"); $out->connect("tcp://loghost:5555"); while(true) { $messages[] = $in->recv(); if(count($messages) == $bufferSize) { $out->sendMulti($messages); $messages = array(); } }
  • 27. logserv.php $ctx = new ZMQContext(); $in = $ctx->getSocket(ZMQ::SOCKET_PULL); $in->bind("tcp://*:5555"); while(true) { $messages = $in->recvMulti(); echo "Messages Received: ", count($messages), PHP_EOL; foreach($messages as $msg) { $a = json_decode($msg); echo date("Y-m-d h:i:s", $a->time), " ", $a->msg, PHP_EOL; } }
  • 28.
  • 29. pub/sub Image: http://www.flickr.com/photos/nikonvscanon/4519133003/
  • 31. pub send “h “hi” i” i” “h sub sub sub i” “h ted ann ned
  • 32. pub/sub $ctx = new ZMQContext(); $pub = $ctx->getSocket(ZMQ::SOCKET_PUB); $pub->bind('tcp://*:5566'); $pull = $ctx->getSocket(ZMQ::SOCKET_PULL); $pull->bind('tcp://*:5567'); while(true) { $message = $pull->recv(); $pub->send($message); } server.php
  • 33. $name = htmlspecialchars($_POST['name']); $msg =htmlspecialchars($_POST['message']); $ctx = new ZMQContext(); $send = $ctx->getSocket(ZMQ::SOCKET_PUSH); $send->connect('tcp://localhost:5567'); if($msg == 'm:joined') { $send->send( "<em>" . $name . " has joined</em>"); } else { $send->send($name . ': ' . $msg); } send.php
  • 34. $ctx = new ZMQContext(); $sub = $ctx->getSocket(ZMQ::SOCKET_SUB); $sub->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE,''); $sub->connect('tcp://localhost:5566'); $poll = new ZMQPoll(); $poll->add($sub, ZMQ::POLL_IN); $read = $wri = array(); while(true) { $ev = $poll->poll($read, $wri, 5000000); if($ev > 0) { echo "<script type='text/javascript'> parent.updateChat('"; echo $sub->recv() ."');</script>"; } ob_flush(); flush(); } ch at.php
  • 35.
  • 36. sub sub user data pub pub pub web web web
  • 37. $ctx = new ZMQContext(); $socket = $ctx->getSocket(ZMQ::SOCKET_PUB); $socket->connect("ipc:///tmp/usercache"); $socket->connect("ipc:///tmp/datacache"); $type = array('users', 'data'); while(true) { $socket->send($type[array_rand($type)], ZMQ::MODE_SNDMORE); $socket->send(rand(0, 12)); sleep(rand(0,3)); } cach e.php
  • 38. $ctx = new ZMQContext(); $socket = $ctx->getSocket(ZMQ::SOCKET_SUB); $socket->setSockOpt( ZMQ::SOCKOPT_SUBSCRIBE, "users"); $socket->bind("ipc:///tmp/usercache"); while(true) { $cache = $socket->recv(); $request = $socket->recv(); echo "Clearing $cache $requestn"; } userlistener.php
  • 39. types of transport inproc ipc tcp pgm
  • 40.
  • 41. distro sub web client sub web sub event sub sub web pub distro sub web client sub db
  • 42. $ctx = new ZMQContext(); $out = $ctx->getSocket(ZMQ::SOCKET_PUB); $out->setSockOpt(ZMQ::SOCKOPT_RATE, 10000); $out->connect("epgm://;239.192.0.1:7601"); $in = $ctx->getSocket(ZMQ::SOCKET_PULL); $in->bind("tcp://*:6767"); $device = new ZMQDevice( ZMQ::DEVICE_FORWARDER, $in, $out); eventhub.php
  • 43. $ctx = new ZMQContext(); $in = $ctx->getSocket(ZMQ::SOCKET_SUB); $in->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, ''); $in->setSockOpt(ZMQ::SOCKOPT_RATE, 10000); $in->connect("epgm://;239.192.0.1:7601"); $out = $ctx->getSocket(ZMQ::SOCKET_PUB); $out->bind("ipc:///tmp/events"); $device = new ZMQDevice( ZMQ::DEVICE_FORWARDER, $in, $out); distro.php
  • 44. $ctx = new ZMQContext(); $in = $ctx->getSocket(ZMQ::SOCKET_SUB); for($i = 0; $i<100; $i++) { $in->setSockOpt( ZMQ::SOCKOPT_SUBSCRIBE, rand(100000, 999999)); } $in->connect("ipc:///tmp/events"); $i = 0; while($i++ < 1000) { $who = $in->recv(); $msg = $in->recv(); printf("%s %s %s", $who, $msg, PHP_EOL); } cli ent.php
  • 45. push handler mongrel pub client client mongrel 2 http://mongrel2.org/
  • 46. $ctx = new ZMQContext(); $in = $ctx->getSocket(ZMQ::SOCKET_PULL); $in->connect('tcp://localhost:9997'); $out = $ctx->getSocket(ZMQ::SOCKET_PUB); $out->connect('tcp://localhost:9996'); $http = "HTTP/1.1 200 OKrnContent-Length: %srnrn%s"; while(true) { $msg = $in->recv(); list($uuid, $id, $path, $rest) = explode(" ", $msg, 4); $res = $uuid." ".strlen($id).':'.$id.", "; $res .= sprintf($http, 6, "Hello!"); $out->send($res); } handler.php
  • 47. simple_handler = Handler( send_spec='tcp://*:9997', send_ident='ab206881-6f49-4276-9db1-1676bfae18b0', recv_spec='tcp://*:9996', recv_ident='' ) main = Server( uuid="9e71cabf-6afb-4ee1-b550-7972245f7e0a", access_log="/logs/access.log", error_log="/logs/error.log", chroot="./", default_host="general.local", name="example", pid_file="/run/mongre2.pid", port=6767, hosts = [ Host(name="general.local", routes={'/test':simple_handler}) ] ) settings = {"zeromq.threads": 1} servers = [main]
  • 48. namespace m2php; $id ="82209006-86FF-4982-B5EA-D1E29E55D481"; $con = new m2phpConnection($id, "tcp://127.0.0.1:9997", "tcp://127.0.0.1:9996"); $ctx = new ZMQContext(); $in = $ctx->getSocket(ZMQ::SOCKET_SUB); $in->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE,''); $in->connect('tcp://localhost:5566'); $poll = new ZMQPoll(); $poll->add($sub, ZMQ::POLL_IN); $poll->add($con->reqs, ZMQ::POLL_IN); $read = $write = $ids = array(); $snd = ''; $h = "HTTP/1.1 200 OKrnContent-Type: text/ htmlrnTransfer-Encoding: chunkedrnrn"; https://github.com/winks/m2php
  • 49. while (true) { $ev = $poll->poll($read, $write); foreach($read as $r) { if($r !== $in) { $req = $con->recv(); $snd = $req->sender; if($req->is_disconnect()) { unset($ids[$req->conn_id]); } else { $ids[$req->conn_id] = $req->conn_id; $con->send($snd, $req->conn_id,$h); } } else { $m = "<script type='text/javascript'> parent.updateChat('".$in->recv()."'); </script>rn"; $con->send($snd, implode(' ', $ids), sprintf("%xrn%s",strlen($m),$m)); } } } }
  • 50. Helpful Links http://zero.mq http://zguide.zero.mq Ian Barber http://zero.mq/ib http://phpir.com ian.barber@gmail.com @ianbarber http://joind.in/talk/view/3442 thanks!