PPMoney微服务之路

备注:这个内容先后讲过两次:

  1. 2016-08-13 在又拍云组织的 “Open Talk No.24 广州"做过一次线下演讲

  2. 2016-10 在中生代技术群进行了一次线上分享(第三十六期)


PPmoney 微服务之路

前言

大家晚上好,今天给大家分享的内容是 PPmoney 微服务之路.

首先简单介绍一下,我是来自 ppmoney 的资深架构师 敖小剑,目前负责 ppmoney 的基础架构和服务化推进。

今天分享的内容主要有四个部分:

  • 首先,介绍了一下为什么要选择微服务架构
  • 其次,讲一下我们微服务框架的技术选型
  • 第三,介绍微服务生态中的支撑体系
  • 第四,旧有系统的迁移改造,以及开源计划

第一部分 为什么要选择微服务架构

我们先开始第一部分的内容:为什么要选择微服务架构?

先简单介绍一下我们公司——PPmoney(万惠).

4年做到600亿元,企业可以说是 野蛮生长。在快速发展的同时,沉积的问题也很多。

大多数创业公司在初期技术上是很郁闷的,没有足够的技术基础,所以早期技术栈会呈现多样化。造成多样化的原因,首先是“黑猫白猫,能上线就是好猫”:只要能把代码写出来、能上线,就OK;第二个是怎么快怎么来?包括买。举个例子,编程语言我们现在有php,.net,java,c++……

问题随即暴露,规划不足、实施艰难;需求太多,来不及规划;变更太快,规划跟不上;还有非技术的原因比如人员变动频繁。整个野蛮生长的过程中,技术债务会越来越多,开发成本会越来越高。现在在加新的功能,会比想象中的要难得多。而且,最严重的是出现了“恶性循环”。

而对于互联网金融企业,应对市场的速度必须要足够快,否则难于立足。

如漫画中所示,我们出现几个问题:

  1. 方法不得当,开发效率非常低,
  2. 问题积累,工程师不堪重负
  3. 没有时间改进,咬牙硬扛

即使给工程师现成的改进方案,他也会拒绝接受:我们很忙,我们没有时间。

这是一个令人心酸的局面,双方都很无奈。

我们改进的方向:

  1. 首先事情要规范化,让无序的开发变成有序。无序的开发是什么概念?逮到哪就做到哪,至于用什么技术:有什么人用什么,会什么用什么。有序的开发有很重要的事情,叫做“统一”,同时简化技术栈。
  2. 第二个就是要“可重用”。之前的项目都是从头开始或者是从上一个项目里头复制过来,这里面是有很多事情没有做好的:基础类库、基础设施、基础架构。做这些最终的目标是提升大家的项目起点,所谓"不要输在起跑线上”。
  3. 第三个是“敏捷”。这个东西对我们而言做得非常不好,现在基本上是属于没有的状态。虽然各个团队都在宣称敏捷,但是实际做的不太好。
  4. 第四个就是“自动化”。这个就是我们希望能改进的一个重点,包括自动化测试、自动化部署、云技术、容器化等,解决这个问题的最终的目标:摆脱低级重复。

DevOps和每日发布是我们的最终目标,虽然从目前看差距还非常大。

我们最终的选择是推行服务化,以微服务架构为目标进行技术转型。

微服务的概念和好处这里就不展开。

第二部分 dolphin 微服务框架的技术选型

接下来我们开始第二部分的内容,讲一下我们微服务框架的技术选型。

这是 PPmoney 自行开发的微服务框架,海豚,英文名 Dolphin。希望这个框架做的敏捷、轻快、优雅,就像海豚一样。

开发工作从今年3月份刚开始,目前版本到了 0.7.*,已经在线上跑了。另外后面会提到,我们最重要的一个大系统已经基于这个框架做了重构(或者说重写),即将在10月上线。

我们的小目标:打造业界一流的微服务框架。

Dolphin要打通整个业务的全流程,这个可能是跟其他微服务框架极为不同,这也是我们技术选型的一个重要的基石。

通常来说的微服务框架覆盖的都是服务器端,不同的的服务器之间的调用。但是这里我们会有一个非常重要的需求,我们必须要把手机App覆盖到。为什么要加这个需求?一个简单的数字足以说明:目前80%成交额来自于手机App。因此我们除了考虑服务器端之外,要考虑从手机App到服务器端的数据通讯。

我们希望它能覆盖日常的开发场景,包括手机App开发、Web服务器开发、应用服务。另外要实现的一个目标就是要三位一体,也就是上面这句话,“打通开发、测试、运维三条线”,实现整个流程的畅通,最终实现全程自动化。

我们看一下Dolphin的主要技术栈:

  • Google开源的gRPC框架,支持多平台多语言,最大的优点是支持手机App。
  • SpringBoot,Spring团队集大成之做,口碑非常好,好用易上手。
  • Etcd3,2016年7月1号才发布,够新鲜,主要用于服务发现和配置

首先介绍一下gPRC。这是 google 新推出来的 RPC 框架,今年8月才发布的 1.0 正式版。gPRC 的主要特性:

  • Protocol Buffer 3.0:最重要的改进就是可以支持 iOS 和 android
  • HTTP/2 协议:出来有几年了,目前正在慢慢铺开
  • netty 4.1:提供NIO支持和 HTTP/2支持,也是今年6月才刚发布的正式版本
  • 对Android/iOS的支持,这对我们来说是杀手锏级的特性

gPRC 的主要特性:

有两个特性对我们来说特别的重要:

  1. 多路复用,可以全双工发送请求和接收应答,不再需要连接池,即使几万 QPS 也是可以一条 socket 搞定。
  2. 支持流/stream,在流的基础上实现了Server Push,方便做变更通知,不再需要客户端做费力的 Long Pull。

google 给 gRPC 的地位中就明确提出:将移动和HTTP/2 放在首位。刚好契合我们的需求,因此成为我们dolphin微服务框架中最重要的一个技术选型目标。

我们选择了 Spring Boot 作为微服务框架的基石,这也是业界常见做法。暂时没有选择 spring cloud,主要是技术选项和我们差异比较大。

在3月份我们做技术选项时,在 zookeeper,etcd, consul 之间我们最后选择了 consul。但是在7月1日 etcd 的 3.0 版本发布之后,我们决定将 consul 替换为 etcd 3.0。

因为我们觉得 Etcd3 更适合 Dolophin 框架。注意我说的是更适合,不是说 etcd3 更好。

使用 etcd3 替代 consul 的几个理由:

  1. 统一通讯协议:新发布的 Etcd3 给了我们一个很大的惊喜:它的通讯机制改了,Etcd3 改用 gRPC 作为通讯机制,替代原有的rest。因为 Dolphin 框架也是使用 gRPC,因此改用 etcd3 替代 consul 之后就简化了内部通讯机制,都统一为 gRPC 了。
  2. 减少依赖:不用 consul 之后从而也省掉了 consul client 端引入的一大堆的用来实现 rest 和 long pull 的依赖包
  3. 性能提升:这个容易理解,gRPC 是二进制格式,对 REST 明显速度肯定是优势
  4. 更高效的推送机制:基于HTTP/2 stream 的服务器端推送机制,效率比基于 long pull 的高,考虑到除了服务发现之后,未来还要做配置变更的通知,而且配置项的数量远远超过服务的数量,这个带来的提升会更大。

这是目前的开发路线图,包括 dolphin 框架外围的一些基础设施,我们预计在年底前能完成微服务框架必备的大部分基础功能。

第三部分 微服务生态中的支撑体系

现在开始这次分享的第三部分,介绍微服务生态中的支撑体系。

首先给大部分正在推行微服务和想推行微服务的同学,泼一盘凉水 :)

不是有了微服务框架就足够的

把框架做好之后,是不是就可以简单的可以在一家公司里推行微服务?我遗憾地告诉大家,这个没有什么必然的关系,并不是你有了微服务的框架,就可以把后面的事情做好。用数学的术语说,微服务框架只是一个 必要不充分 条件。

微服务不是银弹,不能指望微服务单枪匹马的解决问题,“只要微服务一出来,就轻轻松松搞定。” 这种想法不现实。

左边是幻想,右边是现实。

微服务框架需要一系列的基础设施,作为整个微服务体系的基石。

这里面有些是微服务框架的标配,比如实现中央化配置管理的配置中心,管理服务实施服务治理的服务中心。有些是完全和微服务框架没有直接联系,但是又是微服务框架必备的,比如APM/应用性能监控,日志管理如ELK套件等。

在上述的基础上,还需要进一步完善整个生态体系,比如以服务的方式直接提供部分通用功能。

图中是我们在实施中的一些实际例子:

  1. 我们在 dolphin 框架中内置加密服务,限流服务,配合实现框架的基本功能。
  2. 鉴权服务,统一的短信网关,验证码服务等,这些实际和框架就没有直接关系了,而是作为通用业务平台的一部分

对于 微服务 和 docker,只能用天作之合来形容。

docker 这块我们现在涉猎的不多,暂时还处于探索阶段,后面微服务框架基本成型之后肯定要继续铺开的。

在第三部分的最后,我们总结一下实施微服务的四个要点。在微服务的实施的过程中,要真正的要把微服务做好,必须认真考量这些的足以决定成败的因素:

  1. 敏捷开发

    敏捷是必备的,如果是敏捷都没有做到,微服务真的是“连爬都还不会就想跑”。有时候微服务一上手发现不合适了,做这个东西之前先自问一下,敏捷开发是不是跑起来了,团队是不是用敏捷的方式做开发?

  2. 组织决定架构

    规划一个技术框架或者是技术路线的时候,需要考虑组织架构是不是和技术框架匹配。如康威定律所说,“组织决定架构”。为了实现服务化,你必须要让你的组织结构做出相应的调整。需要组建跨功能的团队,这个团队一定不是单纯的只有开发、只有测试、只有运维,或者是只有产品,这些功能应该都在你的团队里头。最重要的是要减少部门墙带来的沟通成本。这个墙是非常可怕的一件事情,它可以让一个小时能做的东西,一个星期都做不完。

    建议微服务团队按照业务而不是按照技术来划分组织,必须要想办法在一个团队内全栈,让团队自治。这个是我们现在试图想做的,但坦白说这个事情很难,有时甚至是绝望。

  3. 产品的思维

    一定是产品,一定不要是项目。

    产品跟项目有不同?项目是做完就项目交接,团队解散,各找各妈!产品是什么概念?这个产品是你的,你要上线,你要维护,你挖的每一个坑都会以把自己坑进去。这是一个决定责任感的事情,做产品你要吃自己的狗粮,和做项目有质的差异,这个是非常重要的事情。

  4. 团队

    所有的问题,最终都会归根到人的问题。为了玩的转微服务,你得打造一支能满足高要求的团队,这个要求是真的比较高:产品,设计、开发 、测试都要搞得定,可能是三五个人,甚至七八个人,要一个团队啃下产品线,包括前端、后端、测试、运维和产品。

对大多数公司来说,这四个要点完全做到还是挺难的。前面我们提到的服务化框架,各种技术选型,各种配套的基础设施,都是硬性条件,都是技术性的支撑。而这四点,则更多的是在人文条件方面提出的要求。

第四部分 旧有系统的迁移改造

下面我们开始最后一个部分的分享,谈一下我们最近的一个实际例子,在这个例子中我们是如何改造我们的一个App架构和团队,来实现微服务在实际产品中的落地。

这是我们的ppmoney理财App(也就是前面说的80%营收的核心产品),原有的架构足够简单而原始:

  1. app和服务器后台是常见的Restful
  2. 中间是一个巨型的服务器后台程序:很要命,因为所有代码都堆在一个WAR中
  3. 底层还好,一些基本功能被封装成SOA,难得。但是,用的语言是.net,然后通讯机制是以慢著称的SOAP

改造的第一个阶段,我们的目标是引入dolphin框架和实现基本的服务拆分:

  1. 首先app和服务器端改用gRPC
  2. 引入 API Gateway来负责网络接入,然后按照业务逻辑进行服务编排,必要时在API Gateway中可以使用缓存
  3. 将原有的war按照业务边界拆分为若干个服务,每个服务有自己的数据存储,缓存
  4. 某些服务可能只是对SOA接口做一个转发和封装汇总

这个工作我们目前基本完成,预计测试通过之后,10月份我们就会上线,逐步替代原有的APP和后台。完成之后系统的性能瓶颈可以得到极大缓解,部署弹性大为增强。

改造的第二个阶段,目标是将现有.net的SOA用Java改写,让前面拆分出来的微服务变成完整的标准微服务。

这个工作还没有开始,坦白说这个工作量比第一阶段要复杂的多,SOA中负责的业务逻辑,相互关联调用的模块耦合,一个又一个的关联查询,挑战极大。

我们再讨论一下人员和团队的问题,好的团队从来不是天上掉下来的,因此如何打造团队成为重点。

在这里我们的做法是这样,分两步:

  1. 把架构部门打造成高素质的敏捷团队

    这个是必须的,这个如果做不到,后面没得玩。

  2. 然后再孵化满足要求的新型业务开发团队

    这个地方有一个很逗的词,孵化。为什么是孵化呢?因为很多时候情况下,即使你做到了第一步,你也仅仅是有一支架构部门的团队,而且也不可能满足整个公司业务各个产品线的需要的,你还要把整个的业务线的开发团队提升上来。

    如何做到这一点很重要,要想办法自己去培养、改造业务团队。我们称之为“孵化”,就是带领一支业务团队,跟他一起去做业务改造,在改造的过程中,顺带将新的团队带起来。过程感觉就像孵小鸡一样,需要耐心,需要投入,新的团队开始很弱小,但是未来的成长值得期待和投入。

这里依然要继续给大家泼凉水,理想和现实之间的差距,往往是远超事前的想象。

下面我们以过来人的角度(其实也只是才上路),给大家分析一下微服务推进的实际道路中常见的问题和难点。

计划一开始都是很美好,但是在实施前,请先自问一个问题:资金、技术、专家,这三者是否已经齐备?

这里有个很有意思的故事:就在今年,习总书记访问英国的时候,英国BBC记者问“英企能否在中国投资建设核电站”,中国驻英大使刘晓明反问:你们有资金吗?你们有技术吗?你们有专家吗?

我们为什么要提这个话题呢?因为一个公司要真正的提升上去,也要问一下自己有没有这三个要素:

  1. 第一个是资金,你要组建团队,要在整个公司推广,把所有的流程都走通,投入巨大;
  2. 第二个是技术:前面我们罗列了一堆
  3. 第三个是专家:尤其是在业务团队,尤其是中小公司,一般业务团队只有一两个核心开发人员,有时甚至一个都微服务的都没有,更恶劣时,连一个有基本架构设计基础和模块理念的都没有

特别强调:第三点尤其致命,而且通常都是被高层忽略或者不认可,后者带来的问题更加麻烦。

注意,虽然说微服务不是银弹,但微服务真是一个大炸弹!

微服务所带来的变革是巨大的,当推行服务化,推广微服务框架的时候,远不是简单的微服务框架的技术推广问题。这个事情远比用mongo替代mysql要严重的多。推广微服务,往往是在实际上推翻整个公司的开发流程

微服务是真正意义上的颠覆性变革,或者用另外一个词会更准确:革命!

要推行微服务,要把这些东西通通跑通,而且做顺、做好,你的微服务框架才能真正落到实处。如果有一个卡住,就会发现经被念歪了,或者走路的时候感觉是腿瘸了一般。

再一次重申康威定律

对于任何一个试图推行微服务的架构师而言,康威定律是一道绕不开的槛。如果没有高层强力支持并愿意为此调整组织结构,就必然在这里遇到无法逾越的阻碍。

这个画面绝不是只会出现在漫画中…… 请做好心理准备。

最后介绍一下我们的开源计划,目前的时间计划是这样:2016年底。

但是,如果出现不可抗力,则无法预期……

个人非常的期待在年底,在github,这只可爱的小海豚可以和大家见面。

谢谢大家参与今天的分享,我们的内容到这里结束,谢谢大家!

问答环节

  • 问题1:微服务和服务化的关系是什么

    服务化是微服务的超级,服务化在很早之前就有提出并推行,典型如SOA。而微服务是最近才兴起,和服务化的最大差异在意服务化明确的将粒度调整为不能再小的"微",同时明确提出必须做到:1. 独立进程 2. 数据分离

  • 问题2: 服务治理应该包含那些内容,现在有那些工具可以用?

  • 问题3: 请比较一下各技术堆栈,如果搭建微服务,最佳工具是哪些?

    这两个问题都比较大,不是三言两语能阐述清楚,每个话题都够再来开一两回今天的演讲 ~0~

    比较巧的是,在10月15日的中生带线下活动中,我会带来一个新的演讲,主题是如何利用开源社区来搭建微服务系统,届时会有详细的介绍和讨论,欢迎关注。

  • 问题4: 使用微服务后,业务接入有没有量化数据,说明效率提升?

    暂时还没有量化数据,因为我们最大的系统还没有正式上线。只能给出一个比较有意思的数字:在过去的两个半月中,我们正在加班加点的进行前面分享的这个app后台系统的重构,标准的996,然后目前测试中,全称我们将bug控制在个位数。

  • 问题5:这个服务化框架的性能怎样?系统测试过吗?

    简单测试过,服务器端空实现在普通i5主机上跑大概能有14w的 QPS。一些典型的简单业务场景,如简单访问一两次redis,大概几万 QPS。不过现在还没有时间进行深入的性能优化。

  • 问题6:请问如何通过设计提高代码质量

    在微服务这个话题中,通过微服务的理念,将系统拆分为小的粒度,开发团队也跟随系统拆分为小的团队,开发人员可以集中在小型的系统中,这本身使得开发人员容易把握全局。简单归纳为,大事化小,分而治之。

  • 问题7:谢谢老师的分享,本人最近也在看 spring boot,java做服务动辄几百兆,我想了解一下贵司选择它是否有更深的原因

    在分享中有给出来,你可以回头翻到那页PPT,理由都列出来了。个人对 spring boot 非常认可,使用方便,而且 spring 会的人也多。

  • 问题8:1.前面讲到的规范化,可重用,真敏捷,自动化也是架构师在推吗?2.你对docker什么看法?

    1. 是的,也是我们基础架构部门在力推。2. 我对docker很认同,和微服务简直是绝配,下一步必然要上docker的。
  • 问题9:grpc 没有服务治理的部分 这部分你们有什么好的实践嘛?

    grpc 有 name resolver,我们用来实现基于 etcd3 的服务注册和服务发现。另外 grpc 内建了负载均衡的支持,1.0版本之后基本可以拿来用了。我们最早在 0.10版本的时候这两个组件都不完善,我们放弃了他们自己实现了,但是1.0之后现在打算换回 grpc 自己的实现。其他的服务治理功能,打算自己动手,当然如果开源社区有合适的组件,我们会在评估之后直接拿来用。

  • 问题10:你上马那么多技术,都是新技术,有没有考虑过这些技术的升级给你带来的影响?

    这是一个非常尖锐的问题。坦白说,在今年三月我决定选择自己搭建微服务框架,而不是继续dobbo,然后又选择了grpc/consul(后来换成etcd3)等新技术时,风险是非常大的。当时这几个项目都还是beta甚至alpha状态,我们比较幸运的时在最近几个月,grpc 1.0/netty 4.1/protocol buffer 3.0/etcd 3.0,这几个最重要的技术栈都陆续正式发布,而我们最大的重构项目10月才上线。有种很幸运的感觉。

  • 问题11: etcd3是做什么的,感觉没怎么用过,使用场景是什么和dubbo+zookeeper相比有什么不同

    etcd 和 zookeeper 类似,都是实现分布式的一致性,不过 etcd 底层是 Raft 协议,稍微简单一些。

    etcd 3.0 是 etcd 最新的版本,因为通讯协议从rest换成了grpc,所以我们在最后时刻选择了它。

  • 问题12:“通常来说的微服务框架覆盖的都是服务器端,不同的的服务器之间的调用。但是这里我们会有一个非常重要的需求,我们必须要把手机App覆盖到。” 为什么要加这个需求? 请问一下这个怎么理解?框架层面做了些什么呢?

    不是要加这个需求,而是我们本来就有这个需求。分享中我们给出了一个数字,80%,这是我们手机app端占我们总的业务量的比例。因此我们在选型时,特别认同google对grpc的定位和要求。框架层面自然是以grpc为主要通讯协议,统一了app端到服务器端,和服务器端内部之间的通讯,由于etcd3的缘故,现在服务注册和配置管理也是统一为grpc了,这算是个意外,令人高兴的意外。

  • 问题13:微服务的粒度怎么划分,能结合业务场景简要说明下吗

    这个问题还是太大,有机会单独再出一个专题来讨论和分享。坦白说,现在我们自己也是在摸索,在实践中调整。

  • 问题14:“底层还好,一些基本功能被封装成SOA,难得。但是,用的语言是.net,然后通讯机制是以慢著称的SOAP”,soap的性能虽然很低,但是可以提供企业级的安全特性,而且支持原子事务,这方面在互联网金融的应用场景下是怎么考虑的?

    实际中我们现在的老系统,SOAP的这些特性都没有使用上。关于安全,我们会使用标准的SSL加密,这个grpc有支持,然后我们会搭建自己的鉴权服务。事务方面,现在主要还是尽量用数据库事务做强一致性,或者事后补偿来实现最终一致性。这块我们目前还没有形成足够完善的机制,后续努力中。如有所得,再来和大家讨论。

  • 问题15:微服务的力度如何把控,拆分过细会影响性能

    这个问题和前面的问题13类似,以后再细聊。的确在度的把握上,有很多讲究,需要权衡很多因素,除了业务边界和领域模型之后,性能,事务,安全都是需要考虑的。

  • 问题16:用thrift如何?

    我们选择 grpc 的一个重要因素是因为 grpc 支持 android 和 iOS,这是决定性的因素。另外 grpc 基于 HTTP/2 实现的 流 也是一大杀手锏,做服务器端推送优势太明显。再有就是不再需要多个连接和连接池,也简化了很多问题。thrift 理论上性能要稍微高一些,不过 grpc 也足够用了。

片尾曲

最后做一下广告, dolphin 框架使用了很多目前业界最新(绝不夸张)的技术栈,很多基本都没有中文资料,因此我自己写了一些学习笔记,里面翻译了部分这些技术的英文文档,如果感兴趣可以一起研究:

敖小剑
敖小剑
新时代农民工 * 中年码农

我目前研究的方向主要在Microservice、Servicemesh、Serverless等Cloud Native相关的领域,全职从事Dapr开发,欢迎交流和指导。