探索嵌入式PHP与C/C++结合的无限种可能
qiyuwang 2024-10-15 14:49 21 浏览 0 评论
内容来源:2018 年 5 月 20 日,腾讯企点开放平台技术负责人熊月在“PHPCon China 2018 技术峰会”进行《嵌入式PHP的探索实践》演讲分享。IT 大咖说作为独家视频合作方,经主办方和讲者审阅授权发布。
阅读字数:2410 | 7分钟阅读
获取嘉宾演讲视频及PPT,请复制:http://t.cn/RDsTba0,粘贴至浏览器即可。
摘要
对于拥有很多复杂业务场景的tob领域,“开发效率”和“性能”常常是我们考虑的两个主要问题,PHP作为脚本语言,本身适用于快速开发业务逻辑,同时为了解决PHP特定的性能瓶颈,一般将C++/PHP结合,在PHP代码里调用C/C++扩展。 这次我们带来了不同思路的探索:将php嵌入到高性能C/C++框架运行,将C/C++框架作为容器,完美结合php快速开发优势和C/C++高性能特点。Zend Engine提供了一种嵌入式开发模式,我们利用这一特性使它可以在C/C++的环境中单独执行PHP脚本,并且支持多实例运行,可以在C/C++协程框架中运行。嵌入式PHP也为在任意C/C++协程框架结合带来无限可能,包括在C++的客户端上运行PHP。
嵌入式PHP
作为一门后台开发语言PHP有着不同的发展阶段。最开始是大家都比较熟悉的LAMP,接着是PHP-fpm和fastcgi,再往后是swoole,之后在swoole的基础上又新增了协程。
为了便于理解,在介绍嵌入式PHP之前要先讲下SAPI的概念。SAPI即后台应用程序编程接口,是PHP与其他应用程序交互的接口。常见的SAPI有cgi、fpm、cli、Apace2 hander,而嵌入式PHP(embed)也是其中一类。
业务场景
我们最初的业务框架是基于TSF2.0,底层为Zend Engine和扩展,扩展最核心的部分是基于swoole。在此之上是TSF PHP层,包含协程调度器、微服务框架、监控管理进程、MVC模式。最上层才是真正的执行逻辑的PHP脚本。
这样一套框架存在几个问题。PHP原生的Generator协程需要配合yield使用,对开发来说不怎么友好,因为yield的使用时机不太好确定,尤其是对于新手。由于协程调度器是用原生PHP实现的,因此相对其他语言在性能上会差些,特别是在高并发场景下。还有就是低版本swoole不够稳定,问题最多的就是在内存泄露这块。大家都知道腾讯内部有很多公用组件,这些组件接口大多是用C++实现的,为此我们需要做的是用扩展对接PHP与其他组件,而问题就在于扩展无法使用上层的PHP协程。
方案:SPP+PHP
为什么选择嵌入式PHP
SNG中有个非常有名的C++后台框架SPP,它是一个高性能的网络框架,起始于2008年,被广泛的应用于SNG的各个业务线。众所周知开发效率一直是PHP的长处,性能方面则是短板。所以我们就在想能不能将SPP和PHP结合起来兼顾高性能和开发效率,嵌入式PHP无疑是很好的结合方案。
SPP主要有5个模块。proxy用来处理新请求,内存队列是proxy和workgroup交互的内存区域,workgroup是和后台逻辑脚本交互的模块,controller作为控制核心来控制proxy和workgroup的运行状态,最后是最重要的协程模块。
如何将SPP和Zend结合
SPP其实是基于协程的框架,协程是一个用户态的多线程概念。在协程切换的时候会涉及内存管理的机制,而Zend没有这种切换内存资源的机制,只有全局变量和多线程资源隔离的方式。这样的话要想将SPP和Zend结合起来,就要对Zend进行改造。
Zend的源码大概有60万行,如果直接改动核心源码,不光实施起来很麻烦,对之后的升级也会造成问题。最好的办法是借助Zend本身的机制对入口进行改造,而不侵入内核。
Zend改造
Zend有多进程和多线程两种方式,在多线程模式下有一个线程安全的机制ZTS。ZTS本质其实是对每个线程的全局资源进行了隔离,与SPP协程的结合就需要用到ZTS,下面是具体步骤。
第一步当然是打开Zend内核ZTS开关,第二步为了满足协程上下文切换,需要将ZTS中的线程私有变量转化为全局数据元素,第三步增加资源入口切换API。做完这三步就完成了Zend和SPP的结合,虽然步骤不多但实际上在做的过程中还是会有很多挑战。
PHP执行流调度器
解决了结合问题之后,接下来为了将整个流程串起来需要有一个执行流程调度器。上图是整个执行流程,首先SPP通过SAPI进入到Zend中,然后Zend执行PHP脚本,先编译成OpCode,之后如果有网路IO就会用到协程。协程也可以基于SPP提供的API来运作,通过Tsrm的全局资源table可以进行协程切换。
在有这样一套执行流的情况下,扩展也可以依赖SPP的API实现协程调度。
上图是SPP结合PHP之后的整体架构。最底层是SPP,往上是PHP执行流调度器,中间是PHP内核和扩展,最上层是PHP脚本。这一整套架构以嵌入式的方式结合了SPP和PHP,让开发者既可以利用SPP提供的高性能网络框架,同时也能应用到上层PHP快速开发的特点。
这里展示的是压测时候的环境数据,包括机型、压测工具、压测方法以及框架的版本等。
这是压测后获得的实际数据对比,可以看到SPP-PHP框架相对旧的框架性能上大概有3倍的提升。
以上为今天的分享内容,谢谢大家!
编者:IT大咖说,转载请标明版权和出处
相关推荐
- # 安装打开 ubuntu-22.04.3-LTS 报错 解决方案
-
#安装打开ubuntu-22.04.3-LTS报错解决方案WslRegisterDistributionfailedwitherror:0x800701bcError:0x80070...
- 利用阿里云镜像在ubuntu上安装Docker
-
简介:...
- 如何将Ubuntu Kylin(优麒麟)19.10系统升级到20.04版本
-
UbuntuKylin系统使用一段时间后,有新的版本发布,如何将现有的UbuntuKylin系统升级到最新版本?可以通过下面的方法进行升级。1.先查看相关的UbuntuKylin系统版本情况。使...
- Ubuntu 16.10内部代号确认为Yakkety Yak
-
在正式宣布Ubuntu16.04LTS(XenialXerus)的当天,Canonical创始人MarkShuttleworth还非常开心的在个人微博上宣布Ubuntu下个版本16.10的内...
- 如何在win11的wsl上装ubuntu(怎么在windows上安装ubuntu)
-
在Windows11的WSL(WindowsSubsystemforLinux)上安装Ubuntu非常简单。以下是详细的步骤:---...
- Win11学院:如何在Windows 11上使用WSL安装Ubuntu
-
IT之家2月18日消息,科技媒体pureinfotech昨日(2月17日)发布博文,介绍了3中简便的方法,让你轻松在Windows11系统中,使用WindowsSubs...
- 如何查看Linux的IP地址(如何查看Linux的ip地址)
-
本头条号每天坚持更新原创干货技术文章,欢迎关注本头条号"Linux学习教程",公众号名称“Linux入门学习教程"。...
- 怎么看电脑系统?(怎么看电脑系统配置)
-
要查看电脑的操作系统信息,可以按照以下步骤操作,根据不同的操作系统选择对应的方法:一、Windows系统通过系统属性查看右键点击桌面上的“此电脑”(或“我的电脑”)图标,选择“属性”。在打开的...
- 如何查询 Linux 内核版本?这些命令一定要会!
-
Linux内核是操作系统的核心,负责管理硬件资源、调度进程、处理系统调用等关键任务。不同的内核版本可能支持不同的硬件特性、提供新的功能,或者修复了已知的安全漏洞。以下是查询内核版本的几个常见场景:...
- 深度剖析:Linux下查看系统版本与CPU架构
-
在Linux系统管理、维护以及软件部署的过程中,精准掌握系统版本和CPU架构是极为关键的基础操作。这些信息不仅有助于我们深入了解系统特性、判断软件兼容性,还能为后续的软件安装、性能优化提供重要依据。接...
- 504 错误代码解析与应对策略(504错误咋解决)
-
在互联网的使用过程中,用户偶尔会遭遇各种错误提示,其中504错误代码是较为常见的一种。504错误并非意味着网站被屏蔽,它实际上是指服务器在规定时间内未能从上游服务器获取响应,专业术语称为“Ga...
- 猎聘APP和官网崩了?回应:正对部分职位整改,临时域名可登录
-
10月12日,有网友反映猎聘网无法打开,猎聘APP无法登录。截至10月14日,仍有网友不断向猎聘官方微博下反映该情况,而猎聘官方微博未发布相关情况说明,只是在微博内对反映该情况的用户进行回复,“抱歉,...
- 域名解析的原理是什么?域名解析的流程是怎样的?
-
域名解析是网站正常运行的关键因素,因此网站管理者了解域名解析的原理和流程对于做好域名管理、解决常见解析问题,保障网站的正常运转十分必要。那么域名解析的原理是什么?域名解析的流程是怎样的?接下来,中科三...
- Linux无法解析域名的解决办法(linux 不能解析域名)
-
如果由于误操作,删除了系统原有的dhcp相关设置就无法正常解析域名。 此时,需要手动修改配置文件: /etc/resolv.conf 将域名解析服务器手动添加到配置文件中 该文件是DNS域名解...
- 域名劫持是什么?(域名劫持是什么)
-
域名劫持是互联网攻击的一种方式,通过攻击域名解析服务器(DNS),或伪造域名解析服务器(DNS)的方法,把目标网站域名解析到错误的地址从而实现用户无法访问目标网站的目的。说的直白些,域名劫持,就是把互...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- # 安装打开 ubuntu-22.04.3-LTS 报错 解决方案
- 利用阿里云镜像在ubuntu上安装Docker
- 如何将Ubuntu Kylin(优麒麟)19.10系统升级到20.04版本
- Ubuntu 16.10内部代号确认为Yakkety Yak
- 如何在win11的wsl上装ubuntu(怎么在windows上安装ubuntu)
- Win11学院:如何在Windows 11上使用WSL安装Ubuntu
- 如何查看Linux的IP地址(如何查看Linux的ip地址)
- 怎么看电脑系统?(怎么看电脑系统配置)
- 如何查询 Linux 内核版本?这些命令一定要会!
- 深度剖析:Linux下查看系统版本与CPU架构
- 标签列表
-
- navicat无法连接mysql服务器 (65)
- 下横线怎么打 (71)
- flash插件怎么安装 (60)
- lol体验服怎么进 (66)
- ae插件怎么安装 (62)
- yum卸载 (75)
- .key文件 (63)
- cad一打开就致命错误是怎么回事 (61)
- rpm文件怎么安装 (66)
- linux取消挂载 (81)
- ie代理配置错误 (61)
- ajax error (67)
- centos7 重启网络 (67)
- centos6下载 (58)
- mysql 外网访问权限 (69)
- centos查看内核版本 (61)
- ps错误16 (66)
- nodejs读取json文件 (64)
- centos7 1810 (59)
- 加载com加载项时运行错误 (67)
- php打乱数组顺序 (68)
- cad安装失败怎么解决 (58)
- 因文件头错误而不能打开怎么解决 (68)
- js判断字符串为空 (62)
- centos查看端口 (64)