温故而知新,PHP Swoole使用过程中的一些思考

简介: 本文回顾了异步任务处理、进程与协程调度机制、Redis与消息队列的应用、Swoole协程原理等内容,探讨了CPU时间片分配、IO阻塞、协程切换等关键技术问题,适用于高并发场景下的性能优化与系统设计。

原文:https://nicen.cn/8341.html

温故而知新

今天突然发现很多以前理解过的概念,再次回顾的时候感觉有点模糊了,翻了翻笔记又有了一些新的理解。

1.场景

  • 简单的异步任务执行可以直接通过管道向子进程投递异步任务,然后触发事件执行任务。
  • Redis的订阅与发布也可以实现上述的功能,但它的优势在于它可以一对多,PUBLISH之后可以同时触发多个订阅的事件,并且可以在任意进程内进行订阅。
  • 专门的消息队列组件,则适用于对消息队列要求比较高的场景(消息确认、消费者组等)


在大多数操作系统中,父进程和子进程通常被分配相同的 CPU 时间片。时间片是操作系统用来调度进程的一种机制,它将 CPU 时间划分为较小的块,并按照某种策略分配给不同的进程。每个进程被分配一个时间片,在该时间片结束后,操作系统会剥夺该进程的 CPU 使用权,并将其分配给其他进程。所以多进程程序获得的CPU时间片比单进程程序多。


为什么不使用管道作为消息队列的通信接口,而是使用Redis List?


处理异步事件的时候,假设只有一个子进程,可以直接使用管理进行通信,然后触发事件。但是一个进程的处理能力是有限的,所以我们往往需要多个进程同时处理异步任务。多个进程同时读取Redis队列时,由于Redis的单线程模型,所以只有一个进程会拿到这个消息

2.问题

  • Mysql一个链接的内存占用?(PHP协程创建了100个不进行操作的连接,占用内存7.8m)
  • 主从复制,数据同步延时的问题?
  • 数据量过大时,避免使用join,通过协程并发查询?
  • 将单个查询分解成多个查询,通过协程并发查询?
  • 读是共享锁,写是排它锁,考虑读写分离?
  • 创建协程,单个协程需要的内存大小(底层默认分配2M(C)虚拟内存+8K(PHP)内存(PHP-7.2或更高版本)。这里的虚拟内存是指操作系统并不会立即分配2M物理内存,系统会根据在内存实际读写时发生缺页中断,再分配实际内存)?
  • 测压过程中如何一步步排查问题所在?
  • 自定义进程的数量,消费者消费的速度、消费者被阻塞的时长?
  • 索引降维和连接池预热?
  • 数据量过大时,直接分库,通过封装中间层,来实现现有业务的无缝迁移。
  • 多个进程分配到的时间片会更多,通过多进程处理异步任务。多进程封装成一个进程组,然后通过原子计数器将任务平均派发到每一个进程。
  • 协程机制的优点之一就是有阻塞就会自动处理别的任务,比如Mysql被阻塞就去处理Redis读取,Redis被阻塞就去Mysql;

3.Swoole协程

  • 协程没有IO等待 正常执行PHP代码,不会产生执行流程切换
  • 协程遇到IO等待 立即将控制权切,待IO完成后,重新将执行流切回原来协程切出的点
  • 协程并行协程依次执行,同上一个逻辑
  • 协程嵌套执行流程由外向内逐层进入,直到发生IO,然后切到外层协程,父协程不会等待子协程结束
  • Swoole的协程在底层实现上是单线程的,因此同一时间只有一个协程在工作,协程的执行是串行的。这与线程不同,多个线程会被操作系统调度到多个CPU并行执行。
  • 一个协程正在运行时,其他协程会停止工作。当前协程执行阻塞IO操作时会挂起,底层调度器会进入事件循环。当有IO完成事件时,底层调度器恢复事件对应的协程的执行。
  • 对CPU多核的利用,仍然依赖于Swoole引擎的多进程机制。
  • Swoole遇到需要等待的IO才会切换,比如SQL查询、比如网络请求等待响应、比如读取文件等找到那个文件。
  • 从Mysql获取返回的结果集,这个需要CPU来计算,需要写内存,所以Swoole协程的单线程模型是串行来的,所以对于结果集数据量级过大的查询,效果不明显。
  • 搞明白什么时候会发生协程切换,业务无关的任务可以异步处理

4.关于队列

队列可以通过客户重要性等条件因素,进行优先级划分。优先级越高的越先处理(Redis的zSet类型数据)。

如何及时处理的区别就在于,队列可以进行中间操作,根据任务进行不同的异步处理。

5.协程的调度


Swoole 的协程化主要集中在 I/O 操作上,通过异步 I/O 提升了 I/O 密集型任务的性能。对于 CPU 密集型操作,虽然不会阻塞协程,但可能会占用较多 CPU 时间,影响协程的响应速度。协程的切换主要依赖于以下几种情况:


  • I/O 操作:当协程执行异步 I/O 操作时,会自动挂起,让出 CPU 给其他协程运行。
  • 显式让出:协程可以通过调用 Swoole\Coroutine::yield 或 Swoole\Coroutine::suspend 显式让出 CPU。
  • 超时等待:协程在等待某个操作完成时,如果设置了超时时间,超时后会自动让出 CPU。


CPU 密集型操作不会触发协程的挂起。如果一个协程执行了耗时 5 秒的CPU 密集型操作,它会占用当前协程的 CPU 时间。具体影响如下:


  • 当前协程:执行CPU 密集型操作的协程会持续占用 CPU,直到操作完成。
  • 其他协程:其他协程仍然可以运行,但会受到当前协程占用 CPU 时间的影响。如果当前协程占用 CPU 时间过长,其他协程的执行时间会相应减少。


swoole.enable_preemptive_scheduler ,可防止某些协程死循环占用 CPU 时间过长 (10ms 的 CPU 时间) 导致其它协程得不到调度

6.一个进程的 CPU 时间由什么决定

一个进程的 CPU 时间主要由以下几个因素决定:

  1. 进程的优先级
  • 操作系统会根据进程的优先级分配 CPU 时间。高优先级的进程会获得更多的 CPU 时间,而低优先级的进程可能会被推迟执行。
  1. 进程的 CPU 使用情况
  • 如果进程执行的是 CPU 密集型任务(如计算密集型操作),它会占用较多的 CPU 时间。
  • 如果进程执行的是 I/O 密集型任务(如文件读写、网络通信),它会在等待 I/O 操作完成时释放 CPU 时间,让其他进程运行。
  1. 操作系统的调度策略
  • 操作系统使用调度算法(如时间片轮转、优先级调度等)来分配 CPU 时间。每个进程会获得一定的时间片(通常几毫秒)来运行,时间片结束后,操作系统会切换到其他进程。
  • 在多核处理器系统中,多个进程可以同时在不同的核心上运行,从而提高系统的整体性能。
  1. 系统负载
  • 当系统负载较高(即有多个进程同时竞争 CPU 资源)时,每个进程获得的 CPU 时间会减少。
  • 当系统负载较低时,进程可能会获得更多的 CPU 时间。
  1. 进程的阻塞状态
  • 如果进程进入阻塞状态(如等待 I/O 操作完成),它会释放 CPU 时间,让其他进程运行。
  • 阻塞状态的进程不会占用 CPU 时间,直到它从阻塞状态中恢复。

进程不能无限申请 CPU 时间

操作系统会根据调度算法和进程的优先级来限制进程的 CPU 使用时间。即使进程试图占用更多的 CPU 时间,操作系统也会通过时间片轮转等方式强制切换到其他进程。

7.常见的进程阻塞

I/O 阻塞是指进程在等待输入/输出操作完成时进入的阻塞状态。常见的 I/O 操作包括:

  • 文件读写:如打开文件、读取文件内容、写入文件等。
  • 网络通信:如发送数据、接收数据等。
  • 设备操作:如读取磁盘数据、等待用户输入等。

进程在等待某个时间间隔时会进入阻塞状态。常见的操作包括:

  • sleep:使进程休眠指定的时间。
  • usleep:使进程休眠指定的微秒数。

......

阻塞卡主,跟CPU占用过高卡主,是两种情况

相关文章
|
PHP
MAMP PRO 安装php swoole扩展
MAMP PRO 安装php swoole扩展
451 0
MAMP PRO 安装php swoole扩展
|
前端开发 网络协议 测试技术
探索PHP的异步编程模型:从React到Swoole
在Web开发领域,PHP一直以简单易用著称。然而,随着互联网应用对性能和并发处理能力的不断追求,传统的同步阻塞式编程模型已逐渐暴露出局限性。本文将深入探讨PHP中的异步编程模型,从早期的React到现代的Swoole,分析其原理、优势及应用场景,并通过实例展示如何利用这些工具提升PHP应用的性能和响应速度。文章旨在为PHP开发者提供一种全新的视角,帮助他们在构建高性能Web应用时做出更合理的技术选择。
217 27
|
JavaScript 应用服务中间件 Go
PHP的异步编程:探索Swoole的奥秘
在传统的同步编程模型中,PHP的表现一直受到诟病。然而,随着Swoole的出现,PHP开发者得以迈入异步编程的新纪元。本文将深入浅出地介绍Swoole如何让PHP在性能和并发处理上实现飞跃,同时保持代码的简洁与优雅。
157 32
|
缓存 程序员 PHP
为什么说 Swoole 是 PHP 程序员技术水平的分水岭?
【9月更文挑战第8天】Swoole 被视为 PHP 程序员技术水平的分水岭,因为它要求程序员深入理解底层原理(如网络编程、异步和并发模型),具备性能优化能力(如高效服务器开发、数据库连接池管理),拥有架构设计能力(如微服务架构、项目复杂度管理),并具备持续学习和自我提升意识。熟练掌握 Swoole 的程序员在技术能力和综合素质方面更具优势。
162 9
|
缓存 网络协议 程序员
为什么说 Swoole 是 PHP 程序员技术水平的分水岭?
【9月更文挑战第7天】Swoole 因其异步非阻塞编程模式、高性能服务器开发能力、性能优化工具及拓展技术视野等特点,被视为 PHP 程序员技术水平的分水岭。它要求程序员掌握异步编程、协程、网络协议等知识,并具备性能优化和系统管理能力,从而全面提升技术水平。
186 0
|
网络协议 中间件 API
探索PHP的异步编程:Swoole框架的应用
在Web开发领域,PHP以其易用性和广泛的社区支持而闻名。然而,传统的PHP编程模型通常是同步的,这意味着在处理请求时,服务器必须等待任务完成才能响应。随着技术的发展,异步编程逐渐成为提升应用性能的关键。本文将深入探讨如何通过Swoole框架实现PHP的异步编程,从而优化并发处理能力,并提高应用的响应速度和扩展性。
|
Apache PHP
百度搜索:蓝易云【Apache环境php安装扩展swoole。】
通过以上步骤,你就可以在Apache环境中成功安装和配置Swoole扩展了。请确保你按照正确的步骤进行操作,并根据你的系统和环境进行相应的调整。如果遇到问题,你可以参考Swoole官方文档或社区的支持资源来获取更多帮助。
123 1
|
数据采集 网络协议 PHP
如何使用PHP的swoole扩展提高服务器并发能力
PHP的swoole扩展是一个高性能的网络通信框架,它可以让PHP开发者轻松地创建TCP/HTTP服务,来响应客户端的请求。但是,有些请求可能涉及到一些复杂和耗时的业务逻辑,如果在工作进程中直接处理,可能会影响服务器的并发能力。
291 0
如何使用PHP的swoole扩展提高服务器并发能力
|
Linux PHP Docker
Windows下PHP微服务框架Hyperf Swoole开发部署(Docker方式)
Windows下PHP微服务框架Hyperf Swoole开发部署(Docker方式)
1177 0
Windows下PHP微服务框架Hyperf Swoole开发部署(Docker方式)