这个频道内会详细介绍异步编程与同步编程的不同之处以及需要注意的事项。
sleep
以及其他睡眠函数,这样会导致整个进程阻塞exit/die
是危险的,会导致Worker
进程退出register_shutdown_function
来捕获致命错误,在进程异常退出时做一些清理工作,具体参考 /wiki/page/305.html
PHP
代码中如果有异常抛出,必须在回调函数中进行try/catch
捕获异常,否则会导致工作进程退出set_exception_handler
,必须使用try/catch
方式处理异常Worker
进程不得共用同一个Redis
或MySQL
等网络服务客户端,Redis/MySQL
创建连接的相关代码可以放到onWorkerStart
回调函数中,具体参考 /wiki/page/325.html
使用Coroutine
特性,请认真阅读 协程编程须知
新手非常容易犯这个错误,由于Swoole
是常驻内存的,所以加载类/函数定义的文件后不会释放。因此引入类/函数的php文件时必须要使用include_once
或require_once
,否会发生cannot redeclare function/class
的致命错误。
PHP守护进程与普通Web程序的变量生命周期、内存管理方式完全不同。请参考 swoole_server内存管理 页面。编写swoole_server
或其他常驻进程时需要特别注意。
进程隔离也是很多新手经常遇到的问题。修改了全局变量的值,为什么不生效,原因就是全局变量在不同的进程,内存空间是隔离的,所以无效。所以使用Swoole
开发Server
程序需要了解进程隔离
问题。
Redis
、MySQL
、文件
、Swoole\Table
、APCu
、shmget
等工具实现$server = new Swoole\Http\Server('127.0.0.1', 9500);
$i = 1;
$server->on('Request', function ($request, $response) {
global $i;
$response->end($i++);
});
$server->start();
在多进程的服务器中,$i
变量虽然是全局变量(global
),但由于进程隔离的原因。假设有4
个工作进程,在进程1
中进行$i++
,实际上只有进程1
中的$i
变成2
了,其他另外3
个进程内$i
变量的值还是1
。
正确的做法是使用Swoole
提供的Swoole\Atomic
或Swoole\Table
数据结构来保存数据。如上述代码可以使用Swoole\Atomic
实现。
$server = new Swoole\Http\Server('127.0.0.1', 9500);
$atomic = new Swoole\Atomic(1);
$server->on('Request', function ($request, $response) use ($atomic) {
$response->end($atomic->add(1));
});
$server->start();
Swoole\Atomic
数据是建立在共享内存之上的,使用add
方法加1
时,在其他工作进程内也是有效的