热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

房产基于Swoole的PHPRPC框架设计

导语本文基于业务的实际场景出发,重构异步驱动的PHP微服务框架,实现了对接跨平台跨语言的微服务管理能力,保证了PHP在开发效率和运行效率的兼容,希望能够对PHP开发同学实现高并发的服务有所帮助。

导语

本文基于业务的实际场景出发,重构异步驱动的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、高发并支持

PHP作为解析型语言的代表,每次执行都需要将PHP代码转为Opcode数组(PHP7增加了抽象语法树,分析阶段生成AST),然后由Zend引擎来执行,并释放响应资源,鉴于Fpm的传统同步模式都需要开启大量进程保证并发,造成CPU上下文切换频繁和资源的相对浪费。因此新的服务框架需要具备以下特点:

  • 支持事件驱动的异步编程模式,支持多线程Reactor模式处理网络请求,能够应对大量链接的情况。
  • 具备同步/异步/协程实现能力。
  • 避免每次请求都重新解析,创建,销毁的空转流程。
  • 支持IPC通信。

Swoole Reactor说明图

2、快速部署

  • 能够兼容房产现有框架的开发测试监控流程。
  • 支持集团云服务管理平台&&代码发布平台。

3、监控&统计上报能力

  • 支持函数的自动化注册能力,鉴于PHP并无Maven pom配置文件,也无注解(Annotation),为保证系统开发的便捷性需要能够实现函数的映射&注册能力。
  • 服务调用异步统计&上报,支持识别服务的访问,访问耗时,执行耗时,异常,抛弃等状态的捕捉和上报。
  • 支持对服务管理平台的长连接心跳检测,保证服务侧可用状态维护及对应熔断能力。

4、序列化&反序列化服务

  • 通用性,能够支持丰富的数据结构类型并实现跨语言跨平台的序列化和反序列化能力,保证序列化性能的同时也要保证服务的可用性。
  • 鲁棒性,一旦出现内部结构扰动,可以有效避免序列化/反序列化的带来的不确定性。
  • 可扩展性&可读性。

由于系统升级的不可避免性,序列化协议应该具备良好的可扩展性,支持自动增加新的能力而不影响老服务。简化序列化流程,保证开发同学能够通过较低的学习和接入成本来共同接入。

5、通用组件支持

对开发同学常用的组件如redis服务(Wredis),个性化监控打点服务(Wmonitor),分布式KV,KList系统(Wtable)等工具和服务有着友好的接入能力,能够由同步编程驱动快速切成换异步编程驱动处理业务逻辑。

Swoole RPC 进程解析图

6、服务治理

为了系统能够在并发量峰值场景下提供稳定可靠的服务,服务需要有效实现如下内容:

  • 服务的注册和发现:服务启动时通过独立进程,上报ip,端口,服务详情等信息至服务管理中心,由服务管理中心实时更新。
  • 服务的限流,熔断,降级:避免对挂起服务的请求造成服务的不可用蔓延至整个集群,熔断器和限流器的令牌算法保障服务的可用性。
  • 服务的配置中心能力。

技术难点

1、如何实现服务层的序列化/反序列化

架构平台部提供的RPC客户端( SCF -client)是基于Fpm同步进程的架构体系的,为了提升序列化的性能会将实体序列化至Apcu中,但是锁的粒度较粗,高并发的情况下会存在锁的竞争,一方面性能较差,另一方面会造成异步处理进程阻塞乃至异常退出。针对这种情况我们重构了服务层的序列化框架,舍弃对Apcu的依赖,降低资源的线程式读取,避免无效类的抽象,精简反序列化和序列化流程,精简80%代码,聚焦核心流程。

SCF Client重构流程图

2、服务层如何实现高效的心跳检测&统计&上报

持久化服务层需要保持长连接和服务管理平台实现心跳检测和调用上报,在这方面架构平台提供了相应的扩展初始化了独立的进程支持来实现心跳检测和服务调用上报协议,服务层实现函数的调用即可统计。但是由于服务层的运行机制,众多 Worker 之间是内存隔离的,如果将心跳检测进程依赖于任何一个worker进程,那么在处理一定的Tcp请求后Worker会自动关闭,造成上报进程也会随之关闭,因此我们将心跳上报进程在Manager进程启动时Fork出来,然后通过持久化的task进程来实现上报,worker处理完Tcp请求后,将任务投递到task中实现异步收集和上报。

3、 怎么从同步编程切换为异步非阻塞的模式

众所周知,PHP常用Fpm运行模式是同步处理请求的,如果我们调用4-5个微服务应用( SCF) 服务时,耗时是串行累加的,而在服务层通过协程(用户态的线程)在网络IO处理的时候是可以跳过去执行其他的业务逻辑,也就是可以并行的发起后端的请求,一旦请求完毕则会将结果放在一个Channel中去供下游逻辑使用。假设一个服务中调用其所依赖的其他服务共N个请求&每个请求耗时相等,那么总耗时仅为同步的1/N(如果N个服务耗时不等,总耗时=max(子请求耗时)),极大提升了服务吞吐能力。

系统架构

PHP 微服务架构图

  • 服 务侧动态化配置能力,在启动时依据服务层配置文件和业务层配置文件分别启动不同的能力,灵活定制服务侧能力,同时通用框架文件,配置信息常驻内存,避免每次请求处理都需要编译执行通用信息。
  • 启动过程中基于业务类的反射配置,获取业务模块的函数信息,参数等,自动注册至服务管理平台,并监听指定的Tcp端口。
  • Tcp请求通过框架级的序列化/反序列化通用能力(W SCF )将二进制流转化成可供PHP识别的变量和参数,调用路由映射类将请求分发至指定的类实现业务逻辑需求。
  • 通过协程并行请求后端的资源能力,通过池化设计能力,降低链接资源的重复开销,有效复用链接资源。
  • 函数的访问,耗时,执行等统计类信息,基于IPC交付至异步的task进程,避免同步阻塞任务,由异步任务统计至上报扩展,再由上报扩展通信至服务管理平台。

功能设计&实践

1、服务进程启动

服务启动时监听配置文件指定端口,在启动Manager进程时开启上报进程,并将通过反射Map获取的服务名称,函数名称等信息注册至服务管理平台,通过长连接保持心跳检测服务的可用性。

2、序列化&路由映射

Tcp EOF收到完整的二进制字节流后,根据PHP的数据序列化/反序列组件(W SCF) 对字节流定义的字段类型开始序列化/反序列化,获取路由信息以及对应参数信息,转换至PHP可识别的类和函数,然后使用钩子调用对应的路由能力,由对应的业务逻辑处理。

3、协程异步处理 在业务处理阶段,对于依赖的后端服务能力,如微服务框架( SCF) , Mysql ,Redis服务(Wredis),分布式KV,Klist系统( Wtable) 等能力,通过协程实现并行能力请求,如遇到接口请求自动挂起协程,将CPU让给其他协程执行,提升单线程的CPU资源利用率,提高性能。同时持久化后端资源池,降低Tcp资源连接开销,减少本地端口调用并提升系统吞吐能力。

协程流程图

展望&总结

目前已和云平台共同定制了服务侧的开发标准,并推广至公司级平台,面向广大的开发同学,在租房业务线已有连接组和租房组等业务线平稳接入使用,安居客业务线在调研接入阶段,同步的连接模式变更至异步的驱动模式,有效降低对后端资源的开销,充分挖掘了系统的潜力。

作者简介

陈艺天,房产租房技术部。专注于PHP的生态建设和性能提升。先后负责PHP技术栈的W SCF 重构,Wfmanager扩展,PHP微服务能力孵化等工作。


推荐阅读
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • [翻译]微服务设计模式5. 服务发现服务端服务发现
    服务之间需要互相调用,在单体架构中,服务之间的互相调用直接通过编程语言层面的方法调用就搞定了。在传统的分布式应用的部署中,服务地 ... [详细]
  • zuul 路由不生效_Zuul网关到底有何牛逼之处?竟然这么多人在用~
    作者:kosamino来源:cnblogs.comjing99p11696192.html哈喽,各位新来的小伙伴们,大家好& ... [详细]
  • LVS-DR直接路由实现负载均衡示例
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
  • centos6.8 下nginx1.10 安装 ... [详细]
author-avatar
静乐思
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有