协程可以理解为纯用户态的线程,其通过协作而不是抢占来进行切换。相对于进程或者线程,协程所有的操作都可以在用户态完成,创建和切换的消耗更低。Swoole可以为每一个请求创建对应的协程,根据IO的状态来合理的调度协程,这会带来了以下优势:
- 开发者可以无感知的用同步的代码编写方式达到异步IO的效果和性能,避免了传统异步回调所带来的离散的代码逻辑和陷入多层回调中导致代码无法维护。
- 同时由于swoole是在底层封装了协程,所以对比传统的php层协程框架,开发者不需要使用yield关键词来标识一个协程IO操作,所以不再需要对yield的语义进行深入理解以及对每一级的调用都修改为yield,这极大的提高了开发效率。
协程API目前针对了TCP,UDP等主流协议client的封装,包括:
- UDP
- TCP
- HTTP
- Mysql
- Redis
注意:协程的客户端必须是使用在onRequest、onReceive,onConnect的回调中,因此不能直接使用,在这里我们使用了http_server的onRequest
传统的实现方式和现有的实现方式的比较:
/**
* 传统的同步实现方式:
* 1.redis
* 2.mysql
* 所以时间是redis+mysql的响应时间之和
* 使用协程的方式,那么所有的数据层的网络io的时间的逻辑是
* time = max(redis,mysql),即两块操作时间的最大值
*/
以同步的方式,通过key值异步的获取redis中的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php /** * Created by bingxiong. * Date: 4/18/18 * Time: 6:48 PM * Description: */ $http = new swoole_http_server('0.0.0.0',8001); $http->on('request',function ($request,$response){ // 获取redis里面的 key的内容,然后输出到浏览器 $redis = new Swoole\Coroutine\Redis(); $redis->connect('127.0.0.1',6379); $value = $redis->get($request->get['a']); $response->header("Content-Type","text/plain"); $response->end($value); }); $http->start(); |
效果:
现在redis中插入一条数据:
然后可以看到: