Swoole Php 高性能服务器框架

创作人 Leo


编辑时间 Wed Jan 1,2020 at 10:13


简介

swoole 是一款高性能的php网络框架

异步任务

高性能tcp/udp服务器

websocket服务器

swoole屏蔽了网络通信io处理、进程/线程/io复用的管理等复杂问题,使开发者可以专注业务逻辑

swoole的服务端程序运行在命令行,异步任务需要配置几个worker,worker根据具体业务需要配置

配置的过小会导致单个worker子进程压力过大,配置太多会导致系统资源不够用,一般建议配置设置为cpu的1-4倍

安装

官网地址 http://www.swoole.com/

安装

swoole是以php扩展的形式安装

 phpize
 ./configure
 make
 make install

为什么配置与CPU有关?这里涉及到计算机多任务处理的一个知识:

一个cpu的一个线程在一个时钟频率下只能处理一条指令

我们眼睛看到的系统同时处理多个程序,实际上是cpu在不停的切换进程上下文做到的

在io密集型程序中(比如web应用程序)

由于cpu计算的很快,但是io特别慢(不是一个数量级),所以cpu大部分时间都是闲置的

在很早以前,人们使用多线程/多进程的方式处理异步io,也就是当一个io事件(比如accept/recv)来到,系统不得不单独开一个进程/线程来处理

由于进程/线程不能开的太多(超级占资源),所以cpu会有大量闲置时间

io复用完美解决了这个问题,以最差的select为例(早期的Apache使用这个东西,而nginx使用epoll,瞬间秒杀apache好几条街,不知道它们之间区别的自行百度)

单个select可以同时监听最多1024个文件描述符,我们给每一个进程/线程配置一个select,如果是10个进程/线程,就可以同时监听10240个文件描述符

比如实时聊天系统,mmorpg游戏,每一个文件描述符,实际上就是一个持续在线的用户,那我单台服务器就可以支持同时万人在线

swoole内部使用reactor模型,实现方式是io复用,也就是一个worker进程维护多个event loop

当一个io事件到达,对应的端口去接收,这时候cpu可以继续处理其他指令,而不需要等待io操作完成

著名的高性能web服务器 nginx 也是同理

例:SWOOLE实现异步任务处理

AsyncServer.php

<?php
/**
 * 异步任务测试
 */
date_default_timezone_set('Asia/Chongqing');
class TaskManager{
    public static $inst = null ;
    private $db = null;
 
    private function __construct(){
        $pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'lixinxin');
        $this->db = $pdo ;
    }
 
    private function __clone(){
 
    }
 
    public static function getInst(){
 
        if (self::$inst==null && !(self::$inst instanceof self) ){
            self::$inst = new self() ;
        }
 
        return self::$inst ;
    }
 
 
    public function processTask($jsonData){
        $taskData = json_decode($jsonData, true) ;
 
        $ret = 'err' ;
 
        switch ($taskData['taskid']){
            case 1:
                //sendmsg
                //
                //echo 'send msg task is invoked ' , PHP_EOL ;
                //file_put_contents('/tmp/swoole_test.txt', date('Y-m-d H:i:s').'send msg task is invoked ' . PHP_EOL, FILE_APPEND) ;
                $ret = date('Y-m-d H:i:s').'send msg task is invoked ' ;
                break;
            case 2:
                $save = $taskData['data'];
                $sql = "insert into user(account, pwd, nickname, school) values('{$save['account']}','{$save['pwd']}','{$save['nickname']}','{$save['school']}')" ;
                $this->db->query($sql) ;
 
                $ret = date('Y-m-d H:i:s').'save data task is invoked ' ;
                break;
            default:
                //echo 'unknow task id ' , PHP_EOL ;
                break;
        }
 
        return $ret . PHP_EOL;
    }
 
 
}
 
 
$serv = new swoole_server("127.0.0.1", 9501);
 
$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'lixinxin');
 
//设置异步任务的工作进程数量
$serv->set(array(
    'task_worker_num' => 10 ,
    'user' => 'lixin',
    ));
 
$serv->on('receive', function($serv, $fd, $from_id, $data) {
    //投递异步任务
    $task_id = $serv->task($data);
    echo "Dispath AsyncTask: id=$task_id
";
});
 
//处理异步任务
$serv->on('task', function ($serv, $task_id, $from_id, $data) {
    echo "New AsyncTask[id=$task_id]".PHP_EOL;
    //返回任务执行的结果
 
    $ret = TaskManager::getInst()->processTask($data) ;
 
    $serv->finish($ret);
});
 
//处理异步任务的结果
$serv->on('finish', function ($serv, $task_id, $data) {
    //echo "AsyncTask[$task_id] Finish: $data".PHP_EOL;
    file_put_contents('/tmp/swoole_test.txt', $data, FILE_APPEND) ;
 
});
 
$serv->start();

AsyncClient.php

<?php
/**
 * 异步任务测试,客户端程序
 */
 
$taskData = [
    'taskid' => '2' ,
    'data' => [
        'account' => 'lixinxi',
        'pwd' => rand() ,
        'nickname' => 'lalal',
        'school' => rand().' schoole'
    ]
] ;
 
 
$fd = fsockopen('127.0.0.1', 9501);
fwrite($fd, json_encode($taskData)) ;
fclose($fd);

阅读:1178
搜索
  • Linux 高性能网络编程库 Libevent 简介和示例 2578
  • web rtc 学习笔记(一) 2354
  • Mac系统编译PHP7【20190929更新】 2304
  • react 学习笔记(一) 2244
  • zksync 和 layer2 2237
  • Hadoop 高可用集群搭建 (Hadoop HA) 2182
  • Hadoop Map Reduce 案例:好友推荐 2151
  • 小白鼠问题 2085
  • Linux 常用命令 2082
  • 安徽黄山游 2058
简介
不定期分享软件开发经验,生活经验