TFS的Nginx扩展nginx_tfs 与 PHP包装器

Taobao官方有提供一个针对TFS的Nginx扩展,地址https://github.com/alibaba/nginx-tfs,设计成REST风格API,它就是一个适配器,任何的编程语言执行简单发送指令就可以操作TFS。

官方描述的安装:
1 TFS模块使用了一个开源的JSON库来支持JSON,请先安装yajl-2.0.1(http://lloyd.github.io/yajl/)。
2 下载nginx或tengine。
3 ./configure –add-module=/path/to/nginx-tfs
4 make && make install

实际操作过程:

#先安装Nginx需要的包
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel

#获取yajl
wget http://github.com/lloyd/yajl/zipball/2.1.0
mv 2.1.0 yajl-2.0.1.zip
unzip yajl-2.0.1.zip
cd yajl-2.0.1
##默认安装到/usr/local,库放入了/usr/local/lib中
./configure 
##这个玩意使用了cmake      
yum install cmake 
make && make install
#避免后面找不到这个库,玛尼,这里拷贝一下
cp -a /usr/local/libyajl* /lib64/

#获取nginx-tfs扩展,解压一下就好了
wget https://github.com/alibaba/nginx-tfs/archive/master.zip
unzip master.zip

#Ngingx-1.8.0无法适配这个扩展,所以找一个低一点的版本
wget http://nginx.org/download/nginx-1.2.9.tar.gz
tar zxvf nginx-1.2.9.tar.gz
cd nginx-1.2.9
useradd www
./configure --user=www --group=www --prefix=/usr/local/nginx-1.2.9 --add-module=/root/nginx-tfs-master
make && make install

配置:

vi nginx.conf 添加:
tfs_upstream tfs_ns {
        server 192.168.1.102:8000;
        type ns;
    }

server {
	listen       80;
	server_name  192.168.1.102;

        tfs_keepalive max_cached=10 bucket_count=2;

        location / {
              tfs_pass tfs://tfs_ns;
        }
}

我这里不使用rcServer,所以配置异常简单。具体配置参考:https://github.com/alibaba/nginx-tfs/blob/master/ReadMe.markdown

然后用如下程序POST一张图片:

/////////////////////////////////////////////////////
$url = 'http://192.168.1.102/v1/tfs?suffix=.jpg&simple_name=0';

$postBinary = file_get_contents('D:\v.jpg');

//初始化
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, '');
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
//
curl_setopt($ch, CURLOPT_POST, false);
//
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,$postBinary);
//
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch,CURLOPT_MAXREDIRS,10);
//
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0");

$result = curl_exec($ch);
$errn = curl_errno($ch);
curl_close($ch);

print_r($result);

######################################
输出:
{ "TFS_FILE_NAME": "T1IRETByxT1RXrhCrK" } 

说明:这个POST跟一般常见的POST是不一样的(RESTful风格),首先,参数作为URL的一部分,然后就是POST的数据不需要对应一个名称,直接是原生数据。

直接访问这个链接:
tfs_output

其它的API参考:https://github.com/alibaba/nginx-tfs/blob/master/TFS_RESTful_API.markdown,这些API的调用可以通过CURL来非常容易的使用。

针对一个nginx_tfs的这个扩展,在Github有一个针对它的PHP包装器:https://github.com/ifa6/php_tfs_client
这个包里面提供的HttpClient.php是对Curl的封装,HttpResponse.php是响应对象的封装,HttpClient.php提供了RESTfull风格的几个方法:

    public function get($url)
    {
        return $this->prepareCurlHandler(array(
            CURLOPT_URL => $this->prepareUrl($url),
            CURLOPT_CUSTOMREQUEST => 'GET',
        ))->send();
    }

    public function put($url, $content=null)
    {
        return $this->prepareCurlHandler(array(
            CURLOPT_URL => $this->prepareUrl($url),
            CURLOPT_CUSTOMREQUEST => 'PUT',
            CURLOPT_POSTFIELDS => $content,
        ))->send();
    }

    public function post($url, $content=null)
    {
        return $this->prepareCurlHandler(array(
            CURLOPT_URL => $this->prepareUrl($url),
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $content,
            CURLOPT_POST => true
        ))->send();
    }

    public function delete($url)
    {
        return $this->prepareCurlHandler(array(
            CURLOPT_URL => $this->prepareUrl($url),
            CURLOPT_CUSTOMREQUEST => 'DELETE',
        ))->send();
    }

    public function head($url)
    {
        return $this->prepareCurlHandler(array(
            CURLOPT_URL => $this->prepareUrl($url),
            CURLOPT_CUSTOMREQUEST => 'HEAD',
            CURLOPT_NOBODY => true
        ))->send();
    }

除了这些方法,还有一系列的set方法,比如设置请求URL,CURL用的头信息等:

$httpClient = new HttpClient();
$reponse = $httpClient->setBaseUrl('http://blog.ifeeline.com')->get('/xxx/api.php');
if($reponse->isOk()){
    $content = $response->getContent();
    // ......
}

这个包下面Client.php是利用HttpClient对nginx_tfs提供的API进行了二次封装,不过我觉得使用HttpClient已经足够好了。