腾讯QQ团队开源分布式后台毫秒服务引擎全解析:引擎架构、RPC、灰度……

腾讯QQ团队将于12月4日开源一个服务开发运营框架,叫作毫秒服务引擎(Mass Service Engine in Cluster,MSEC),它集RPC、名字发现服务、负载均衡、业务监控、灰度发布、容量管理、日志管理、Key-Value存储于一体,目的是提升开发与运营的效率和质量。程序员

毫秒服务引擎的创做冲动和构建经验,来自QQ后台团队超过10年的运营思考。它是一整套解决方案,但也能够拆分来使用其中的监控、Key-Value存储单品。算法

典型用户群体

毫秒服务引擎很是容易搭建和上手,使用它,初学者从零开始开发一个分布式后台demo并运行起来,只须要2个小时。基本上是一个小时完成框架搭建,一个小时完成开发上线,特别适合互联网初创公司。shell

功能与优点

模块间访问采用RPC的方式,开发者不用关注网络与报文格式,像写单机程序同样开发分布式服务。缓存

  1. 负载自动均衡与容错,对于单机故障、局部网络波动等情况自动应对,服务高可用性。
  2. 支持C/C++、Java、PHP语言,立刻还会推出支持Python语言;若是选择C/C++语言,支持协程,兼具开发和运行效率。
  3. Web化的管理界面,在Web界面完成配置、发布、监控、日志、Key-Value存储集群管理等全部操做。
  4. 须要复杂部署的服务器都采用Docker镜像的方式安装,使得部署与上手很是容易。
  5. 相比使用其余开源组件拼凑起来的解决方案,毫秒服务引擎更加的体系化,对团队的规范更加到位。

毫秒服务引擎设计背景

对于互联网服务后台团队,开发框架的选择是很是关键的问题,10年的海量服务经验和教训使得咱们团队深入认识到:服务器

  1. 要尽早规范团队的开发服务框架,避免到了后期,各类开发语言混杂、各种存储组件充斥、重复编码、每一个模块形态不统1、文档缺失、监控瘫痪、人员离职形成大量信息丢失,最后积重难返、痛苦不堪;
  2. 没有框架来规范,团队的随意性就太大,合做效率就大打折扣,甚至于内耗、反复的挖坑填坑,系统的成败过于依靠人的意识和水平;
  3. 规范,不能靠文档、不能靠劳动纪律、不能靠苦口婆心、不能靠人员意识、不能靠运动式的整顿,要靠技术框架上切实的限制与贴心保护。

若是有机会从零开始定义一个理想的开发框架,咱们以为须要考虑下面9点。网络

  1. 同步编码异步执行。兼顾运行效率和编码效率,但愿代码写起来是同步和顺序的,而执行的时候是异步的。
  2. IDL/RPC。支持IDL(接口描述语言)和RPC,减小网络协议相关的重复工做,协议有比较好的扩展性;远程调用友好且高效,作到覆盖主要的开发语言。
  3. LB。对服务间的调用选路进行统一的管理,对单机故障和网络波动等常见状况有自动容错,咱们简称load balance(LB)。
  4. 存储服务化。这个其实和开发框架关系不太紧密,这里提一下,强调存储应该有统一的组件且由专业的团队运维,就像共有云同样。
  5. 过载保护。框架必须有成熟自带的过载保护机制,不须要业务开发人员关注或者关注不多。
  6. 基础的监控和告警。RPC调用、机器的CPU/网络活动、任务并发度、时延、进程监控和秒起等基础信息,要有上报、统计和告警,不须要业务开发人员关注。
  7. 完整的业务流转呈现。统一日志,在一个地方可以清晰的呈现某次业务处理过程的流转详细状况:通过了哪些模块间调用,调用参数是怎样的,每一个模块处理的重要分支和结果是怎样的,最好图形化呈现。支持染色和不一样的日志详细级别。
  8. 中央总控。整个系统的配置和文档等重要信息,例如每一个模块有哪些机器,分布在哪些机房、容量冗余状况、模块间调用关系、访问控制的配置动态管理甚至电子流,都但愿能统一在一个地方Web化的管理起来,而且与运营的系统是直接联系直接生效的。
  9. 云调度。容量的自动调度。例如要进行某个运营活动须要大量的扩容,只须要把设备放进去,就能自动的扩缩容。当某个城市机房故障,可以自动调度容量到其余城市。

毫秒服务引擎架构

整个系统由下面几部分组成,如图所示。 数据结构

**Web Console:**整个系统的运营管理中心,包括:

  • Tomcat提供Web管理界面,管理的数据保存在MySQL里。架构

  • LB是名字发现服务和负载均衡,remote_shell是远程文件传输与远程命令执行服务。并发

**Log服务器:**提供业务Log的存储和查询服务。Log存储在MySQL表里。负载均衡

**Monitor服务器:**提供业务上报信息的存储和查询服务。业务上报信息存储在内存里,推荐内存8G~16G。定时dump到磁盘的方式防止数据掉电丢失。

**业务运营服务器:**部署开发框架和业务逻辑代码,处理业务请求。

**key-value存储服务:**相对整个框架比较独立,按需选用。

服务标准化运营

一套互联网后台服务的开发和运营涉及很是多的细节。

  1. 访问其余服务模块,服务端IP如何管理?网络报文格式是怎样的?

  2. 有哪些配置文件? 用到哪些第三方的库?

  3. 业务逻辑和基础框架是如何分离的?

  4. 对外提供怎样的网络接口?怎么对外提供接口API和文档?

  5. 运营机器上的安装目录准备怎么安排? 有哪些运维脚本和工具?

  6. 应该监控哪些指标?应该记录哪些日志?

  7. 还有不少…

上面种种细节,每一个程序员实现起来都有不一样的作法。经验证实,若是后台各个模块没有标准化和规范化,可能致使:同一个团队开发的服务,千差万别千奇百怪,负责运维的同事面对的多个模块“长”的都不同,程序框架彻底不同,安装目录乱七八糟,没法规模化的高效运维。

服务的质量彻底依赖团队成员的技能和意识,有的成员可能会作得比较好,配置文件命名易懂、文档及时更新与代码保持一致、有对服务作细致的监控上报和日志记录,提供了运维脚本,可是也有的成员的工做让人抓狂。

每当有团队成员离职和工做交接,交接自己就是工做量很大,交接时间长,交接质量很差,文档缺失,不少信息在交接过程当中丢失,运营事故每每频发。

经验难以获得传承,一块石头反复绊倒各个成员和业务模块,运营事故雷同、频出,团队挫折感倍增、服务可用性低下。

也曾经有过作事比较规范的时候,可是这些规范一般靠耳提面命、人口相传,靠管理者运动式的整顿,有时候管理焦点没有持续跟进,或者随着人员更替,团队又把这些宝贵的经验丢弃了,变得无序。

因此服务标准化是后台技术团队组建开始的第一要务。

两个误区

**误区一:**找几个开源的组件用起来就行了呗。

  • 一般的开源的组件,只是在某一方面上规范了服务,有的是规范了网络调用,有的是规范了如何监控,有的是规范了如何记录远程记录,其实这还远远不够,例如配置文件、接口定义、使用到的外部库、安装目录的结构等很是多的细节,必须统一管理、有惟一出处。

**误区二:**你说的我都懂,咱们团队刚起步,业务需求多,时间紧,先野蛮生长,打破条条框框,后面再规范再改。

  • 一开始没有标准化,后面当代码和模块都多起来了,且都处于运营状态,再改再标准化,难度很是大,成本很是大,风险很是大;另外工欲善其事必先利其器,一开始就标准化好,其实可让业务跑的更快。

如何实现服务标准化?

首先,每一个服务的配置都Web化、集中管理起来。

部署在哪些IP上?

有且只有一个配置文件。
Protocol buffer的接口定义文件。
引用了哪些外部库?例如openssl。
业务逻辑和基础框架分离,业务逻辑以插件形式提供。
而后,每一个业务模块部署的目录结构都是肯定的。
如上图所示:

  • 业务部署的目录都是/msec/一级业务名/二级业务名;

  • 都包含bin etc log 等几个目录;

  • bin里面是启停脚本、业务插件msec.so和外部库(若是有);

  • etc里面是配置文件config.ini;

  • Log里面是本地的日志文件。

另外,程序员不能随意打破上面的方式。例如临时的另外搞一个本身配置文件什么的,他若是这样作,那下次发布的时候目录会被覆盖,个性化的东西会被删除掉。

后台服务的RPC和路由管理

互联网服务的后台,硬件一般是由大量的廉价机器组成;软件架构一般采起大系统小作、分而治之的思想。这就决定了业务逻辑涉及到大量的网路IO,同时单机故障、网络局部故障是运营的常态。那么,RPC和路由管理就显得尤为重要了。毫秒服务引擎为此提供了一个完整的解决方案。

  • RPC的概念其实出现已经好久了,记得笔者读大学的时候,接触到RPC的概念,总以为不重要,画蛇添足。 我掌握好Socket通讯这个利器和TCP/IP协议族原理,什么功能不能实现?

  • RPC就跟本地函数调用同样写代码,确实开发效率比较高;我本身把Socket相关函数好好封装一下,让代码复用起来,开发效率也很高。

  • 不懂或者不关注网络通讯底层原理,光会函数调来调去,这样的程序员太没有出息了!

后来,笔者开始带团队,亲身经历了一些团队协做和IT服务运营过程当中的故事,才发现RPC很是关键。若是没有很好的实现RPC和路由管理,IT系统服务质量会过分的依赖人的意识,而这个一般成本很是高、效果也很差。

毫秒服务引擎是怎么作的?

首先,毫秒服务引擎将每一个服务部署在哪些IP上这些信息集中管理起来,即便是调用外部的非标准服务(咱们叫异构服务),也须要将该外部服务的接口IP配置到毫秒服务引擎管理系统里。这样涉及到的IP信息就不会散落在代码和各类配置文件里了。

服务之间的调用,统一采用CallMethod()函数的方式,避免代码千奇百怪;按服务名字调用和接口名调用。
RPC背后的路由算法对于单机故障、网络局部波动等异常,自动容错。简单的说,路由算法按必定的规则轮转的选择被调用模块的接口机,并统计过去一段时间的调用成功率、时延信息,根据这些信息调整该接口机被选择到的比例。若是某个接口机故障了,那么就不会发送请求给它,从而实现自动容错。

毫秒服务引擎框架自己,在RPC执行的时候,就上报了不少基础属性和日志,这样保证了服务监控和告警等运营措施不依赖与人的意识。下图是叫作getMP3List这样一个RPC调用的请求数和成功数,这些是不须要业务开发者工做就自动上报。

每一个请求有惟一ID来标识,经过该ID,毫秒服务引擎能够在框图中直观的呈现该请求通过的模块、模块间的RPC名字等信息,这个一样不须要业务开发者的工做就自动实现。

后台服务的灰度发布与监控

灰度发布和监控是互联网海量服务必备的两大利器,可以极大提升后台服务可用性和运营水平,背后的哲学是持续交付、用户测试和尽在掌控。

在腾讯,有一个课程系列,叫作《海量服务之道》,包含十多门课程和方法论,是技术同事必修和必知必会的,其中两门课程就是《灰度发布》和《全方位监控》。

笔者在加入腾讯QQ后台团队以前,曾经在电信行业、金融行业作过几年开发工做。刚进入腾讯时,以为技术上不少地方让人耳目一新。

  • 后台系统都是部署在很是多的廉价服务器上,每一个人都会管理很是多的机器,让人以为颇有成就感很富有。

  • 有比较精确的设备预算计算模型,每一个服务器的性能在考虑容灾冗余的前提下,一般被压榨到刚恰好,负责人会深刻的洞悉整个系统的性能、容灾、柔性等方方面面。能负责一个海量的系统是很荣耀的一件事情。

  • 没有专职的测试人员,通过开发者自测后,灰度发布加详细的监控,主要的系统几乎每两周都会被发布一轮,做为后台技术人员,本身的工做直接影响数以亿计的用户,有点手握核弹处于上帝视角的感受。

  • 监控系统(咱们内部一个叫monitor的系统)真的是太方便了,一条条曲线直观的展现整个系统运做的各类指标,若是有异常短信和电话就会响起来,让人以为一切尽在掌控,有一种面对着大量仪表盘操控着航母游弋或者是战斗机挂着核弹翱翔的感受。

好了,赶忙结束程序员意淫的美好感受,我想说的重点是:灰度发布和监控真的是互联网海量服务必备的两大利器,可以极大的提升后台服务可用性和运营水平。

固然,灰度发布不仅是一部分一部分的发布新代码,监控也不仅是绘制曲线和告警短信那么简单,这里面深究下去会有不少东西,背后的哲学是持续交付、用户测试和尽在掌控。

毫秒服务引擎是怎么作的?

#####灰度发布 在服务配置管理页点击“制定发布计划”。

选择这一次灰度要发布的目标机器和发布类型。
在接下来的向导中选择正确版本的配置文件、外部库、业务插件等,这样就完成了发布计划的制做。
接着,点击菜单 “运维->发布”,能够查询全部发布计划,对于已经发布的计划,能够作回滚操做。点击详情能够查看发布计划更详细信息,并执行发布。

监控

关于监控,在“RPC和路由管理”那里讲得已经比较详细了,这里不赘述。只说明一下:除了RPC和框架自己自动上报的一些信息,还支持业务自定义上报信息(例如我想上报第28级VIP用户登陆的次数),且支持对于关键指标的波动、最大值、最小值设置告警。

KV存储集群的设计要点

Key-Value存储系统,是很是广泛的需求,几乎每一个在线的互联网后台服务都须要KV存储,咱们团队在KV存储方面,经历过几个时期,我本身深感要作好不容易。

第一个时期,很早期的时候,咱们的数据存储在MySQL表里,按照用户帐号简单的分库分表,为了保证访问高并发,利用每一个MySQL服务器的内存作数据缓存;主备两套分布在不一样IDC,业务逻辑本身作副本同步。当时主要的问题是:内存的数据结构扩展困难、运维工做琐碎、数据同步机制自己的缺陷致使不能作异地IDC部署,这些缺点对于业务飞速发展、一地机房已经不够用的局面很是被动。

第二个时期,咱们设计了新的KV存储系统,其用户数据结构容易扩展、具有能够多地部署的数据同步机制,很好的应对了新时期业务发展的须要。为了设备成本考虑,咱们把数据作冷热分离,访问频繁的数据会加载到专门的Cache层,且对于不一样的访问模型,挂载不一样架构的Cache,另一个File层专门作数据持久化。这样的设计,使得架构太复杂,bug收敛速度慢,运维工做相比之前甚至更复杂了。

第三个时期,为了应对广泛的KV存储需求,咱们以公共组件的形式从新设计了KV存储,做为团队标准的组件之一,获得了大规模的应用。结合同期抽象出来的逻辑层框架、路由管理等其余组件,团队的公共基础组件和运维设施建设的比较完备了,整个业务的开发和运维实现了标准化。但这个阶段就用了咱们团队足足2年多时间。

不一样于无数据的逻辑层框架,KV存储系统的架构设计会更复杂、运维工做更繁琐、运营过程当中可能出现的情况更多、bug收敛时间会更长。一句话:团队本身作一个KV存储系统是成本很高的,并且也有比较高的技术门槛。

设计一个KV存储,须要考虑至少这些方面。

  1. 如何组织机器的存储介质,一般是内存、磁盘文件;例如用hash的方式组织内存。

  2. 如何设计用户的数据结构,使得通用、易于扩展、存储利用率高;例如PB序列化、Json、XML方式。

  3. 友好的访问接口,而不仅是get/set一整个value。

  4. 如何作集群分布、如何sharding、如何作到方便的扩缩容;例如一致性hash算法。

  5. 如何作数据冗余、副本间如何同步、一致性问题;副本间如何选举master。

  6. 备份与恢复、数据校验与容错。

  7. 读写性能。

  8. 其余可能的特殊需求:例如咱们设计过一个KV存储,用于存储一些公众号的个数不受限粉丝列表。

上面8点,业内的KV存储组件通常都会考虑到,或者各有特点,各自优点在伯仲之间。可是综合过去的经验教训,咱们以为有一点很容易被忽视:可运维性、运维自动化、黑盒化运维。

举一个例子,前面提到的咱们第二个时期的KV存储系统,刚开始应用的时候,一次扩容过程会有10多步的运维操做,包括load数据、作增量同步、屡次修改机器状态、数据比对等等,须要运维同事以高度的责任心来完成。另外就是运维同事必须如该KV存储架构设计者同样深入理解系统背后的原理和细节,不然就不能很好的执行运维操做,这个要求也很是高,新老交接周期长,还容易出运维事故。

基于上面的考虑,同事为了让用户更容易学习和接受,毫秒服务引擎在Redis Cluster的基础上,实现了运维Web化,并加上了集群的监控。

经过Web界面方便进行

集群概要状态查看。

能够在Web上方便的完成平常的运维操做:新搭集群、扩缩容、故障机器的恢复。
请求量、内存使用、CPU等各类状态信息可直观监控,也能够按IP粒度查看。
相关文章
相关标签/搜索