Swoole引擎原理的快速入门干货

更多内容,欢迎关注微信公众号:全菜工程师小辉~php

过去一年使用PHP和Java两种技术栈完成了一个游戏服务器项目。因为项目中有高频的网络请求,因此PHP技术栈尝试使用Swoole引擎(基于事件的高性能异步并行网络通讯引擎)来完成部分游戏业务。nginx

Swoole的安装

安装swoole很简单,因为是国人作的项目,不少issue能够在官网文档找到答案。安装分两种:git

  • 编译安装。直接去github或者gitee去下载官方的发行版,编译安装后,将so拓展写入php.ini文件。
  • 容器安装。swoole引擎应用普遍,因此hub上有不少可用的容器,选择须要的pull一下便可。
具体操做百度一下便可,网上相关内容不少。

Swoole引擎的优点

  1. 常驻内存。传统 PHP框架或者单文件,在处理每一个请求以前,都要作一遍加载框架文件、配置的操做,请求完成以后会释放全部资源和内存,无须担忧内存泄漏。可是若是请求数量上升,并发很高的时候,快速建立资源,又立刻释放,会致使 PHP 程序运行效率急剧降低。而使用 Swoole 则没有这个问题:PHP的代码加载到内存后,拥有更长的生命周期,这样创建的数据库链接和其余大的对象,不被释放。每次请求只须要处理不多的代码,而这些代码只在第一次运行时,被 PHP 解析器编译,驻留内存。之后都是直接载入 OPCODE ,让 Zend 引擎直接运行。另外,以前PHP不能实现的,如数据库链接池,缓存链接池均可以在Swoole引擎下实现。系统的运行效率会大大提升。
  2. 快速开发。Swoole引擎提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库链接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询。 Swoole内置了Http/WebSocket服务器端/客户端、Http2.0服务器端。
  3. 协程编程模式。Swoole4可使用彻底同步的代码实现异步程序。PHP代码无需额外增长任何关键词,底层自动进行协程调度,实现异步IO。

Swoole引擎的流程解析

Swoole运行的流程图以下:github

Swoole的运行图

Swoole中的线程或进程

结构图以下:数据库

Swoole的线程图

Swoole引擎分为两种模式:单线程模式和进程模式。本文只讨论进程模式。具体二者区别官方文档中有说明。

Master进程

用于处理swoole核心事件,好比来自客户端的链接,本地通信的管道。master进程里有多个线程,每一个线程运行了一个epol函数的实例。(因为Worker进程并非由Master进程fork出来的,因此可能会出现强行kill Master进程后,Worker进程依旧存在)apache

Reactor线程

Swoole的主进程是一个多线程的程序。其中有一组很重要的线程,称之为Reactor线程。它就是真正处理TCP链接,收发数据的线程。
Swoole的主线程在Accept新的链接后,会将这个链接分配给一个固定的Reactor线程,并由这个线程负责监听此socket。在socket可读时读取数据,并进行协议解析,将请求投递到Worker进程。在socket可写时将数据发送给TCP客户端编程

Manager进程

swoole中worker/task进程都是由Manager进程Fork并管理的。
子进程结束运行时,manager进程负责回收此子进程,避免成为僵尸进程。并建立新的子进程
服务器关闭时,manager进程将发送信号给全部子进程,通知子进程关闭服务
服务器reload时,manager进程会逐个关闭/重启子进程segmentfault

Worker进程

Swoole提供了完善的进程管理机制,当Worker进程异常退出,如发生PHP的致命错误、被其余程序误杀,或达到max_request次数以后正常退出。主进程会从新拉起新的Worker进程。 Worker进程内能够像普通的apache+php或者php-fpm中写代码。不须要像Node.js那样写异步回调的代码。缓存

各进程的回调函数

Master内的回调函数:服务器

  • onStart
  • onShutdown

Worker进程内的回调函数

  • onWorkerStart
  • onWorkerStop
  • onConnect
  • onClose
  • onReceive
  • onFinish

TaskWorker进程内的回调函数

  • onTask
  • onWorkerStart

Manager进程内的回调函数

  • onManagerStart
  • onManagerStop

Reactor、Worker、TaskWorker的关系

能够理解为Reactor就是nginx,Worker就是php-fpm。Reactor线程异步并行地处理网络请求,而后再转发给Worker进程中去处理。Reactor和Worker间经过UnixSocket进行通讯。
在php-fpm的应用中,常常会将一个任务异步投递到Redis等队列中,并在后台启动一些php进程异步地处理这些任务。Swoole提供的TaskWorker是一套更完整的方案,将任务的投递、队列、php任务处理进程管理合为一体。经过底层提供的API能够很是简单地实现异步任务的处理。另外TaskWorker还能够在任务执行完成后,再返回一个结果反馈到Worker。
Swoole的Reactor、Worker、TaskWorker之间能够紧密的结合起来,提供更高级的使用方式。一个更通俗的比喻:假设Swoole应用服务器是一个工厂,那Reactor就是销售,接受客户订单。而Worker就是工人,当销售接到订单后,Worker去工做生产出客户要的东西。而TaskWorker能够理解为行政人员,能够帮助Worker干些琐事,让Worker专心工做。
底层会为Worker进程、TaskWorker进程分配一个惟一的ID。不一样的Worker和TaskWorker进程之间能够经过sendMessage接口进行通讯。

实际项目中的各进程线程的分工:

  • Manager进程:负责管理worker进程,建立或回收
  • Worker进程:游戏逻辑处理
  • taskWorker进程:向客户端发网络包、关闭长期不活跃的tcp链接

Swoole版本兼容性

该项目开发阶段使用的swoole引擎版本1.9.6,后来因为测试环境安装成了4.3.2版本,因此尝试业务代码做调整。不过swoole的向下兼容很值得佩服的是,这过程当中居然只发现了一处代码不兼容的问题:是有关swoole_server的一项配置参数,在原来版本采用了魔鬼数字进行配置的,可是到新版本,这个数字没有被宏定义,后来经过查看swoole源码找到了宏定义组,而后修改了这处配置。(不过版本升级顺利也是基于swoole的业务代码比较少,因此仅供参考)

哎呀,若是个人名片丢了。微信搜索“全菜工程师小辉”,依然能够找到我

相关文章
相关标签/搜索