Swoole介绍

  swoole是由c语言开发的异步网络通信引擎,被编译为so文件(swoole.so)作为php的extesion扩展。

  与其他普通扩展不同:

    与普通的扩展不同的是普通的扩展只是提供一个库函数。而swoole扩展在运行后会接管PHP的控制权,进入事件循环。当IO事件发生后,swoole会自动回调指定的PHP函数。  

  高性能:

    swoole使用原生c语言编写,swoole相比apache/fpm,可以常驻内存,主要是节省PHP框架和全局对象每次请求创建销毁带来的性能损耗,提升性能。

  官网 :https://www.swoole.com/

  官网手册:https://wiki.swoole.com/wiki/page/1.html

  php官方手册 :https://www.php.net/manual/zh/book.swoole.php

   swoole源码:https://github.com/swoole/swoole-src

  来自官网的介绍

  

  可以看出Swoole可以支持高并发。在看看Swoole的特性

  

Swoole架构

  

                    swoole架构图

  架构说明:

    1. Master进程:是Swoole的主进程, Master里面包含了很多Reactor线程,主要基于Reactor模式用于处理客户端的请求,swoole对于事件的监听都是在这些线程中实现,也包括对信号的处理。

     Master进程里包含一些线程,比如主线程和Reactor线程组等。

      1)主线程(MainReactor)负责监听等待客户端的socket连接,如果有新的连接accept,主线程会根据Reactor线程连接的数量来评估,将新的连接分配给连接数量最少的reactor线程。

      2)Reactor线程组负责维持与客户端TCP连接,处理网络IO,异步非阻塞的去收发数据等。Reactor线程在socket可读的时候进行协议解析,将请求投递到worker进程,在socket可写时候将数据发送给客户端。

      3)心跳包检测线程(HeartbeatCheck)

      4)UDP收包线程(UDPRecv)。

      
    2.Manger进程:管理进程。位于Worker进程和Task进程的上层,负责对工作进程的创建及管理,当工作进程由于程序原因异常退出或者被误杀,容易产生僵尸进程,为了保证服务的稳定性,Manger进程会监视工作进程的事件,必要的时候Manger进程重新创建工作进程或者回收。  
    3.Worker进程:工作进程,负责业务处理。接受Reactor线程的投递请求数据包,并执行PHP回调函数处理数据,worker处理完毕后,通过进程间的通信(比如管道,共享内存,消息队列)生成响应数据返回给Reactor线程。
    4.Task进程:异步耗时任务工作进程。

  一个请求经历的生命周期如下:

    1. Swoole服务器主线程(Master)等待客户端连接请求。
    2. Reactor线程处理接连socket,读取socket上的请求数据(Receive),将请求封装好后投递给Work进程。
    3. Work进程就是逻辑单元,处理业务数据。
    4. Work进程结果返回给Reactor线程。
    5. Reactor线程将结果返回socket,然后在返回给客户端。

Swoole运行模式

  Swoole最大特点是在于多线程Reactor模式处理网络请求,使其能够面对高并发的大量连接请求。进程常驻内存,程序启动运行只加载一次PHP文件,避免重复加载。全异步非阻塞,占用资源小,使用协程程序执行效率高。解决了传统PHP开发模式的痛点。  

Swoole热重启

  swoole启动之后只需要加载初始化一次php文件,但是这个也导致一些问题,当修改php文件后不能像传统那样马上就能获取修改后的效果,而是需要先关闭swoole服务然后在重新启动,这样才能重新加载修改后的php代码,但是这样显然是不能接受的,当然swoole已经考虑到这点并提供了解决这样问题的功能。

  在swoole中可以向主进程发送各种不同信号,主进程根据接收到的信号作出不同的处理。

传统php-fpm模式和Swoole的区别

  1.  php-fpm模式是一个进程池架构的Fastcgi服务,Master 主进程 / Worker 多进程工作模式,每次每个Worker 进程只能接受一个请求,当PHP代码执行完毕,会释放所有的资源(包括初始化一系列的对象,环境设置),下一次请求需要重新再进行初始化等各种繁琐的操作,消耗很多cpu等资源。

  2. Swoole也是采用的也是 Master/Worker 模式,不同的是 Master 进程有多个 Reactor 线程,Master 只是一个事件发生器,负责监听 Socket 句柄的事件变化。Worker 以多进程的方式运行,接收来自 Reactor 线程的请求,并执行回调函数(PHP 编写)。

  3. 高并发情况下fpm模式容易502,服务压力大时,worker不够用就会不可响应或响应不过来。如果通过开启多个worker进程会占用大量内存,对服务器压力也很大。

Swoole生命周期

  

Swoole使用注意事项

   1. 相比传统PHP,更难于上手,需要一点学习成本。

   2. 因为是常驻内存,更容易内存泄漏,在处理全局变量,静态变量的时候需要注意,这些是不会被GC清理的变量会存在整个生命周期里,如果不稍加注意这些变量会很容易消耗完内存。修改代码不会马上起作用,需要热更新或者重启。

    

Swoole安装

  安装环境要求 

  安装前必须保证系统已经安装了下列软件
  php-7.1 或更高版本
  gcc-4.8 或更高版本
make
autoconf

  1.swoole源码获取并安装

songguojundeMBP:src songguojun$ git clone https://gitee.com/swoole/swoole.git

songguojundeMBP:src songguojun$ ll
total
drwxr-xr-x songguojun wheel : ./
drwxr-xr-x root wheel : ../
drwxr-xr-x songguojun wheel : swoole/ 没有configure文件 那么就需要通过phpize文件去生成configure文件

执行phpize命令

songguojundeMBP:swoole songguojun$ /usr/local/src/php7/bin/phpize
Configuring for:
PHP Api Version:
Zend Module Api No:
Zend Extension Api No:
songguojundeMBP:swoole songguojun$ ls config* #执行完毕后目录下吗多了很多文件 比如configure
config.guess config.h.in config.m4 config.sub configure configure.ac

注意上面phpize命令要在swoole目录下执行,不然会报错

查看configure增加了swoole选项,可以根据你的需要来决定是否开启

songguojundeMBP:swoole songguojun$ ./configure --help | grep swoole
--enable-debug-log Enable swoole debug log
--enable-trace-log Enable swoole trace log
--enable-swoole Enable swoole support

2.执行configure

songguojundeMBP:swoole songguojun$ ./configure --with-php-config=/usr/local/src/php7/bin/php-config  #这里指定具体的php配置目录,因为我本地环境有多个php版本

3.执行make

songguojundeMBP:swoole songguojun$ make && make install          

........

Build complete.
Don't forget to run 'make test'. Installing shared extensions: /usr/local/src/php7/lib/php/extensions/no-debug-non-zts-/ #这里提示swoole扩展安装到这个目录下了
Installing header files: /usr/local/src/php7/include/php/
songguojundeMBP:swoole songguojun$ cd /usr/local/src/php7/lib/php/extensions/no-debug-non-zts-/
songguojundeMBP:no-debug-non-zts- songguojun$ ll
total
drwxr-xr-x songguojun wheel : ./
drwxr-xr-x songguojun wheel : ../
-rwxr-xr-x songguojun wheel : opcache.a*
-rwxr-xr-x songguojun wheel : opcache.so*
-rwxr-xr-x songguojun wheel : swoole.so* <- 进入扩展目录发现swoole.so文件已经生成

examples目录下提供了很多demo文件,我们进入examples/server目录

songguojundeMBP:server songguojun$ pwd
/usr/local/src/swoole/examples/server
songguojundeMBP:server songguojun$ ls
dispatch_func.php getReceivedTime.php pipe_message.php uid_dispatch.php
dispatch_stream.php ip_dispatch.php reload_aysnc.php unix_stream.php
echo.php listen_1k_port.php reload_force.php zmq.php
exist.php local_listener.php reload_force2.php
fixed_header_client.php manager_timer.php single.php
fixed_header_server.php multi_instance.php trace.php

查看其中echo.php文件

$serv = new swoole_server("0.0.0.0", 9501);
$serv->set(array(
'worker_num' => 1,
));
$serv->on('receive', function (swoole_server $serv, $fd, $reactor_id, $data) {
echo "[#".$serv->worker_id."]\tClient[$fd] receive data: $data\n";
if ($serv->send($fd, "hello {$data}\n") == false)
{
echo "error\n";
} });
$serv->start();

我们执行下,发现会报错,提示缺少swoole_server类,这是因为目前php还没办法使用到swoole类库。要是用swoole的类库必须要在php.ini配置文件中打开

查看下php.ini文件路径

songguojundeMBP:server songguojun$ php -i | grep php.ini
Configuration File (php.ini) Path => /usr/local/src/php7/lib

由于我是Mac系统,php.ini文件在/private/etc/目录下,/private/etc/php.ini 如果没有这个文件,将这个目录下的php.ini.default复制一份重命名为php.ini,然后在该文件中添加swoole扩展。

添加完毕之后在将 /private/etc/php.ini文件复制到/usr/local/src/php7/lib目录下

cp /private/etc/php.ini /usr/local/src/php7/lib/php.ini

然后在查看swoole扩展是否存在

然后在执行刚刚上面echo.php文件看是否成执行成功。

发现没有报错了,而且通过命令发现正在监听9501端口

songguojundeMBP:server songguojun$ lsof -i :
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php songguojun 3u IPv4 0xd405c2bd609771f 0t0 TCP *: (LISTEN)
telnet songguojun 3u IPv4 0xd405c2bdf381d9f 0t0 TCP localhost:->localhost: (ESTABLISHED)
songguojundeMBP:server songguojun$ kill -9 3142   #杀掉进程
songguojundeMBP:server songguojun$ lsof -i :

查看Swoole版本

 启动TCP服务

tcp.php

//创建Server对象,监听 127.0.0.1:9501端口
$serv = new Swoole\Server("127.0.0.1", 9501);
//设置基本参数
$serv->set([
'worker_num' => 8, //worker进程数 建议设置cpu核数1-4倍
'max_request' => 10000,
]);
/*
* 监听连接进入事件
* $fd是客户端连接的唯一标识
* $reactor_id 线程id
*/
$serv->on('Connect', function ($serv, $fd, $reactor_id) {
echo "Client: {$fd} Connect.\n";
});
//监听客户端数据接收事件
$serv->on('Receive', function ($serv, $fd, $reactor_id, $data) {
//向客户端发送数据
$serv->send($fd, "Server: ".$data);
});
//监听连接关闭事件
$serv->on('Close', function ($serv, $fd) {
echo "Client: Close.\n";
});
//启动服务器
$serv->start();

 Swoole进程管理

  Swoole 提供的进程管理模块,用来替代 PHP的pcntl扩展。

  Swoole里进程与进程之间的通信是通过管道来进行的。

  在Swoole里使用多进程比原生php多进程更加容易。我们可以使用多进程来处理许多耗时的场景,比如curl获取多个页面内容。

  echo "脚本开始".date("Y-m-d H:i:s");
$urlsArr = [
"http://www.baidu.com",
"http://www.qq.com",
"http://www.sina.com.cn",
"http://www.sohu.com",
"http://www.hao123.com",
"http://www.cnblogs.com"
];
$workers = [];
for ($i = 0; $i < 6; $i++) {
//创建子进程
$childProcess = new swoole_process(function(swoole_process $worker) use ($i, $urlsArr) {
$content = curlData($urlsArr[$i]);
$worker->write($content); // 将内容写入到管道中
}, true); //true表示不打印输出的内容
$pid = $childProcess->start();
$worker[$pid] = $childProcess;
} //模拟请求
function curlData($url){
sleep(2);
return "handle ".$url." finished";
}
//输出进程管道中数据结果
foreach ($worker as $process){
echo $process->read().PHP_EOL;
}
echo "脚本结束".date("Y-m-d H:i:s");

执行结果 总耗时也就1秒多点。

songguojundeMacBook-Pro:swoole songguojun$ php process.php
脚本开始2020-- ::19
handle http://www.baidu.com finished
handle http://www.qq.com finished
handle http://www.sina.com.cn finished
handle http://www.sohu.com finished
handle http://www.hao123.com finished
handle http://www.cnblogs.com finished 脚本结束2020-- ::

 Swoole内存模块

  swoole提供了几个内存操作模块

    1. Lock。

    2. Buffer。

    3. Table。

    4. Atomic。

    5. mmap。

    6. channel。

    7. serialize。

  我们看下swoole里的table。

  swoole_table是一个基于共享内存和锁实现的高性能,高并发数据结构。可以利用swoole_table在内存中申请一块内存空间。

Swoole协程

  swoole另一个特性就是提供了协程,协程可以认为是用户态的线程,是通过协作而非抢占式来进行切换,所有的调度都是在用户态中进行,创建和消耗非常低。

参考资料:

  https://www.w3cschool.cn/swoole/npai1qc9.html

【php】Swoole之php高性能通信框架的更多相关文章

  1. 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.1

    HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...

  2. 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.2

    HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...

  3. 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.0.1

    HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...

  4. 高性能 TCP & UDP 通信框架 HP-Socket v3.5.3

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

  5. 高性能 TCP & UDP 通信框架 HP-Socket v3.5.2

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

  6. 高性能 TCP & UDP 通信框架 HP-Socket v3.5.1

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

  7. 高性能 TCP & UDP 通信框架 HP-Socket v3.4.1

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

  8. 高性能 TCP & UDP 通信框架 HP-Socket v3.3.1

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

  9. 高性能 TCP & UDP 通信框架 HP-Socket v3.2.3

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

随机推荐

  1. 8051单片机中访问int中字节的方法

    在使用单片机中,unsigned int 占2个字节,unsigned char 占一个字节.而单片机是实行的字节寻址.16字节的bit寻址实在是不好用, 不好用在不能建数组. 在实际的开发过程中,要 ...

  2. 新闻网大数据实时分析可视化系统项目——17、Spark2.X分布式弹性数据集

    1.三大弹性数据集介绍 1)概念 2)优缺点对比 2.Spark RDD概述与创建方式 1)概述 在集群背后,有一个非常重要的分布式数据架构,即弹性分布式数据集(resilientdistribute ...

  3. 第1课 VMware的NSX全面落地软件定义网络SDN

    SDN的定义: 即软件定义网络(Software Defined Network)的缩写,它是一种基于网络架构的创新,一种在已存在物理传输网络之上的抽象形态,它是一种体系结构,它是众多网络虚拟化技术中 ...

  4. express 配置 https 服务 ( 以阿里云服务器为例), 探索一周终于搞定

    首先最重要的是 你要明白 https接口的接收或者发送 的形式 是  https://域名:端口号   而不是 https://ip:端口号   一,首先,去阿里云注册免费ssl证书   1,在搜索框 ...

  5. vue table已选列数据

    vue Table@on-selection-change="test" 已选中项数据 test(selection){} <Table :data="tableD ...

  6. R 对数变换 《回归分析与线性统计模型》page103

    BG:在box-cox变换中,当λ = 0时即为对数变换. 当所分析变量的标准差相对于均值而言比较大时,这种变换特别有用.对数据作对数变换常常起到降低数据波动性和减少不对称性的作用..这一变换也能有效 ...

  7. MinGW下编译curl-7.60.0时, 发生ERROR_FILE_NOT_FOUND undeclared

    在编译curl-7.60.0时, 遇到ERROR_FILE_NOT_FOUND undeclared 这个情况, 就没法编译成功!! 下载了以往的版本, 发现是从curl-7.59.0版本开始才有 t ...

  8. Spring的AOP开发(基于ApsectJ的注解)

    创建项目,导包 编写目标类并配置 创建OrderDao package com.rick.aop.demo1; public class OrderDao { public void save() { ...

  9. getchar、scanf以及缓冲区的概念

      1.getchar()是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,也就是说,如果stdin有数据的话不用输入它就可以直接读取了.       getch()和getche( ...

  10. 侯捷C++学习(二)

    #include <iostream>using namespace std;class complex{ public: complex (double r= 0, double i = ...