房产基于Swoole的PHP RPC框架设计
导语
本文基于业务的实际场景出发,重构异步驱动的PHP微服务框架,实现了对接跨平台跨语言的微服务管理能力,保证了PHP在开发效率和运行效率的兼容,希望能够对PHP开发同学实现高并发的服务有所帮助。
背景
58内部常用的微服务框架(SCF)是基于Java技术栈的,而房产租房业务开发通常采用的是PHP技术栈,在运行机制和模式与Java有着诸多的差异。在接口不多,系统与系统交互较少的情况下,用Http接口能够快速实现跨系统/服务的调用,但是随着租房业务的蓬勃发展,内部的子系统/项目越来越多,系统架构也由集中式架构向分布式架构转变,Http的接口调用无论是代码层面,还是在性能层面已经不能满足日渐复杂的应用系统发展能力,开发的同学会经常面临如下的情况:
Http接口需要配置Nginx负载均衡,一旦故障/重启则会影响下游的调用方,直接影响服务的可用性。
大部分是基于Json的格式传输,字节大小和序列化相比二进制传输更消耗性能。
调用纷繁复杂的上游域名,路由眼花缭乱,令后续的维护成本骤升。
服务的耗时,响应,扩容以及安全性都有待弥补。
由于PHP作为解释型语言,在请求结束即释放所有资源的特性,在持久化服务注册发现和心跳检测的实现上有一定的难度,针对PHP此特性业内通用有两种做法:服务代理扩展和长驻内存能力实现,代表分别为微博的Agent和腾讯的Tars-php。
鉴于公司内部已有成熟的微服务管理平台(SCF)可供对接,PHP的技术栈只需要实现服务层处理能力&&接入服务管理平台即可快速提供服务,也因此,为了提升服务的可用性和调用效率,提升应用系统的稳定性,房产租房业务部门内部孵化了基于Swoole的常驻内存RPC框架。
SCF RPC架构图
技术目标
1、高发并支持
支持事件驱动的异步编程模式,支持多线程Reactor模式处理网络请求,能够应对大量链接的情况。
具备同步/异步/协程实现能力。
避免每次请求都重新解析,创建,销毁的空转流程。
支持IPC通信。
能够兼容房产现有框架的开发测试监控流程。
支持集团云服务管理平台&&代码发布平台。
3、监控&统计上报能力
-
支持函数的自动化注册能力,鉴于PHP并无Maven pom配置文件,也无注解(Annotation),为保证系统开发的便捷性需要能够实现函数的映射&注册能力。
-
服务调用异步统计&上报,支持识别服务的访问,访问耗时,执行耗时,异常,抛弃等状态的捕捉和上报。
-
支持对服务管理平台的长连接心跳检测,保证服务侧可用状态维护及对应熔断能力。
4、序列化&反序列化服务
-
通用性,能够支持丰富的数据结构类型并实现跨语言跨平台的序列化和反序列化能力,保证序列化性能的同时也要保证服务的可用性。
-
鲁棒性,一旦出现内部结构扰动,可以有效避免序列化/反序列化的带来的不确定性。
-
可扩展性&可读性。
由于系统升级的不可避免性,序列化协议应该具备良好的可扩展性,支持自动增加新的能力而不影响老服务。简化序列化流程,保证开发同学能够通过较低的学习和接入成本来共同接入。
5、通用组件支持
对开发同学常用的组件如redis服务(Wredis),个性化监控打点服务(Wmonitor),分布式KV,KList系统(Wtable)等工具和服务有着友好的接入能力,能够由同步编程驱动快速切成换异步编程驱动处理业务逻辑。
Swoole RPC 进程解析图
6、服务治理
为了系统能够在并发量峰值场景下提供稳定可靠的服务,服务需要有效实现如下内容:
服务的注册和发现:服务启动时通过独立进程,上报ip,端口,服务详情等信息至服务管理中心,由服务管理中心实时更新。
服务的限流,熔断,降级:避免对挂起服务的请求造成服务的不可用蔓延至整个集群,熔断器和限流器的令牌算法保障服务的可用性。
服务的配置中心能力。
技术难点
1、如何实现服务层的序列化/反序列化
2、服务层如何实现高效的心跳检测&统计&上报
3、 怎么从同步编程切换为异步非阻塞的模式
系统架构
-
服务侧动态化配置能力,在启动时依据服务层配置文件和业务层配置文件分别启动不同的能力,灵活定制服务侧能力,同时通用框架文件,配置信息常驻内存,避免每次请求处理都需要编译执行通用信息。
-
启动过程中基于业务类的反射配置,获取业务模块的函数信息,参数等,自动注册至服务管理平台,并监听指定的Tcp端口。
-
Tcp请求通过框架级的序列化/反序列化通用能力(WSCF)将二进制流转化成可供PHP识别的变量和参数,调用路由映射类将请求分发至指定的类实现业务逻辑需求。
-
通过协程并行请求后端的资源能力,通过池化设计能力,降低链接资源的重复开销,有效复用链接资源。
-
函数的访问,耗时,执行等统计类信息,基于IPC交付至异步的task进程,避免同步阻塞任务,由异步任务统计至上报扩展,再由上报扩展通信至服务管理平台。
功能设计&实践
1、服务进程启动
服务启动时监听配置文件指定端口,在启动Manager进程时开启上报进程,并将通过反射Map获取的服务名称,函数名称等信息注册至服务管理平台,通过长连接保持心跳检测服务的可用性。
2、序列化&路由映射
Tcp EOF收到完整的二进制字节流后,根据PHP的数据序列化/反序列组件(WSCF)对字节流定义的字段类型开始序列化/反序列化,获取路由信息以及对应参数信息,转换至PHP可识别的类和函数,然后使用钩子调用对应的路由能力,由对应的业务逻辑处理。
3、协程异步处理
在业务处理阶段,对于依赖的后端服务能力,如微服务框架(SCF),Mysql,Redis服务(Wredis),分布式KV,Klist系统(Wtable)等能力,通过协程实现并行能力请求,如遇到接口请求自动挂起协程,将CPU让给其他协程执行,提升单线程的CPU资源利用率,提高性能。同时持久化后端资源池,降低Tcp资源连接开销,减少本地端口调用并提升系统吞吐能力。
协程流程图
展望&总结
作者简介
陈艺天,房产租房技术部。专注于PHP的生态建设和性能提升。先后负责PHP技术栈的WSCF重构,Wfmanager扩展,PHP微服务能力孵化等工作。
END
阅读推荐