GitHub网友的疑问:
单一的性能 可能会有提高.但是web服务器处理的东西很多啊.
错误啦,日志啦,缓存啦,扩展性啦 这些用php实现有难度啊.
确认这个能运行在 windows 环境下么?
没有使用pcntl ? 试试在脚本里 sleep 5秒,然后再做压测.. 我觉得会崩
解答:
swoole是扩展层实现多进程的,不依赖pcntl。单个进程sleep或致命错误不会影响整个服务器的运行。
swoole不能在windows下运行,支持Linux,freebsd。
Swoole和Node.js不同,swoole是半同步半异步的,处理网络IO的部分是全异步非阻塞的。业务逻辑部分是同步阻塞执行的。所以不存在上述问题。在业务代码中可以按照现有的编码方式来进行开发。当然Swoole也赞成在代码中使用异步回调的方式来做。
PHP5.3之后支持了类似Java的jar包,名为phar。用来将多个PHP文件打包为一个文件。
首先需要修改php.ini配置将phar的readonly关闭,默认是不能写phar包的,include是默认开启的。
phar.readonly => On
创建一个phar压缩包
<?php
$phar = new Phar('swoole.phar');
$phar->buildFromDirectory(__DIR__.'/../', '/\.php$/');
$phar->compressFiles(Phar::GZ);
$phar->stopBuffering();
$phar->setStub($phar->createDefaultStub('lib_config.php'));
new Phar的参数是压缩包的名称。buildFromDirectory指定压缩的目录,第二个参数可通过正则来制定压缩文件的扩展名。
Phar::GZ表示使用gzip来压缩此文件。也支持bz2压缩。参数修改为 PHAR::BZ2即可。
setSub用来设置启动加载的文件。默认会自动加载并执行 lib_config.php。
执行此代码后,即生成一个swoole.phar文件。
使用phar压缩包
<?php
include 'swoole.phar';
include 'swoole.phar/code/page.php';
使用phar可以很方便的打包你的代码,集成部署到线上机器。
Swoole扩展提供了一个强大的socket客户端实现,支持TCP/UDP。之前文章说过PHP自带的stream函数有各种陷阱。刚刚使用PHP的socket扩展时,很容易栽在这些问题上。
Swoole扩展使用C实现了一个封装好的socket客户端,代码很健壮。以类的方式提供给大家使用。简单方便,安全可靠。代码在:https://github.com/matyhtf/php_swoole
使用方法:
$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); //同步阻塞
$ret = $client->connect('127.0.0.1', 9501, 0.5, 0);
$client->send("hello world\n");
$data = $client->recv(1024);
echo $data;
unset($client);
类的构造方法,第一个参数是socket的类型,目前支持SWOOLE_SOCK_UDP/SWOOLE_SOCK_TCP。第二个参数SWOOLE_SOCK_SYNC表示是同步阻塞来执行的。Swoole已经设置过超时,就算没有收到数据包,在超过约定时间后也会返回的。
connect方法用来连接到Server。参数分别是Host、Port、超时时间单位是秒0.5表示500ms、是否启用UDP connect。
send方法用来发送数据,recv方法来接收数据,recv方法支持第二个参数,如果第二个参数为true,表示会等到所有数据到来才会返回。
close方法用来关闭socket,析构对象时会自动close此socket。
为什么要用C扩展
C是静态编译的,执行效率比PHP代码高很多。同样的运算代码,使用C来开发,性能会比PHP要提升数百倍。IO操作如CURL,因为耗时主要在IOWait上,C扩展没有明显优势。
另外C扩展是在进程启动时加载的,PHP代码只能操作Request生命周期的数据,C扩展可操作的范围更广。
第一步
下载PHP的源代码,如php-5.4.16。解压后进入php-5.4.16\ext目录。输入 ./ext_skel –extname=myext,myext就是扩展的名称,执行后生成myext目录。
ext_skel是PHP官方提供的用于生成php扩展骨架代码的工具。
cd myext。可以看到php_myext.h、myext.c、config.m4等几个文件。config.m4是AutoConf工具的配置文件,用来修改各种编译选项。
第二步
修改config.m4,将
dnl PHP_ARG_WITH(myext, for myext support,
dnl Make sure that the comment is aligned:
dnl [ --with-myext Include myext support])
修改为
PHP_ARG_WITH(myext, for myext support,
[ --with-myext Include myext support])
下边还有一个 –enable-myext,是表示编译到php内核中。with是作为动态链接库载入的。
第三步
修改php_myext.h,看到PHP_FUNCTION(confirm_myext_compiled); 这里就是扩展函数声明部分,可以增加一行 PHP_FUNCTION(myext_helloworld); 表示声明了一个myext_helloworld的扩展函数。
然后修改myext.c,这个是扩展函数的实现部分。
const zend_function_entry myext_functions[] = {
PHP_FE(confirm_myext_compiled, NULL) /* For testing, remove later. */
PHP_FE(myext_helloworld, NULL)
PHP_FE_END /* Must be the last line in myext_functions[] */
};
这的代码是将函数指针注册到Zend引擎,增加一行PHP_FE(myext_helloworld, NULL)(后面不要带分号)。
第四步
在myext.c末尾加myext_helloworld的执行代码。
PHP_FUNCTION(myext_helloworld)
{
char *arg = NULL;
int arg_len, len;
char *strg;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
return;
}
php_printf("Hello World!\n");
RETRUN_TRUE;
}
zend_parse_parameters是用来接受PHP传入的参数,RETURN_XXX宏是用来返回给PHP数据。
第五步
在myext目录下依次执行phpize、./configure 、make、make install。然后修改php.ini加入extension=myext.so
执行php -r “myext_helloworld(‘test’);”,输出hello world!