海运的博客

PHP重新动态编译Curl扩展添加异步DNS支持c-ares

发布时间:January 30, 2015 // 分类: // No Comments

pycurl支持异步DNS支持c-ares类似,请先确定Libcurl是否已支持异步DNS解析c-ares,如不支持可升级libcurl支持异步DNS解析c-ares
理论上的libcurl更新添加支持异步DNS解析后,将库文件通过ldconfig添加到系统动态库,如果大版本号和之前版本相同,可以不用重新编译Php curl扩展已支持异步DNS,因为PHP curl依赖libcurl会自动选择版本较高的lib。
如查看系统共享库中的Libcurl:

ldconfig -p|grep curl
        libcurl.so.4 (libc6,x86-64) => /usr/local/curl/lib/libcurl.so.4
        libcurl.so.4 (libc6,x86-64) => /usr/lib64/libcurl.so.4
        libcurl.so (libc6,x86-64) => /usr/local/curl/lib/libcurl.so
        libcurl.so (libc6,x86-64) => /usr/lib64/libcurl.so

然后查看php curl扩展的共享库依赖,可见已自动选择新编译的libcurl.so.4:

ldd /usr/lib64/php/modules/curl.so|grep curl
        libcurl.so.4 => /usr/local/curl/lib/libcurl.so.4 (0x00007f406f0f9000)

不过为了稳定可以重新编译下php curl扩展,本文PHPyum安装,如果是源码安装的可参考:PHP动态编译添加IMAP模块支持
查看已安装的PHP版本,并下

php -v
PHP 5.5.21 (cli) (built: Jan 21 2015 15:35:14) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies

下载相应版本的源码并重新编译curl扩展:

yum install php-devel
wget https://github.com/php/php-src/archive/php-5.5.21.tar.gz
tar zxvf php-5.5.21.tar.gz 
cd php-src-php-5.5.21/ext/curl/
phpize 
./configure --with-curl=/usr/local/curl

查看当前PHP CURL是否已支持异步DNS支持:

php -i|grep AsynchDNS
AsynchDNS => Yes

Python Curl/Pycurl添加DNS解析支持

发布时间:January 30, 2015 // 分类:Python // No Comments

Pycurl底层使用libcurl,请先确定Libcurl是否已支持异步DNS解析c-ares,如不支持可升级libcurl支持异步DNS解析c-ares
其实Libcurl更新支持为异步DNS如果已安装pycurl不用重新安装Pycurl,见http://www.haiyun.me/archives/1070.html
通过pip安装:

export PATH=/usr/local/curl/bin/:$PATH
export LD_LIBRARY_PATH="/usr/local/curl/lib/"
export PYCURL_SSL_LIBRARY=openssl
pip install pycurl

下载pycurl源码包安装:

wget http://pycurl.sourceforge.net/download/pycurl-7.19.5.1.tar.gz
tar zxvf pycurl-7.19.5.1.tar.gz 
cd pycurl-7.19.5.1
export LD_LIBRARY_PATH="/usr/local/curl/lib/"
python setup.py install --curl-config=/usr/local/curl/bin/curl-config --with-ssl

检查pycurl是否已支持异步DNS解析c-ares:

>>> import pycurl
>>> pycurl.version
'PycURL/7.19.5.1 libcurl/7.40.0 OpenSSL/1.0.1e zlib/1.2.7 c-ares/1.10.0'

安装pycurl后使用时遇到的一些错误:

pycurl.so: undefined symbol: CRYPTO_num_locks

原因:libcurl安装时--with-ssl支持

libcurl link-time ssl backend (openssl) is different from compile-time ssl backend (none/other)

原因:libcurl和pycurl编译时ssl后端不一致,调整见上和libcurl安装

pycurl: libcurl link-time version (7.19.7) is older than compile-time version (7.4.0)

原因:编译pycurl时使用的编译的libcurl动态库,不过现在pycurl现在加载的是系统自带的版本较旧的动态库,解决将编译的libcurl动态库添加到系统动态库,见ldconfig

CentOS编译安装libcurl/curl添加异步DNS解析c-ares

发布时间:January 30, 2015 // 分类: // No Comments

在使用curl异步并发请求时如果有大量域名解析会长时间阻塞程序IO,可以编译升级libcurl以支持异步DNS解析。
Centos7自带libcurl已支持异步DNS支持,不过是--enable-threaded-resolver,可以使用curl-config --configure查看curl编译参数。
查看Libcurl是否已支持异步DNS解析,包含AsynchDNS为支持:

curl --version
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.40.0 OpenSSL/1.0.1e zlib/1.2.3
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IPv6 Largefile NTLM SSL libz 

首先安装异步DNS解析库c-ares:

yum install c-ares-devel openssl-devel

编译libcurl库:

wget http://curl.haxx.se/download/curl-7.40.0.tar.gz
tar zxvf curl-7.40.0.tar.gz 
cd curl-7.40.0/
./configure --enable-ares --prefix=/usr/local/curl --with-ssl
make && make install

查看编译安装的curl信息,已经支持了异步DNS解析库c-ares:

/usr/local/curl/bin/curl --version
curl 7.40.0 (x86_64-unknown-linux-gnu) libcurl/7.40.0 OpenSSL/1.0.1e zlib/1.2.7 c-ares/1.10.0
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz UnixSockets 

将libcurl动态库添加到动态链接库:

echo '/usr/local/curl/lib' > /etc/ld.so.conf.d/libcurl.conf
ldconfig

使用libcurl库看是否支持c-ares:

#include <curl/curl.h>
int main()
{
 curl_version_info_data*info=curl_version_info(CURLVERSION_NOW);
 if (info->features&CURL_VERSION_ASYNCHDNS) {
   printf( "ares enabled\n");
 } else {
   printf( "ares NOT enabled\n");
 }
 return 0;
}

又一PHP libcurl封装异步并发HTTP客户端

发布时间:January 27, 2015 // 分类:PHP // No Comments

PHP标准库内置curl扩展,不过实现不完整,如multi_socket_action接口,无意中发现pecl http库同样基于libcurl封装,支持更多的libcurl特性,更新也比较快,底层通过libevent(epoll)实现multi_socket_action接口,不过pecl http版本1和版本2 api完全不兼容,使用过程中稳定性及性能并不如PHP内置的curl,好像还有内存泄露,以下为示例代码,基于pecl_http 2.20:

<?php
   function push($client, $url) {
      $req = new http\Client\Request("GET", $url, ["User-Agent"=>"My Client/0.1"]);
      $req->setOptions(array('connecttimeout'=>1, 'timeout'=>1));
      $client->enqueue($req, function($response) use ($client, $req, $url) {
         printf("%s returned '%s' (%d)\n", $response->getTransferInfo("effective_url"), $response->getInfo(), $response->getResponseCode());
         echo $client->count().PHP_EOL;
         global $urls;
         if ($urls) {
            while ($client->count() < 20) {
               $url = array_shift($urls);
               push($client, $url);
            }
            return true; // dequeue
         }
      });
   }

   $client = new http\Client;
   $client->enablePipelining(true);
   $client->enableEvents(true);

   for ($i = 0; $i < 10000; ++$i) {
      $urls[] = "http://192.168.1.3/";
   }
   for ($i = 0; $i < 20; ++$i) {
      $url = array_shift($urls);
      push($client, $url);
   }
   /*
   try{
      var_dump($client->send());
   }
   catch(http\Exception\RuntimeException  $e)
   {
      echo 'Message: ' .$e->getMessage().PHP_EOL;
   }
   */

   while ($client->once()) {
      $client->wait();
   }

Docker守护进程管理器s6/Supervisor

发布时间:January 25, 2015 // 分类:Docker // No Comments

安装s6及依赖,注意make版本一定要4.0以上.

wget http://skarnet.org/software/skalibs/skalibs-2.2.0.0.tar.gz
tar zxvf skalibs-2.2.0.0.tar.gz
cd skalibs-2.2.0.0
./configure && make && make install
wget http://skarnet.org/software/execline/execline-2.0.1.1.tar.gz
tar zxvf execline-2.0.1.1.tar.gz
cd execline-2.0.1.1
./configure && make && make install
wget http://skarnet.org/software/s6/s6-2.0.1.0.tar.gz
tar zxvf s6-2.0.1.0.tar.gz
cd s6-2.0.1.0
./configure && make && make install

s6启动时会依次执行目录下run命令:

mkdir -p /etc/s6/nginx/
mkdir -p /etc/s6/.s6-svscan
#启动命令
cat > /etc/s6/nginx/run << EOF
#!/bin/bash
nginx -c /etc/nginx/nginx.conf
EOF
chmod +x /etc/s6/nginx/run
#关闭命令
cat > /etc/s6/nginx/finish << EOF
#!/bin/bash
kill  `cat /var/run/nginx.pid`
EOF
chmod +x /etc/s6/nginx/finish

注意程序要以foreground非守护方式启动,如nginx要在配置文件添加:

daemon off;

当docker容器关闭时s6执行.s6-svscan/finish:

cat > /etc/s6/.s6-svscan/finish << EOF
#!/bin/bash
for file in /etc/s6/*/finish; do
   $file
done

for service in /etc/s6/* ; do
   s6-svwait -d $service
done
EOF
chmod +x /etc/s6/.s6-svscan/finish

docker容器启动时执行命令:

s6-svscan /etc/s6/
#-c 最大service数
#-t 重新扫描间隔,如果程序关闭会自动重启,毫秒,默认5秒

进程控制,重启:

s6-svc -t /etc/s6/nginx

关闭不重启:

s6-svc -d /etc/s6/nginx

更多:http://skarnet.org/software/s6/s6-svc.html
参考:
http://blog.tutum.co/2014/12/02/docker-and-s6-my-new-favorite-process-supervisor/
http://kfei.logdown.com/posts/245469-using-s6-as-the-init-process-for-muliple-service-docker-container

分类
最新文章
最近回复
  • track: NAT 部分没处理,这块感觉有问题。
  • yu: 查到有用的资料很幸福!
  • boscotsang: 请问下服务器端如何控制权限让通过权限认证的客户端才能连接?现在这样只要有自编译的客户端程序都可...
  • yck932: 大侠,请问哪里有 tunnels 详细参考资料,谢谢
  • bubble: 现在linux 4.9以上的内核有个bbr的参数,用这个bbr比用锐速效果更好,可参考我的博文...
  • wang: openwrt 只有 tmp/etc/miniupnpd.conf 修改后又重置了,其他路径找...
  • wbq: 可以了 只是https透明代理如何做呢?
  • wbq: 你的这个配置需要浏览器设置代理ip+port, 现在假设不设置,只配置客户端网关为Nginx那...
  • wbq: 您好,想用Nginx做个透明代理,客户端机器配置下网关(即Nginx那台机器),客户端dns配...
  • ccc: 可以提供易调用openssl常用函数吗?