首页 » SEO优化 » phpissset技巧_phper成长之路swoole进修笔记一

phpissset技巧_phper成长之路swoole进修笔记一

访客 2024-11-21 0

扫一扫用手机浏览

文章目录 [+]

Swoole须要源码安装,目前不支持Windows版本。

官网:http://www.swoole.com/Github:https://github.com/swoolehttps://github.com/matyhtf

源码安装:

phpissset技巧_phper成长之路swoole进修笔记一

wget -O swoole.zip https://github.com/swoole/swoole-src/archive/v1.9.11.zip unzip swoole.zip cd swoole phpize ./configure make && make install

pecl安装:

phpissset技巧_phper成长之路swoole进修笔记一
(图片来自网络侵删)

pecl是须要编译的,以是须要先安装编译器(已安装编译器可以忽略)

yum install -y gcc gcc-c++ make cmake bison autoconf

pecl install swoole pecl install redis

pecl扩展安装完成之后,会提示添加so文件到php.ini

Build process completed successfully Installing '/usr/lib64/php/modules/swoole.so' install ok: channel://pecl.php.net/swoole-1.9.11 configuration option "php_ini" is not set to php.ini location You should add "extension=swoole.so" to php.ini

添加swoole.so文件到php.ini

[swoole] extension = /usr/lib64/php/modules/swoole.so

版本选择:

Swoole版本:稳定版:V1.9.9,预览版:V2.0.7

PHP版本:5.5或更高,7.0.13或更高

把稳:利用TP3.1+框架的朋友升级到PHP7.1.0可能会涌现rewrite失落效问题。
建议PHP7.0.x系列。

快速查看Swoole版本的方法

php --ri swoole

1.8.6~1.8.13 都是小范围BUG修复及功能新增。
个中 1.8.11 增加SIGRTMIN旗子暗记处理函数,用于重新打开日志文件。

1.8.6 版本是一个主要的BUG修复版本,紧张修复了PHP7环境下HttpServer、TCPClient、HttpClient、Redis等客户端存在的内存泄露、崩溃问题。

1.9.0 版本增加了多项新特性,修复了多个已知问题。
1.9版本是100%向下兼容1.8的,用户可无缝升级。

1.9.1 修复PHP7下启用opcache导致崩溃的问题;重构reopen log file特性,收到SIGRTMIN旗子暗记后重新打开日志文件并重定向标准输出 等。

1.9.2 修复PHP7下发生zend_mm_heap corrupted的问题 等。

1.9.4 修复WebSocket做事器默认onRequest方法内存泄露问题 等。

1.9.5 增加pid_file选项,在Server启动时将主进程ID写入指定的文件 等。

1.9.6 修复添加超过1万个以上定时器时发生崩溃的问题;增加swoole_serialize模块,PHP7下高性能序列化库;修复监听UDP端口设置onPacket无效的问题 等。

1.9.9 修复Http2客户端POST数据时协议缺点问题 等。

1.9.11 修复WebSocket做事器onOpen回调函数存在内存泄露的问题;修复Http做事器文件上传在5.6版本发生崩溃的问题;优化添加Task和Timer的定时器性能,提升分支预测成功率 等。

Swoole的进程模块

运行模式

Swoole目前统共有三种运行模式,默认为多进程模式(SWOOLE_PROCESS)。

# Base模式(SWOOLE_BASE)传统的异步非壅塞Server,reactor和worker是同一个角色。
TCP连接是在worker进程中坚持的。
如果客户端连接之间不须要交互,可以利用BASE模式。
如Memcache、Http做事器等。
# 线程模式多线程Worker模式,Reactor线程来处理网络事宜轮询,读取数据。
得到的要求交给Worker线程去处理。
缺陷:一个线程发生内存缺点,全体进程会全部结束。
由于PHP的ZendVM在多线程模式存在内存缺点,多线程模式在v1.6.0版本后已关闭。
# 进程模式与多线程Worker模式不同的是,线程换成了进程。
Reactor线程来处理网络事宜轮询,读取数据。
得到的要求交给Worker进程去处理。
适宜业务逻辑非常繁芜的场景。
如WebSocket做事器等。
$serv = new swoole_server(string $host, int $port, int $mode = SWOOLE_PROCESS, int $sock_type = SWOOLE_SOCK_TCP);

实例剖析

<?php $server = new \swoole_server("127.0.0.1",8088);//默认是多进程模式、TCP类型 $server->on('connect', function ($serv, $fd){ }); $server->on('receive', function ($serv, $fd, $from_id, $data){ }); $server->on('close', function ($serv, $fd){ }); $server -> start();

连续在Shell中输入以下命令:

php swoole_tcp_server.php pstree -ap|grep swoole_tcp_server | | `-php,2454 swoole_tcp_server.php | | |-php,2456 swoole_tcp_server.php | | | `-php,2458 swoole_tcp_server.php

从系统的输出中,我们可以很容看出server实在有3个进程,进程的pid分别是2454、2456、2458,个中2454是2456的父进程,而2456又是2458的父进程。

以是,实在我们虽然看起来只是启动了一个Server,实在末了产生的是三个进程。

这三个进程中,所有进程的根进程(2454),便是所谓的Master进程;而2456进程,则是Manager进程;末了的2458进程,是Worker进程。

基于此,我们大略梳理一下,当实行的start方法之后,发生了什么:

守护进程模式下,当提高程fork出Master进程,然退却撤退出,Master进程触发OnMasterStart事宜。
Master进程启动成功之后,fork出Manager进程,并触发OnManagerStart事宜。
Manager进程启动成功的时候,fork出Worker进程,并触发OnWorkerStart事宜。
非守护进程模式下,则当提高程直接作为Master进程事情。

以是,一个最根本的Swoole Server,至少须要有3个进程,分别是Master进程、Manager进程和Worker进程。

事实上,一个多进程模式下的Swoole Server中,有且只有一个Master进程;有且只有一个Manager进程;却可以有n个Worker进程。

进程模型

Master进程是一个多线程进程,个中有一组非常主要的线程,叫做Reactor线程(组),每当一个客户端连接上做事器的时候,都会由Master进程从已有的Reactor线程中,根据一定规则挑选一个,专门卖力向这个客户端供应坚持链接、处理网络IO与收发数据等做事。
分包拆包等功能也是在这里完成。

Manager进程,某种意义上可以看做一个代理层,它本身并不直接处理业务,其紧张事情是将Master进程中收到的数据转交给Worker进程,或者将Worker进程中希望发给客户真个数据转交给Master进程进行发送。

Manager进程还卖力监控Worker进程,如果Worker进程由于某些意外挂了,Manager进程会重新拉起新的Worker进程,有点像Supervisor的事情。
而这个特性,也是终极实现热重载的核心机制。

Worker进程实在便是处理各种业务事情的进程,Manager将数据包转交给Worker进程,然后Worker进程进行详细的处理,并根据实际情形将结果反馈给客户端。

我们可以总结出来上面大略的Server,当客户端连接的时候这个过程中,三种进程之间是怎么协作的:

Client主动Connect的时候,Client实际上是与Master进程中的某个Reactor线程发生了连接。
当TCP的三次握手成功了往后,由这个Reactor线程将连接成功的见告Manager进程,再由Manager进程转交给Worker进程。
在这个Worker进程中触发了OnConnect的方法。
当Client向Server发送了一个数据包的时候,首先收到数据包的是Reactor线程,同时Reactor线程会完成组包,再将组好的包交给Manager进程,由Manager进程转交给Worker。
此时Worker进程触发OnReceive事宜。
如果在Worker进程中做了什么处理,然后再用Send方法将数据发回给客户端时,数据则会沿着这个路径逆流而上。

Swoole进程/线程构造图

现在,我们基于上面的例子修正代码,来看看一个大略的多进程Swoole Server的几个基本配置:

<?php $server->set(array( 'demonize' => false,//是否后台运行 'reactor_num' => 2, 'worker_num' => 4 ));$server -> start();

reactor_num:表示Master进程中,Reactor线程统共开多少个,把稳,这个可不是越多越好,由于打算机的CPU是有限的,以是一样平常设置为与CPU核心数量相同,或者两倍即可。

worker_num:表示启动多少个Worker进程,同样,Worker进程数量不是越多越好,仍旧设置为与CPU核心数量相同,或者两倍即可。

我们可以在Shell里运行,利用pstree查看进程模型构造:

php swoole_tcp_server.php pstree -ap|grep swoole_tcp | | `-php,2505 swoole_tcp_server.php | | |-php,2507 swoole_tcp_server.php | | | |-php,2510 swoole_tcp_server.php | | | |-php,2511 swoole_tcp_server.php | | | |-php,2512 swoole_tcp_server.php | | | `-php,2513 swoole_tcp_server.php

回调函数

Swoole作为Server时,回调函数有很多。
但可以大略分个类:

进程启动时实行的:onStart、onManagerStart、onWorkerStart;onWorkerStop、onManagerStop、onShutdown;onWorkerError客户端交互时触发的:onReceive/onRequest/onPacket/onMessage、onOpen/onConnect、onCloseTask:onTask、onFinishTimer:onTimer

事宜实行顺序:

所有事宜回调均在$server->start后发生做事器关闭程序终止时末了一次事宜是onShutdown做事器启动成功后,onStart/onManagerStart/onWorkerStart会在不同的进程内并发实行。
onReceive/onConnect/onClose/onTimer在worker进程(包括task进程)中各自触发worker/task进程启动/结束时会分别调用onWorkerStart/onWorkerStoponTask事宜仅在task进程中发生onFinish事宜仅在worker进程中发生onStart/onManagerStart/onWorkerStart 3个事宜的实行顺序是不愿定的UDP协议下只有onReceive事宜,没有onConnect/onClose事宜如果未设置onPacket回调函数,收到UDP数据包默认会回调onReceive函数onOpen事宜回调是可选的:当WebSocket客户端与做事器建立连接并完成握手后会回调此函数

实际利用的时候不是所有回调都可以利用的,例如UDP做事器没有onConnect/onClose;例如吸收数据,在WebSocket里利用onReceive,在HttpServer利用onRequest,在UDPServer利用onPacket。

<?php $server = new \swoole_server("127.0.0.1",8088); $server->set( array( 'daemonize' => false, 'reactor_num' => 2, 'worker_num' => 4 )); $server->on('connect', function ($serv, $fd){ echo "client connect. fd is {$fd}\n"; }); $server->on('receive', function ($serv, $fd, $from_id, $data){ echo "client connect. fd is {$fd}\n"; }); $server->on('close', function ($serv, $fd){ echo "client close. fd is {$fd}\n"; }); // 以下回调发生在Master进程 $server->on("start", function (\swoole_server $server){ echo "On master start.\n"; }); $server->on('shutdown', function (\swoole_server $server){ echo "On master shutdown.\n"; }); // 以下回调发生在Manager进程 $server->on('ManagerStart', function (\swoole_server $server){ echo "On manager start.\n"; }); $server->on('ManagerStop', function (\swoole_server $server){ echo "On manager stop.\n"; }); // 以下回调也发生在Worker进程 $server->on('WorkerStart', function (\swoole_server $server, $worker_id){ echo "Worker start\n"; }); $server->on('WorkerStop', function(\swoole_server $server, $worker_id){ echo "Worker stop\n"; }); $server->on('WorkerError', function(\swoole_server $server, $worker_id, $worker_pid, $exit_code){ echo "Worker error\n"; }); $server -> start();不要在代码中实行sleep以及其他就寝函数,这样会导致全体进程壅塞exit/die是危险的,会导致worker进程退出可通过register_shutdown_function来捕获致命缺点,在进程非常退出时做一些要求事情,详细参看/wiki/page/305.htmlPHP代码中如果有非常抛出,必须在回调函数中进行try/catch捕获非常,否则会导致事情进程退出swoole不支持set_exception_handler,必须利用try/catch办法处理非常Worker进程不得共用同一个Redis或MySQL等网络做事客户端,Redis/MySQL创建连接的干系代码可以放到onWorkerStart回调函数中。
缘故原由是如果共用1个连接,那么返回的结果无法担保被哪个进程处理。
持有连接的进程理论上都可以对这个连接进行读写,这样数据就发生错乱了。
详细参考/wiki/page/325.html不能利用类的属性保存客户端连接信息,由于一个worker进程可以处理多个客户端连接,导致类属性数据错乱。
常量则是可以的。

标签:

相关文章

九游安装指南,轻松上手,畅享游戏乐趣

随着科技的发展,游戏已经成为人们生活中不可或缺的一部分。而九游作为一款集众多热门游戏于一体的平台,深受广大玩家喜爱。今天,就为大家...

SEO优化 2025-01-01 阅读0 评论0

六角星的绘制艺术,从原理到方法

六角星,又称六芒星,是一种古老的符号,具有丰富的文化内涵。在绘画艺术中,六角星以其独特的形状和美感,成为众多艺术家笔下的宠儿。本文...

SEO优化 2025-01-01 阅读0 评论0

六爻排盘,古老智慧的占卜艺术

六爻,又称易经八卦,是我国古代一部博大精深的占卜哲学。它以阴阳五行为基础,通过八卦的排列组合,预测未来、指导人生。本文将为大家详细...

SEO优化 2025-01-01 阅读0 评论0