专访FPNN开源项目负责人:适用于实时数据处理的高性能框架
各种框架都是为了解决问题而出现的,而框架简单来说,可以理解为搭起架子、划定框子。程序设计的过程简单的说,可以归为三个步骤,其一是资源整合;其二是逻辑设计;其三是代码实现。代码实现部分需要把架构师设计出来的接口和各个功能模块进行具体的代码实现,此时就需要考虑到代码的扩展性、复用性、协同性和开发效率等因素,而框架的作用正在于此。
引入框架可以解决哪些问题呢?
① 代码规范,由于部分功能引入框架解决,所以为了统一,其他代码也要遵守规范,这样统一后,后续维护和开发都方便;
② 快,少一部分代码,不用重写和调试;
③ 协同合作,有了条的基础,加上框架的基础,就能多人合作开发,而不是开发中磨合;
本期我们有幸采访了FPNN开源项目负责人施王兴老师,一起探讨云上曲率完全自主研发的高性能网络通信框架——FPNN。一个全功能的轻量级RPC框架,同时也是一个轻量级的微服务框架,还是一种协议,一套技术体系。
问题1:老师,您好!请简单介绍一下您的技术背景、目前所负责的领域
大家好,我是云上曲率首席架构师施王兴,技术背景主要涉及网络服务、系统架构、和性能优化,辅以信息安全。其中在网络服务领域已经有19年工作经验,负责过用户上亿,日活4000万以上的社区项目,主打还是复杂系统架构、底层基础设施、和性能优化。工具方面,以C++为核心,辅以其他语言作为开发工具。2010年~2014年曾服务于开心网,负责中间层,也就是现在所说的中台,和新产品部的后端系统。其后加入FunPlus趣加游戏,在基础设施团队负责全球消息传输和基础组件。目前就职于云上曲率,依旧负责高性能高压力网络服务、基础设施、系统架构和性能优化。
问题2:FPNN当前是怎么进行分工的?FPNN的技术生态是什么样的?含有哪些技术生态的独立服务?
在云上曲率创业开始的阶段,FPNN核心是由我,目前云上曲率首席架构师;杜晓祥,云上曲率现任CEO;赵建军,云上曲率现任技术VP,三人协同维护。之后由于团队的扩大,现在FPNN框架基本上是我在维护,SDK由我和基服务团队进行维护;技术生态中系统运维侧的服务组件,如分布式日志系统、监控系统、报警系统主要是赵建军在维护;其余如数据库前端代理DBProxy、服务发现和治理集群FPZK、通用代理API网关UG,等服务组件由我维护。
FPNN的技术生态其实就是以FPNN协议和服务治理为核心思想,搭配模块化的通用型微服务,加上服务开发框架和各语言、各平台SDK组成的一个技术资源体系的集合。在这个生态下,可以以尽可能少的业务代码,直接开发出可维护性高、伸缩性高、抗高压高并发的业务系统;业务所需的模块化服务可通过配置文件即起即用,无需编写胶水代码进行粘合;在遵循FPNN服务治理的思想下,实际业务无需关心服务治理、部署拓扑、负载均衡和访问控制。一切交给FPNN框架和相关的FPNN技术生态内的模块化服务解决。
目前FPNN技术生态内的独立服务有以下几个:
logServer:分布式日志服务,暂未开源。16年的时候,兄弟集团因为日志问题焦头烂额。采用logServer系统替换当时的fluentd后,所有日志从1/10采样,到全收集,且无需担心刚启动的1分钟左右的日志会丢失。而且日志服务的机器数量和配置双减半。
FPMonitor:信息监控和报警系统,暂未开源。
FPZK:服务发现和服务/集群治理系统,支持洲际分层组网,暂未开源。
DBProxy:mySQL数据库前端代理,屏蔽数据分布和分库分表细节,已开源:https://github.com/highras/dbproxy。
TableCache:数据库前端行级缓存 + 透明代理。屏蔽数据库和分库分表细节。已开源:https://github.com/highras/tableCache。
IDGen:全局ID生成服务。支持全球组网,暂未开源。
UniversalGate:通用代理网关,对外屏蔽内部网络拓扑。可以代理任意FPNN协议,可自由配置访问策略和访问控制,暂未开源。
RTM:全球实时信令传输系统。该系统为商用系统。
RUM:实时数据分析系统。该系统为商用系统。
FPManager:FPNN生态运营运维一体化联动监控和管理系统。支持数据采集、服务监控、主机监控、服务部署和迁移、运营数据分析和预警。暂未开源。
问题3:FPNN如何进行服务治理?是否支持服务网格?什么是服务网格?
FPNN的服务治理主要由FPZK服务集群和FPNN框架的extends内的组件配合完成。
核心有三块:
1. FPNN通过框架内置的FPZKCLient向FPZK集群注册自身,并选择需要同步的信息,以及同步范围是全局,还是当前区域。
2. FPZK按 全局/区域/服务/服务分组 的层次,对服务进行梳理。如果出现服务的集群变动,实时通知对应服务,或者服务分组的订阅者。
3. FPNN框架内置了FPZKProxy系列集群代理。该系列代理内置了FPZKClient,通过指定目标服务,FPZKProxy会自动去订阅相关的集群变动和集群状态。当一台服务A需要向某一集群“逻辑上”特定的服务B通讯时,服务A只需选择对应的FPZKProxy,传入消息即可。具体的负载均衡、负载选择、“逻辑上”和物理上的机器映射,均由FPZKProxy自动完成。
FPNN的服务网格和服务治理是一体的。
FPNN通过FPZKClient向FPZK注册自身后,会定时同步自生状态变化。而相关的状态会立刻同步到各个订阅者的FPZKClient中。各个订阅者的FPZKProxy使用FPZKClient的相关信息,决定了具体的消息应该发送给那一个确定的服务节点。
服务网格(Service Mesh)是一个新兴的概念,目前没有行业统一的标准解释。该名词早在2016年9月29日,由开发Linkerd的公司提出。其早定义由Linkerd的CEO表述为:Service Mesh是一个专门处理服务通讯的基础设施层。它的职责是在由云原生应用组成服务的复杂拓扑结构下进行可靠的请求传送。在实践中,它是一组和应用服务部署在一起的轻量级的网络代理,并且对应用服务透明。
问题4:FPNN的项目特色有哪些?突出的优点是什么?
FPNN项目大的特色有三个:
1. IDL-less:无需IDL,也能实现数据和协议的有效编排和处理。相关文章可参考《RPC框架的IDL与IDL-less》https://zhuanlan.zhihu.com/p/397060740
2. 支持低配机器的高性能高压力高并发。目前我们大量使用4核和8核心的虚拟机,这样可以有效的将单节点故障引起的波动降至低。
3. 通过内置的集群治理和服务网格模块,使通过FPNN框架开发的服务天生就具有集群治理和服务网格的能力。
突出的优点其实还是高性能。参考FPNN框架的性能报告https://github.com/highras/fpnn/blob/master/doc/zh-cn/fpnn-performance.md, 可以看到在低至虚拟4核CPU的虚拟机上,依然可以有20+万(同一局域网)或30+万(欧美跨洲传输)的QPS;在虚拟8核CPU的虚拟机上,依然能同时处理204万的长链接。
问题5:FPNN服务的安全与访问控制可以分为哪几部分?
安全的话,首当其冲便是访问控制。
FPNN的访问控制可以分为四个层次。个层次便是允许以什么样的协议进行访问。对于FPNN,除了TCP和UDP是需要以代码形式控制外,启不启用TLS链接,启不启用私有加密,起不启用HTTP/HTTPS,都是可以通过配置文件直接控制。第二个层次是接口层的访问控制。内置的三个敏感接口(*infos、*tune、*status),均只能内网访问。对于业务接口,可以在开发注册接口的时候,指定是仅允许加密链接(FPNN TLS/FPNN私有加密/HTTPS/wss)访问,还是仅允许内网访问,或是仅内网的加密链接可以访问。此外,通过配置还可以直接强制所有接口必须通过加密链接才可访问。访问控制的第三个层次,便是白名单。白名单支持子网和子网掩码,可以通过代码,或框架内置的参数动态配置接口进行配置。访问控制的后一个层次,是FPNN技术生态的通用网关,UniversalGate(UG)服务。UG用于对外屏蔽内部的网络结构和非公开服务,并限定外部对内部公开服务的访问方式和访问策略。
在访问中控制之外,还有四个地方一同协助保障服务的安全性。
个就是对网络包的各项限制。无论是单个包的大小、UDP四元组冲突策略、UDP重组切片的大小数量限制等。第二个就是容量限制相关。比如大链接数量,大任务积压等,用于防止服务过压的一些安全限制。以上这两个都可以通过代码或者配置文件进行控制。
第三个就是线程池隔离。业务任务和IO任务不光线程隔离,线程所属的线程池之间也是隔离的。这样是为了避免诸如当服务处于高压状态,需要主动降级时,IO不会因为业务线程全部无法切出而导致IO无响应。反之亦然。另外,不同的核心任务之间,任务的线程池也是相互隔离的。
后就是FPNN技术生态的FPMonitor和FPManager。FPMonitor通过监测日志,进行主动报警;而FPManager则对服务进行主动监测和趋势预测,根据结果进行报警,以便相关人员能及时调整服务集群相关状态。
问题6:FPNN正是有了好用的底层框架加持,云上曲率实时数据传输服务才能在性能上处于领先地位。其中,FPNN采用的是哪种框架架构?此种框架相比于其他框架有什么优势?
FPNN框架和主流的RPC框架一样,采用的还是消息式的流程结构。在这种思路下,会把网络数据作为一个一个独立的消息(请求/回应)进行并发处理。如果要做流式数据,还需要简单转换一下。不过大部分的流式数据,比如音视频流,本质上也是消息数据,所以很好转换。比如直播的视频流,它是由一帧一帧的数据组成,而每一帧数据,其实就是一个独立的消息结构。但为了更好的支持流媒体的处理,FPNN也在考虑增加对纯流式数据的支持。
之后,底层网络系统的开发者大部分其实热衷于reactor模式,但对于实际的业务使用方而言,业务方仅关系自己的数据(请求/应答)是否完整发出,收到的完整数据是请求还是应答。所以相对于reactor模式而言,proactor更契合实际的业务开发需要。因此我们会和主流的RPC框架一样,将底层的reactor行为,封装为proactor行为,同时对开发者屏蔽网络处理细节,让开发者专注于业务。而这正是以reactor模式为核心的网络框架,无法成为RPC框架的本质原因。
问题7:FPNN技术生态使用FPZK作为集群管理服务,基于FPZK是怎么实现集群管理与服务治理的呢?
基于FPZK的集群管理和服务治理,依赖于FPZK服务集群和FPZKClient/FPZKProxy两方面配合完成。
其中,业务服务使用FPZKClient向FPZK集群注册自身信息,以便其他服务能够发现和访问;FPZK向集群内其他节点同步自身所持有的服务信息,并将从其他节点同步来的信息和自身所持有的信息进行合并,然后将集群-发生变动的信息推送给集群的订阅者。而服务的访问者则需要根据具体的访问策略和负载均衡策略,选择相应的FPZKProxy,并用已有的FPZKClient实例和目标服务的集群名称来创建对应的FPZKProxy。创建的FPZKProxy将自动通过FPZKClient订阅对应的集群信息。当服务的访问者访问服务时,无需指定具体的数据接收者,仅需将所需要发送的数据交给对应的FPZKProxy即可。具体的负载均衡、节点选取、数据路由会由FPZKProxy根据FPZKClient收到的FPZK集群推送过来的信息进行抉择。所以对于开发者而言,只需要注册和选定订阅的目标集群,之后的处理将被透明化,所以使用起来相当简单。
而根据业务服务注册时的信息选项,注册的业务服务信息可以仅在同一区域内同步,业务服务仅在同一区域内被访问;也可以进行全网同步,在全网内任何节点都可访问。而且还可以同步系统和服务自身的性能信息,以便订阅者可以根据这些性能信息进行负载优选。
后,业务服务注册时,可以携带自身的分组信息,这样访问者可以直接访问某一服务集群的特定分组。比如DBProxy默认的集群名称是“dbproxy”,但带上分组信息后,就成了“dbproxy@bizA”、“dbproxy@bizB”等。如果需要访问不区分分组的某一个DBProxy,在FPZKProxy中指定集群名称“dbproxy”即可。否则如果需要访问bizA分组,则在FPZKProxy中指定“dbproxy@bizA”即可。
以上便是FPZK对集群的管理,以及服务治理的主要操作。
问题8: FPNN将业务内容划分为哪几部分?FPNN的下一步规划是什么?
FPNN其实分成3个层次:FPNN框架、FPNN技术生态的基础服务、基于FPNN技术生态的扩充服务。
个层次,FPNN框架很好理解,就仅只是服务端框架,以及各语言各平台SDK。这部分主要是提供开发工具。第二个层次,FPNN技术生态的基础服务,就包含了FPZK、DBProxy、UniversalGate、TableCache、FPMnoitor、FPManager等,通过配置,立刻可用,无需胶水代码,直接无缝衔接的通用服务。这部分主要是为了快速搭建业务系统和生产系统而提供了现成的服务模块。第三部分,就是使用FPNN框架开发,利用FPNN技术生态基础组件,开发和搭建的具体的业务系统,比如云上曲率的RTM实时信令系统和实时音视频传输服务,以及RUM实时数据监控系统。
FPNN下一步的核心规划是TCP和UDP混合链接。当完成TCP和UDP的混和链接后,所有FPNN服务,除特殊需求外,将不再区分是TCP链接,还是UDP链接。有关业务的TCP和UDP分离需求将自动消失。配合UniversalGate,和云服务商的高带宽,在FPManager的控制下,FPNN系列的服务将对DDoS产生足够的防御能力。在带宽足够的情况下,可以避免现有业务和客户链接受到DDoS攻击的影响。
此外,在时间允许的情况下,有考虑重写C++版的msgPack的编解码库,以提升对消息结构生成和使用上的体验,减少现有C++版msgPack库带来的一些使用上的负面体验。类似的事情2020年的时候已经在C#上做过一次,当时是因为C#的msgPack库过于巨大,且不方便使用,所以当时针对我们的具体需求和使用场景,重新写了一份C#的msgPack编解码库,地址为 https://github.com/highras/msgpack-csharp。到目前为止,2年多来,该重写版本在数十个客户项目上,不论是C#后端,还是Unity版本,与使用msgPack官方版的其他语言和平台的数据交互协作相当良好,没有发现任何异常。
问题9:FPNN的核心内容是什么?另外,开源往往需要很大的勇气,为什么要想到开源FPNN呢?
FPNN的核心重点其实就是快速开发和性能。FPNN针对快速开发,无论是在开发体验上,还是开发效率上,以及运维和服务治理上均作了针对性的优化。此外,性能优化也是核心重点。相关的优化,核心能数据,可以参考开源小秀场的PPT/PDF,以及FPNN框架的性能报告:https://github.com/highras/fpnn/blob/master/doc/zh-cn/fpnn-performance.md。
至于为什么开源,一方面是为了回馈开源社区,毕竟不光是FPNN,我们其他项目也大量采用了不少的开源项目和组件。比如Nginx、MySQL、PHP、RapidJson、msgPack等基础服务或组件,以及AES、ECC、SHA等算法的开源实现。所以希望大家可以相互交流一下,看一下大家对我们的设计和应用体验有什么反馈。此外,现在开源的知名RPC框架,除我们外,无一例外全部使用IDL。在我们于多个大型复杂项目中体验过IDL-less RPC框架的优势之后,特别希望给大家带来一个IDL-less的RPC框架,让大家能有机会在实际项目中,特别是经常需要灰度兼容和灰度发布的项目中,体验一下IDL-less RPC框架的优势。然后另外一方面的原因是,初我们基于FPNN开发的商用服务的客户,希望我们能公开SDK的代码,以便他们可以进行安全性检查,同时也希望能确认我们的技术实力。所以我们索性也就将底层开发框架直接开源。而通过项目和代码的分析评测,我们的商业客户也给了我们极高的评价,并极大地增强了对我们的信心和信任。这就是我们将FPNN开源的初的原因。
问题10:如何理解国内开源生态链,有什么关于开源方向的意见和建议吗?在开源实战中,印象深的事情是是什么?
目前从整体形势来看,国内目前的开源生态链主要还是以业务功能链为主,在基础设施领域,相对较小。目前除BAT等大公司外,在基础设施领域,基本没有有大规模的项目,或有成熟的大型项目验证过的开源组件。经常被提及的,无论是docker、k8s、kafka还是其他,基本上清一色的国外的开源组件。此外,国内在基础设施领域,目前主要集中在数据库领域,而数据库领域则受到国家解决“卡脖子”项目政策红利的引导。总体来看,国内的开源生态的还是以业务为驱动,辅以政策为导向。基础层面的,或者不在政策导向范围内的,小团队的开源项目,鲜有机会能以实际成功的大规模应用来证实自己。
至于建议,倒是有一个观点可以分享一下:在关键环节,采用更新过于频繁的项目,可能不是一个很好的注意。特别是后端基础系统,稳定是压倒一切的。更新太过频繁,特别是fix很频繁,也就意味着项目还不够成熟,问题还很多。在基础系统领域,我们一般能接受的是半年到1年更新一次。长期更新频率快于3个月的,对于基础系统来说,一般无法接受。
在开源的实战中,其实印象深刻的还是对fbThrift的使用。当时因为要开发一个能全球联网,还能承载高压高并发的的实时系统,我们当时选了当时市面上评测好的RPC框架fbThrift。但因当时(14年)fbThrift还没有正式release,所以直造成了我们的很多困扰。也直接促成了FPNN的诞生,以及后续的开源。所以一点经验就是,在开源项目还没有一个正式的release之前,或能正式承诺兼容以前版本之前,无论业界对他评价多好,选择的时候一定要谨慎。
相关文章