Swoole在2.0
开始内置**协程(Coroutine)**的能力,提供了具备协程能力IO接口(统一在命名空间Swoole\Coroutine\*
)。
2.0.2
或更高版本已支持PHP7
2.0.8
或更高版本已默认开启--enable-coroutine
,可使用--disable-coroutine
关闭协程特性
从2.0.12版本开始不再支持PHP5
4.0.0
或更高版本仅支持PHP7.1及以上版本,4.0.1
版本开始去除了--enable-coroutine
编译选项, 改为动态配置
enable_coroutine动态配置请见文档
协程可以理解为纯用户态的线程,其通过协作而不是抢占来进行切换。相对于进程或者线程,协程所有的操作都可以在用户态完成,创建和切换的消耗更低。Swoole可以为每一个请求创建对应的协程,根据IO的状态来合理的调度协程,这会带来了以下优势:
开发者可以无感知的用同步的代码编写方式达到异步IO的效果和性能,避免了传统异步回调所带来的离散的代码逻辑和陷入多层回调中导致代码无法维护。
同时由于swoole是在底层封装了协程,所以对比传统的php层协程框架,开发者不需要使用yield关键词来标识一个协程IO操作,所以不再需要对yield的语义进行深入理解以及对每一级的调用都修改为yield,这极大的提高了开发效率。
协程API目前针对了TCP,UDP等主流协议client的封装,包括:
可以满足大部分开发者的需求。对于私有协议,开发者可以使用协程的TCP或者UDP接口去方便的封装。
swoole_server
或者swoole_http_server
进行开发,目前只支持在onRequet
, onReceive
, onConnect
等事件回调函数中使用协程。swoole_server
和swoole_http_server
将为每一个请求创建对应的协程,开发者可以在onRequet
、onReceive
、onConnect
事件回调中使用协程客户端。
在Swoole\Server
的set
方法中增加了一个配置参数max_coro_num
,用于配置一个Worker
进程最多同时处理的协程数目。因为随着Worker
进程处理的协程数目的增加,其占用的内存也会增加,为了避免超出php的memory_limit
限制,请根据实际业务的压测结果设置该值,默认为3000
。
$http = new swoole_http_server("127.0.0.1", 9501);
$http->on("request", function ($request, $response) {
$client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP);
$client->connect("127.0.0.1", 8888, 0.5);
//调用connect将触发协程切换
$client->send("hello world from swoole");
//调用recv将触发协程切换
$ret = $client->recv();
$response->header("Content-Type", "text/plain");
$response->end($ret);
$client->close();
});
$http->start();
当代码执行到connect()和recv()
函数时,swoole会触发进行协程切换,此时swoole可以去处理其他的事件或者接受新的请求。当此client连接
成功或者后端服务回包
后,swoole server会恢复协程上下文,代码逻辑继续从切换点开始恢复执行。开发者整个过程不需要关心整个切换过程。具体使用可以参考client的文档。
__call()
__get()
__set()
等Swoole\Coroutine\Client
Swoole\Coroutine\HTTP\Client
Swoole\Coroutine\HTTP2\Client
Swoole\Coroutine\Redis
Swoole\Coroutine\MySQL
Swoole\Coroutine\PostgreSQL
Server
中需要使用协程版Client
,可以实现全异步Server
go
关键词手工创建协程Swoole
提供了协程工具集:Swoole\Coroutine
,提供了获取当前协程id
,反射调用等能力。