前言
最近听说有个东东重新定义了"世界上最好的语言",激动一查原来大名叫swoole,
你看下它的官方定义:
PHP的异步、并行、高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询。 Swoole内置了Http/WebSocket服务器端/客户端、Http2.0服务器端。
Swoole2.0支持了类似Go语言的协程,可以使用完全同步的代码实现异步程序。PHP代码无需额外增加任何关键词,底层自动进行协程调度,实现异步。
你再看它有多牛:
上面的引用的都来自人民日报噢不,是官方定义,不管你信不信,反正我有点方。。。
既然它辣么好,那oss php sdk必须支持啊(没错我只是想告诉你它怎么用,oss php sdk没毛病,别上来就歧视俺们是残疾人)。
废话说那么多,干货还没见到。下面就说说oss php sdk怎么和swoole搞基。
一、安装swoole
别看人民日报上说的swoole根正苗红的扩展,我简单调查下它php -m | grep swoole
尽然为空、为空、为空。。。所以要自行安装swoole,如果你和我一样安装了php7和pecl,你可以直接,pecl install swoole
然后用php -info | grep php.ini查看Loaded Configuration File(只有它能让php扩展干活)具体是哪个,对于我的环境是/etc/php/7.0/cli/php.ini这个文件,你需要vim /etc/php/7.0/cli/php.ini
然后添加extension = "swoole.so"
或者你可以自行编译安装swoole(什么?不会?google一搜满屏都是方法),只要和下面一样我们就可以继续玩。
二、玩转oss php sdk
既然是在oss php sdk中玩转swoole,那必须要把php sdk搞起呀。方法很简单,方法如下:
- git clone https://github.com/aliyun/aliyun-oss-php-sdk.git #从oss php sdk的代码地址下载代码
- cd aliyun-oss-php-sdk/
- 配置好samples/Config.php #相信你肯定不是第一次用oss
- php sample/Swoole.php #运行我们提前放好的sample程序
- curl 127.0.0.1:9503
是不是出现了 Hello Swoole
这就证明swoole和oss php sdk正式搞在一起了。
三、设置nginx做反向代理
前面已经可以通过swoole访问oss了,但在服务器端更普遍的做法是使用nginx作为前端代理,通过nginx反向代理服务器访问我们起的swoole server。
具体的步骤:(已安装nginx的自觉跳过)
- wget http://nginx.org/download/nginx-1.11.3.tar.gz #下载最新版本
- tar -zxvf nginx-1.11.3.tar.gz #解压
- cd nginx-1.11.3
- ./configure --prefix=/usr/local/nginx #配置
- make #注意:这里可能会报错,提示“pcre.h No such file or directory”,具体详见:http://stackoverflow.com/questions/22555561/error-building-fatal-error-pcre-h-no-such-file-or-directory
需要安装 libpcre3-dev,命令为:sudo apt-get install libpcre3-dev - sudo make install
- sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf #注意:-c 指定配置文件的路径,不加的话,nginx会自动加载默认路径的配置文件,可以通过 -h查看帮助命令。
- ps -ef | grep nginx #查看nginx进程:
如果是这样说明nginx正常工作了,下面用nginx反向代理127.0.0.1:9503,修改 /usr/local/nginx/conf/nginx.conf如下:
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream swoole{
server 127.0.0.1:9503;
keepalive 4;
}
server {
listen 80;
server_name www.swoole.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://swoole;
proxy_set_header Connection "";
proxy_http_version 1.1;
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
- reload nginx使配置生效
- /usr/local/nginx/sbin/nginx -s reload
- vim /etc/hosts,添加
127.0.0.1 www.swoole.com
- 验证结果,curl www.swoole.com 或者浏览器打开这个域名,是不是还是出现 Hello Swoole了。
四、swoole使用经验贴
废了这么大功夫,如果只出现了个Hello Swoole是太low了点,我不剧透你耐心往下看。
- 在./aliyun-oss-php-sdk目录下有个sample.jpg文件, 简单上传文件示例代码如下,
<?php
require_once __DIR__ . '/Common.php';
use OSS\OssClient;
use OSS\Core\OssException;
$bucket = Common::getBucketName();
$ossClient = Common::getOssClient();
if (is_null($ossClient)) exit(1);
//*******************************简单使用***************************************************************
$options = array(
OssClient::OSS_FILE_DOWNLOAD => "example_download.jpg",
);
$ossClient->uploadFile($bucket, "example.jpg", "example.jpg");
$ossClient->getObject($bucket, "example.jpg", $options);
- 执行并查看结果:
这是最简单的oss上传下载文件用法。
- 仿照上面的步骤在swoole server中调用oss php sdk,并作nginx代理后,最简单的oss上传下载代码变成了这样:
<?php
require_once __DIR__ . '/Common.php';
use OSS\OssClient;
use OSS\Core\OssException;
$bucket = Common::getBucketName();
$ossClient = Common::getOssClient();
if (is_null($ossClient)) exit(1);
//*******************************简单使用***************************************************************
$options = array(
OssClient::OSS_FILE_DOWNLOAD => "example_download.jpg",
);
$serv = new swoole_http_server("127.0.0.1", 9503);
$serv->set(array(
'worker_num' => 16,
'daemonize' => true,
'max_request' => 10000,
'dispatch_mode' => 2,
'debug_mode'=> 1,
'log_file' => '/tmp/swoole_http_server.log',
));
$serv->on('Request', function($request, $response) use($ossClient, $bucket, $options){
$ossClient->uploadFile($bucket, "example.jpg", "example.jpg");
$ossClient->getObject($bucket, "example.jpg", $options);
$response->end("Hello Swoole\n");
});
$serv->start();
- php sample/Swoole.php
- curl www.swoole.com
是不是发现长时间没反应,nginx报个错误。查看nginx的accesslog,发现报504。打开我们在swoole中设置的swoole_http_server.log发现:
这里有两层问题:
- 问题一:从报错发现是oss php sdk没有找到这个example.jpg文件,example.jpg明明是个本地文件为什么会找不到?
- 问题二:即使有这个错误为什么会造成nginx报504?
如何去解这两个问题?
对于问题一应该是swoole的坑,实际测试发现,swoole下相对路径是从根目录"/"算的,而不是当前目录。所以把文件写成绝对路径就ok了。
对于问题二我的理解是swoole的使用者必须去包装它所调用接口抛出的错误,对本文来说当然就是oss php sdk抛出的错误,以让nginx正确识别。