海运的博客

PHP异步并发执行multi cURL详解

发布时间:January 4, 2014 // 分类:PHP // No Comments

官方提供的例子,一次执行多个连接,然后阻塞所有链接完成取内容,整个过程是阻塞的。

<?php
// 创建单个cURL资源
$ch1 = curl_init();
$ch2 = curl_init();

// 设置URL和相应的选项
curl_setopt($ch1, CURLOPT_URL, "https://www.haiyun.me/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch2, CURLOPT_URL, "https://www.haiyun.me/");
curl_setopt($ch2, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);

// 创建批处理cURL句柄
$mh = curl_multi_init();

// 增加单个句柄到批处理
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);

$active = null;
// 执行批处理句柄,循环任务直到全部执行,不等待返回结果
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

//循环判断任务是否执行完成
while ($active && $mrc == CURLM_OK) {
    //阻塞等待cURL批处理中的活动连接,失败时返回-1,不等于-1代表还有活动连接
    if (curl_multi_select($mh) != -1) {
        //有活动连接时继续执行批处理句柄
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

//获取单个URL返回的内容
var_dump(curl_multi_getcontent($ch1));
// 关闭全部句柄
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
?>

非阻塞实现http://code.google.com/p/rolling-curl/,不过在循环时是根据curl_multi_exec返回的运行状态判断的,大量链接时经常没完成就跳出,修改了下根据循环的队列是否完成来判断。

<?php
   $isruning = 1;
   do {
      //执行句柄内所有连接,包括后来新加入的连接
      do {
         $execrun = curl_multi_exec($master, $running);
      } while ($execrun == CURLM_CALL_MULTI_PERFORM);
      //while (($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM) ;
      //if ($execrun != CURLM_OK)
      //break;
      //有连接返回立即处理,并加入新的连接
      while ($done = curl_multi_info_read($master)) {

         //获取返回的信息
         $info = curl_getinfo($done['handle']);
         $output = curl_multi_getcontent($done['handle']);

         //发送返回信息到回调函数
         $callback = $this->callback;
         if (is_callable($callback)) {
            //获取返回信息的句柄
            $key = (string) $done['handle'];
            //根据请求映射是哪个请求返回的信息
            $request = $this->requests[$this->requestMap[$key]];
            unset($this->requestMap[$key]);
            call_user_func($callback, $output, $info, $request);
         }

         //判断队列内的连接是否用完
         if ($i < sizeof($this->requests) && isset($this->requests[$i]) && $i < count($this->requests)) {
            $ch = curl_init();
            $options = $this->get_options($this->requests[$i]);
            curl_setopt_array($ch, $options);
            //增加新的连接
            curl_multi_add_handle($master, $ch);

            //添加到request Maps,用于返回信息时根据handle找到相应连接
            $key = (string) $ch;
            $this->requestMap[$key] = $i;
            $i++;
         } 
         else {
            //循环结束
            $isruning = 0;
         }

         //删除完成的句柄
         curl_multi_remove_handle($master, $done['handle']);
      }

      // Block for data in / output; error handling is done by curl_multi_exec
      if ($running)
      curl_multi_select($master, $this->timeout);

   } while ($isruning);
?>

CentOS5使用Git CA证书错误解决几种方法

发布时间:January 3, 2014 // 分类:Linux基础 // No Comments

设置Git禁用SSL检验:

git config --system http.sslVerify false

更新根证书:

curl http://curl.haxx.se/ca/cacert.pem -o /etc/pki/tls/certs/ca-bundle.crt

更新OpenSSL:

yum update openssl

NoSQL持久化存储之Tokyo Cabinet

发布时间:January 2, 2014 // 分类:NoSQL // No Comments

安装Tokyo Cabinet,后端存储:

yum install gcc zlib-devel bzip2-devel
wget http://fallabs.com/tokyocabinet/tokyocabinet-1.4.48.tar.gz
tar zxvf tokyocabinet-1.4.48.tar.gz
cd tokyocabinet-1.4.48/
./configure --prefix=/usr/local/tokyocabinet-1.4.48/
make && make install

安装Tokyo Cabinet PHP扩展:

git clone https://github.com/rsky/php-tokyocabinet.git
cd php-tokyocabinet/
phpize 
export PKG_CONFIG_PATH=/usr/local/tokyocabinet-1.4.48/lib/pkgconfig/
./configure --enable-tokyocabinet 
make && make install
echo "extension=tokyocabinet.so" >> /etc/php.ini

使用:

<?php
   $bdb = new TCBDB();
   $bdb->open('tc.bdb', TCBDB::OWRITER | TCBDB::OCREAT);
   $bdb->put('key', 'value');
   echo $bdb->get('key'), "\n";
?>

安装Tokyo Cabinet Lua扩展:

yum install lua-devel
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/tokyocabinet-1.4.48/include/
wget http://fallabs.com/tokyocabinet/luapkg/tokyocabinet-lua-1.10.tar.gz
tar zxvf tokyocabinet-lua-1.10.tar.gz 
cd tokyocabinet-lua-1.10
./configure --prefix=/usr/local/tokyocabinet-lua-1.10 
make && make install

安装Tokyo Tyrant,网络前端:

wget http://fallabs.com/tokyotyrant/tokyotyrant-1.1.41.tar.gz
tar zxvf tokyotyrant-1.1.41.tar.gz 
cd tokyotyrant-1.1.41
./configure --prefix=/usr/local/tokyotyrant-1.1.41/ --enable-lua  \
--with-tc=/usr/local/tokyocabinet-1.4.48/
make && make install
cp -r ext/ /etc/ttserver
echo "/usr/local/tokyotyrant-1.1.41/lib/" >> /etc/ld.so.conf.d/tokyo.conf
echo "/usr/local/tokyocabinet-1.4.48/lib" >> /etc/ld.so.conf.d/tokyo.conf
ldconfig

启动Tokyo Tyrant:

ttserver -host 127.0.0.1 -port 1978 -thnum 8 -dmn -pid /tmp/ttserver.pid -log /tmp/ttserver.log -le \
-ulog /tmp/ -ulim 32m -sid 1 -rts /tmp/ttserver.rts -ext /etc/ttserver/queue.lua /tmp/database.tch

Tokyo Tyrant通过tcrdbext.c对Lua提供了API,可使用Lua脚本扩展Tokyo Tyrant服务端功能。
更多:http://fallabs.com/tokyotyrant/spex.html#luaext
安装Tokyo Tyrant PHP扩展:

git clone https://github.com/mkoppanen/php-tokyo_tyrant.git
cd php-tokyo_tyrant/
phpize
./configure --with-tokyo-tyrant=/usr/local/tokyotyrant-1.1.41/ \
--with-tokyo-cabinet-dir=/usr/local/tokyocabinet-1.4.48/
make && make install
echo 'extension=tokyo_tyrant.so' >> /etc/php.ini

测试:

<?php
   $tt = new TokyoTyrant("localhost", '1978');
   $tt->put("key", "value");
   echo $tt->get("key");

   for($i=1; $i<=100; $i++)
   {
      $tt->ext('enqueue','0', 'my_queue', $i );
   }
   print_r($tt->ext('dequeue', '0','my_queue',  10));
   print_r($tt->ext('dequeue', '0','my_queue',  10));
   print_r($tt->ext('dequeue', '0','my_queue',  10));
//上面ext方法的第2个参数0,为是否开启锁机制,还有下面两个值可选:
//一个相当于行锁,一个相当于表锁,一般第一个就够用了
//Tyrant::XOLCKREC for record locking
//Tyrant::XOLCKGLB for global locking
?>

使用客户端管理:

tcrmgr put -port 1978 127.0.0.1 key1 value1
tcrmgr ext -port 1978 127.0.0.1 enqueue myqueue value1
curl -X PUT http://192.168.1.3:1978/key1 -d "value1"
curl http://127.0.0.1:1978/key1

NoSQL持久化存储之LevelDB

发布时间:January 2, 2014 // 分类:NoSQL // No Comments

安装LevelDB:

cd /usr/local/src/
wget http://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz
tar zxvf leveldb-1.15.0.tar.gz 
cd leveldb-1.15.0
make
cp libleveldb.* /usr/local/lib/
cp -r include/leveldb /usr/local/include/

LevelDB提供了一个测试程序:

make db_bench
cp db_bench /usr/local/bin/
db_bench --num=100000000 --write_buffer_size=$((256*1024*1024))

安装PHP扩展,https://github.com/reeze/php-leveldb

git clone https://github.com/reeze/php-leveldb.git
cd php-leveldb/
phpize
./configure
make
make install
echo 'extension=leveldb.so' >> /etc/php.ini

测试下下写入2亿数据用时30分钟,然后读取单个key用时0.02秒左右。

<?php
   $start = microtime ( true ); 
   $db = new LevelDB("/tmp/leveldb-test2-db");
   for($i=1; $i<=200000000; $i++)
   {
      $key = sprintf('%012d', $i);
      $db->put("queue-$key", "value$i@gmail.com");
   }
   $end = microtime ( true ); 
   echo "脚本执行时间".($end - $start)."\n";  
   //$db->get('key');
?>

前端可使用:Kyoto Tycoon

NoSQL持久化存储之Berkeley DB

发布时间:January 2, 2014 // 分类:NoSQL // No Comments

安装Berkeley DB:

wget http://download.oracle.com/berkeley-db/db-6.0.20.tar.gz
tar zxvf db-6.0.20.tar.gz 
cd db-6.0.20/build_unix/
../dist/configure --prefix=/usr/local/berkeleydb --enable-cxx
make && make install

安装PHP扩展:

cd ../lang/php_db4/
phpize
./configure --with-db4=/usr/local/berkeleydb/
make && make install
echo 'extension=db4.so' >> /etc/php.ini

简单使用:

<?php
   $db = new Db4();
   $db->open(null, "/var/tmp/db4", "test"); 
   $db->put('key', 'value');
   $db->get('key');
?>

http://www.oracle.com/technetwork/products/berkeleydb/downloads/index-082944.html

分类
最新文章
最近回复
  • opnfense: 谢谢博主!!!解决问题了!!!我之前一直以为内置的odhcp6就是唯一管理ipv6的方式
  • liyk: 这个方法获取的IPv6大概20分钟之后就会失效,默认路由先消失,然后Global IPV6再消失
  • 海运: 不好意思,没有。
  • zongboa: 您好,請問一下有immortalwrt設定guest Wi-Fi的GUI教學嗎?感謝您。
  • 海运: 恩山有很多。
  • swsend: 大佬可以分享一下固件吗,谢谢。
  • Jimmy: 方法一 nghtp3步骤需要改成如下才能编译成功: git clone https://git...
  • 海运: 地址格式和udpxy一样,udpxy和msd_lite能用这个就能用。
  • 1: 怎么用 编译后的程序在家里路由器内任意一台设备上运行就可以吗?比如笔记本电脑 m参数是笔记本的...
  • 孤狼: ups_status_set: seems that UPS [BK650M2-CH] is ...
归档