Skip to content

swoole

文档

使用swoole需要注意的

扩展冲突(phptrace,aop,molten,xhprof,phalcon)
不要使用sleep/usleep.会使整个进程阻塞(Swoole\Timer::after()等);协程中用Co::sleep或hook后的sleep;
不要使用exit/die;worker进程会不断退出启动。
有异常必须用try/catch捕捉(不支持set_exception_handler),否则退出工作进程;
多个worker不能连同一个mysql或redis连接,会导致混乱;
并发编程,协程上下文;
常驻内存,不能重复定义function,类,请用include_once和require_once
尽量使用局部变量,会回收;非局部变量global ,static $_GET等不会回收,一直追加可能造成内存泄露和溢出;(可max_request,task_worker_request worker进程task进程,运行次次数上限后自动退出,然后释放掉;onclose事件或定时器用unset清理)
禁止使用$_GET/$_POST/$_REQUEST/$_SESSION/$_COOKIE/$_SERVER,等全局变量;
进程隔离,一个进程修改某个值,其他进程是无法获取的;用 \swoole\table,Swoole\Atomic(原子计数),redis等来替代
父进程mt_rand,导致子进程的值一样,用mt_srand重新播种
__get 和 __set 魔术方法里,不得产生协程切换;因为下次调用会被判定为循环调用(php底层)

swoole内存泄露的原因?

请勿在 onReceive 等回调函数中创建锁,否则内存会持续增长,造成内存泄漏。
不要循环创建 / 销毁锁的对象,否则会发生内存泄漏。
必须在 socket 的 close 操作前使用 Event::del 移除事件监听,否则可能会产生内存泄漏
在事件回调函数中需要特别注意非局部变量的 array 类型值,某些操作如 TestClass::$array[] = "string" 可能会造成内存泄漏,严重时可能发生内存溢出,必要时应当注意清理大数组。
在事件回调函数中,非局部变量的字符串进行拼接操作是必须小心内存泄漏,如 TestClass::$string .= $data,可能会有内存泄漏,严重时可能发生内存溢出。

swoole 内存溢出

在事件回调函数中需要特别注意非局部变量的 array 类型值,某些操作如 TestClass::$array[] = "string" 可能会造成内存泄漏,严重时可能发生内存溢出,必要时应当注意清理大数组。
在事件回调函数中,非局部变量的字符串进行拼接操作是必须小心内存泄漏,如 TestClass::$string .= $data,可能会有内存泄漏,严重时可能发生内存溢出

task_max_request(默认为0不退出),设置之后处理完超过此数值就自动退出

swoole的协程

可以理解为用户态的线程,不需要系统参与,创建和销毁成本更低,不同的是不能用多核cpu,要用需使用swoole多进程

请说明socket监听端口9502在内存中大小端的layout

进程,多线程,协程的区别

  • 进程:进程是操作系统进行资源分配和调度的基本单位,是程序的实体。每个进程都有自己的独立地址空间和系统资源。进程之间不共享全局变量,因此,多进程程序的安全性较高,但资源开销较大。
  • 多线程:线程是程序执行中的一个单一的顺序控制流程,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,同一进程中的多个线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈和线程本地存储。由于线程之间能够共享地址空间,因此,需要考虑同步和互斥操作。一个线程的意外终止会影响整个进程的正常运行。
  • 协程:协程是存在于单个线程中的不同执行流,通过显式调用进行切换来实现非阻塞的异步操作,同时共享相同的数据空间。协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。协程的切换是由程序自身控制的,而不是像线程那样由操作系统进行调度,因此效率更高。 总的来说,多进程程序安全性高,进程切换开销大,效率低;多线程程序维护成本高,线程切换开销小,效率高;协程则是异步的,切换开销极小,效率极高。希望这个解答能帮助你理解这三者的区别。

是否有向静态属性,静态变量,全局变量追加数据,use &$变量
扩展在fpm没问题,在cli可能就有问题
有钱用Swoole Tracker
请求周期(onrequest等)内对全局对象赋值,并且请求结束后没有释放
new 类,方法启用swoole服务,无法释放 那个类
1.global 2.类的静态熟悉 3.函数的静态变量 4.无法结束的函数的局部变量

在linux下启动swoole配置daemonize和不配做daemonize时有什么区别?不配置时为什么ctrl+c就退出了?

swoole的http/websocket协议的实现原理是什么?给出伪代码

swoole的Event事件的工作原理

伪代码说明swoole协程切换的原理

请简述协程工作机制和协程栈空间地址变化

websocket拒绝服务攻击?

swoole进程间的通信方式?还有哪些通信方式?

管道(pipe) 命名管道(named pipe)
消息队列(message queue) useQueue() 后 push pop
共享内存(shared memory) 用swoole\table或redis等
套字节(socket,unixsock) 使用 Process::exportSocket() send() recv()
信号量() Swoole\Process::kill(int $pid, int $signo = SIGTERM): bool
文件映射(memory-mapped file)
文档

常驻进程,mysql超时如何处理?

1.重试 2.定时发送心跳维持连接 $server->set([ 'open_tcp_keepalive' => true,//启用 TCP keepalive 'tcp_keepidle' => 4, //4s没有数据传输就进行检测 'tcp_keepinterval' => 1, //1s探测一次 'tcp_keepcount' => 5, //探测的次数,超过5次后还没回包close此连接 'heartbeat_idle_time' => 600, // 表示一个连接如果600秒内未向服务器发送任何数据,此连接将被强制关闭 'heartbeat_check_interval' => 60, // 启用心跳检测,连接最大允许空闲的时间,表示每60秒遍历一次 ]);