swoole笔记

发布时间:2020-09-07 00:00:00 阅读:(368)

    swoole

    注意

    在 Swoole 内,无法通过 $_GET/$_POST/$_REQUEST/$_SESSION/$_COOKIE/$_SERVER$_开头的变量获取到任何属性参数。

    快速启动TCP

    实例化server对象,监听端口
    $server = new Swoole\Server('ip_address',port)
    监听事件
    $server -> on('event',function(params){})
    启动服务器
    $server->start()

    快速启动UDP

    实例化server对象
    $server = new Swoole\Server('ip_address',port, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);

    • tips: udp无需链接,直接接收数据包

    快速启动HTTP

    $http = new Swoole\Http\Server('0.0.0.0',port);

    • tips:HTTP 服务器只需要关注请求响应即可
    • tips:使用 Chrome 浏览器访问服务器,会产生额外的一次请求,/favicon.ico,可以在代码中响应 404 错误。
    • tips:应用程序可以根据 $request->server[‘request_uri’] 实现路由。

    快速启动websocket 同tcp

    MQTT(物联网,暂空)

    异步执行任务(Task)

    TCP服务实例

    $serv = new Swoole\Server("127.0.0.1", 9501); //设置异步任务的工作进程数量 
    
    $serv->set(array('task_worker_num' => 4)); //此回调函数在worker进程中执行 
    
    $serv->on('receive', function($serv, $fd, $from_id, $data) { //投递异步任务 
            $task_id = $serv->task($data); 
            echo "Dispatch AsyncTask: id=$task_id\n"; 
        }); //处理异步任务(此回调函数在task进程中执行) 
    
    $serv->on('task', function ($serv, $task_id, $from_id, $data) { 
            echo "New AsyncTask[id=$task_id]".PHP_EOL; //返回任务执行的结果 
            $serv->finish("$data -> OK"); 
        }); //处理异步任务的结果(此回调函数在worker进程中执行) 
    
    $serv->on('finish', function ($serv, $task_id, $data) { 
            echo "AsyncTask[$task_id] Finish: $data".PHP_EOL; 
        }); 
    $serv->start();
    
    • tips:调用 $serv->task() 后,程序立即返回,继续向下执行代码。onTask 回调函数 Task 进程池内被异步执行。执行完成后调用 $serv->finish() 返回结果。

    协程

    go关键词创建一个协程,可以简单的理解为创建了一个线程

    • 什么是协程

    协程可理解为线程,但为用户态,无法使用多核cpu

    • 什么是channel

    消息队列,协程间通讯,但无法跨进程通讯

    • 什么是协程容器

    使用 Coroutine::creatego 方法创建协程,在创建的协程中才能使用协程 API,而协程必须创建在协程容器里面。

    • 协程调度

    决定到底让 CPU 执行哪个协程的代码决断过程就是协程调度

    • 什么是EventLoop

    事件循环,要发生事件的句柄加入到epoll_wait中,epoll_wait 函数返回的时候我们就会挨个调用相应的回调函数,叫做一轮事件循环,即 IO 多路复用,然后再次阻塞调用 epoll_wait 进行下一轮事件循环。

    服务器(异步)

    Swoole\Server 类是所有异步风格服务器的基类

    • 什么是IPC

    同一台主机上两个进程间通信,在 Swoole 下使用了 2 种方式 Unix Socket 和 sysvmsg,主要为Unix Socket方式
    Unix Socket又可分两种,类似TCPUDP

    TCP/UDP服务器
    属性
    • $setting

      Server::set() 函数设置的参数会保存到$server -> $setting 属性上,在回调函数中可以访问运行参数的值

    • $master_pid

    返回当前服务器主进程PID,只能在onStart/onWorkerStart后获取

    • $manager_pid

    返回当前服务器管理进程的PID,只能在onStart/onWorkerStart后获取

    • $workder_id

    得到当前 Worker进程的编号,包括Task进程

    • 提示
    1. 这个属性与onWorkerStart时的 $workerId 是相同的。
    2. Worker 进程编号范围是 [0, $serv->setting['worker_num']-1]
    3. Task 进程编号范围是 [$serv->setting['worker_num'], $serv->setting['worker_num'] + $serv->setting['task_worker_num']]
    4. 工作进程重启后worker_id的值是不变的
    • $worker_pid

    得到当前Worker进程的操作系统进程ID。与posix_getpid()返回值相同

    • $taskwoker

    当前进程是否是Task进程

    • 返回值:
    1. 返回值为true,表示为Task工作进程
    2. 返回值为false,表示为Worker进程
    • $connections

    TCP连接迭代器,可使用foreach遍历服务器当前所有连接,遍历的元素为单个连接的fd

    • tips:$connections是一个迭代器对象,不是php数组,所以只能使用foreach进行遍历操作

    • $ports

    监听端口数组,如果服务器监听了多个端口,可以遍历Server::$ports得到所有Swoole\Server\Port对象

    其中 swoole_server::$ports[0] 为构造方法所设置的主服务器端口。

    方法
    • __construct初始化方法
    • set设置运行时参数
    • on注册事件回调函数
    • addListener增加监听端口(别名listen
    • addProcess增加用户自定义工作进程
    • start启动服务
    • reload重启所有worker/task进程(柔性终止/重启),对自定义工作进程无效
    • stop停止当前woker进程,并立即触发onWorkerStop回调
    • shutdown关闭服务
    • tick添加定时器(间隔时间 毫秒),可自定义回调函数
    • after一次性定时器
    • defer延后执行一个函数
    • clearTimer清除tick/after定时器
    • close关闭客户端连接
    • send向客服端发送数据(有长度限制)
    • sendfile发送文件到TCP客户端连接
    • sendto向任意客户端发送IP:PORT 发送UDP数据包
    • sendwait同步地向客户端发送数据
    • sendMessage向任意worker进程或者task进程发送消息,在飞主进程和管理进程中可调用
    • exist检测fd对应的连接是否存在
    • pause停止接收数据(指定fd
    • resume恢复接收数据
    • getClientInfo获取连接信息
    • getClientList遍历当前server所有客户端连接,基于共享内存
    • bind将连接绑定到一个用户定义的UID
    • stats得到当前server 的活动TCP 连接数,启动时间,accept/close的总次数等信息
    • task投递一个异步任务到task_worker池中,此函数是非阻塞的,执行完毕会立即返回。
    • taskwait同投递一个异步任务到task进程池去执行,但此函数是同步等待,知道任务完成或者超时返回
    • taskWaitMulti并发执行多个task异步任务,不支持协程调度
    • taskCo并发执行task 并进行协程调度,为协程环境下的上个函数的功能
    • finish 用于在task进程中通知worker进程,投递的任务已完成,此函数可传递结果数据给worker进程
    • heartbeat 主动监测服务器所有连接,并找出已经超过约定时间的连接
    • getLastError 获取最近一次操作错误的错误码。业务代码中可以根据错误码类型执行不同逻辑
    • getSocket 得到底层的socket句柄,返回对象为sockets资源句柄
    • protect 设置客户端连接为保护状态,不被心跳线程切断
    • confirm 确认连接。当客户端建立连接后,并不监听可读时间,仅触发onConnect事件回调,在onConnect回调中执行confirm确认连接,这时服务器才会监听可读事件,接收来自客户端连接的数据
    配置
    • reactor_num 设置启动的Reactor线程数
    • woker_num 设置启动的Worker进程数
    • max_request 设置worker进程的最大任务数
    • max_conn 服务器程序,最大允许的连接数
    • task_worker_num 配置task进程的数量(未配置不启动task)
    • task_ipc_mode 设置task进程worker进程之间的通信方式
    • task_max_request 设置task进程的最大任务数(设置 task 进程的最大任务数。一个 task 进程在处理完超过此数值的任务后将自动退出。这个参数是为了防止 PHP 进程内存溢出。如果不希望进程自动退出可以设置为 0。)
    • task_tmpdir 设置task的数据临时目录
    • task_enable_coroutine 开启task协程支持
    • task_use_object 使用面向对象风格的task回调格式
    • dispatch_mode 数据包分发策略
    • dispatch_func 自定义dispatch_mode,使用 c++函数或者php函数
    • message_queue_key 设置消息队列的KEY (仅在 task_ipc_mode = 2/3 时使用)
    • daemonize 守护进程化(设置 daemonize => 1时,程序将转入后台作为守护进程运行。长时间运行的服务器端程序必须启用此项。如果不启用守护进程,当 ssh 终端退出后,程序将被终止运行。)
    • backlog 设置Listen 队列长度,决定最多同时有多少个等待accept的连接
    • log_file 指定Swoole错误日志文件
    • log_level 设置Server错误日志打印的等级,范围是0~6。低于设置的日志信息不会抛出
    事件

    每个回调函数都是一个php函数,对应一个事件

    • onStart 启动后在主进程的主线程回调此函数(此回调中,只允许echo、打印Log、修改进程名称)
    • onShutdown 此事件在Server正常结束时发生(在其中不能调用任何一部或协程相关API)
    • onWorkerStart 在worker进程/ task进程启动时发生,此处创建的对象可在进程生命周期内使用(在onWorkerStart回调函数中会自动创建协程,所以可以调用协程API
    • onWorkerStop 此事件在worker进程终止时发生,在此函数中可以收回woker进程申请的各类资源
    • onWorkerExit
    • onConnect 有新的连接进入时,在worker进程中回调
    • onReceive 接收到数据时回调此函数,发生在worker进程中
    • onPacke 接收到UDP数据包时回调此函数,发生在worker进程中
    • onClose TCP客户端连接关闭后,在worker进程中回调此函数
    • onTask 在task进程内被调用。worker进程可以使用atsk函数向task_worker进程投递新的任务。当前的task进程在调用ontask回调函数时会将进程状态切换为忙碌,这时将不会接收新的task,当ontask函数返回时会将进程状态切换为空闲然后继续接收新的task。
    • onFinish 此回调函数在worker进程被调用,当worker进程投递的任务在task进程中完成时,task进程会通过Swoole\Server->finish()方法将任务处理的结果发送给worker进程
    • onPipeMessage 当工作进程收到由$server->sendMessage()发送的unixSocket消息时会触发onPipeMessage事件。worker/task进程都可能回触发onPipeMessage事件
    • onWorkerErrorwoeker/task 进程发生异常后会在Manager进程内回调此函数
    • onManagerStart 当管理进程启动时触发此事件
    • onManagerStop 当管理进程结束时触发
    • onBeforeReload worker进程 Reload 之前触发此事件,在Manager进程中回调
    • onAfterReload worker进程Reload之后触发此事件,在Manager进程中回调
    事件执行顺序
    • 所有事件回调均在$server->start()后发生
    • 服务器关闭程序终止时最后一次事件是onShutdown
    • 服务器启动成功后,onStart/onManagerStart/onWorkerStart会在不同的进程内并发执行
    • onReceive/onConnect/onClose 在 Worker进程中触发
    • Worker/Task 进程启动、结束时会分别调用一次onWorkerStart/onWorkerStop
    • onTask 事件仅在task进程中发生
    • onFinish 事件仅在 worker 进程中发生
    • onStart/onManagerStart/onWorkerStart 3个事件的执行顺序是不确定的