滴滴杜欢大型微服务框架设计实践

来自:滴滴技术

桔妹导读:在不久前的GopherChina大会中,滴滴高级专家工程师杜欢以《大型微服务框架设计实践》为主题的深度分享。小编在此整理成文,与大家分享。

————

大家好,我是杜欢,很荣幸能代表滴滴来做分享。我来滴滴的 件事情就是帮助公司统一技术栈,在服务端我们要把以前拿PHP和Java做的服务统一起来,经过很多思考和选择之后我们决定用Go来重构大部分业务服务。现在,滴滴内部已经有非常多的用Go实现的服务和大量Go开发者。

《?型微服务框架设计实践》是一个很大的话题,这个题目其实分为三个方面,“微服务框架”、“大型”和“设计实践”。我们日常看到的各种开源微服务框架,在我看来都不算“大型”,解决的问题比较单纯。大型微服务框架究竟是什么,又应该怎么去一步步落地实践,我会从问题出发,分别从以下几个方面来探讨这个话题。

?发现问题:服务开发过程中的痛点

?以史鉴今:从服务框架的演进历程中找到规律

??道?简:?型微服务框架的设计要点

?精雕细琢:框架关键实现细节

▍发现问题:服务开发过程中的痛点▍复杂业务开发过程中的痛点

我们在进行复杂业务开发的过程中,有以下几个常见的痛点:

?时间紧、任务多、团队?、业务增?快,如何还能保证架构稳定可靠?

?研发?平参差不?、项?压??顾不暇,如何保证质量基线不被突破?

?公司有各种?具平台、SDK、 实践,如何尽可能的在业务中使??

互联网业务研发的特点是“快”、“糙”、“猛”:开发节奏快、质量较粗糙、增长迅猛。我们能否做到“快”、“猛”而“不糙”呢?这就需要有一些技术架构来守住质量基线,在业务快速堆砌代码的时候也能保持技术架构的健康。

在大型项目中,我们也经常会短时间聚集一批人参与开发,很显然我们没有办法保证这些人的能力和风格是完全拉齐的,我们需要尽可能减少“人”在项目质量中的影响。

公司内有大量 的技术平台和工具,业务中肯定是希望尽可能都用上的,但又不想付出太多的使用成本,必定需要有一些技术手段让业务与公司基础设施无缝集成起来。

很自然我们会想到,有没有一种“框架”可以解决这个问题,带着这个问题我们探索了所有的可能性并找到一些答案。

▍以史鉴今:从服务框架的演进历程中找到规律

▍服务框架进化史

服务框架的历史可以追溯到年,PHP在那一年诞生。PHP是一个服务框架,这个语言首先是一个模板,其次才是一种语言,默认情况下所有的PHP文件内容都被直接发送到客户端,只有使用了?php?标签的部分才是代码。在这段时间里,我们也称作Web.0时代里,浏览器功能还不算强,很多的设计理念来源于C/S架构的想法。这时候的服务框架的 是00年推出的ASP.net,当年真的是非常惊艳,我们可以在VisualStudio里面通过拖动界面、双击按钮写代码来完成一个网页的开发,非常具有颠覆性。当然,由于当时技术所限,这样做出来的网页体验并不行,最终没有成为主流。

接着,Web.0时代来临了,大家越来越觉得传统软件中经常使用的MVC模式特别适合于服务端开发。Django发布于年,这是一款非常经典的MVC框架,包含了所有MVC框架必有的设计要素。MVC框架的 当属RubyonRails,它给我们带来了非常多先进的设计理念,例如“约定大于配置”、ActiveRecord、非常好用的工具链等。

年后,各种MVC架构的服务框架开始井喷式出现,这里我就不做一一介绍。

▍标志性服务框架

随着互联网业务越来越复杂,前端逻辑越来越重,我们发现业务服务开始慢慢分化:页面渲染的工作回到了前端;Model层逐步下沉成独立服务,并且催生了RPC协议的流行;业务接入层只需要提供API。于是,MVC中的V和M逐步消失,演变成了路由框架和RPC框架两种形态,分别满足不同的需求。年,Sinatra发布了,它是一个非常 的纯路由框架,大量使用middleware设计来扩展框架能力,业务代码可以实现的非常简洁优雅。这个框架相对小众(GithubStars0k,实际也算很有名了),其设计思想影响了很多后续框架,包括Express.js、Gomartini等。同年,Thrift开源,这是Facebook内部使用RPC框架,现在被广泛用于各种微服务之中。Google其实更早就在内部使用Protobuf,不过直到年才首次开源。

再往后,我们的基础设施开始发生重大变革,微服务概念兴起,虚拟化、docker开始越来越流行,服务框架与业务越发解耦,甚至可以做到业务几乎无感知。08年刚开源的Istio就是其中的典型,它专注于解决网络触达问题,包括服务治理、负载均衡、动态扩缩容等。

▍服务框架的演进趋势

通过回顾服务框架的发展史,我们发现服务框架变得越来越像一种新的“操作系统”,越来越多的框架让我们忘记了Web开发有多么复杂,让我们能专注于业务本身。就像操作系统一样,我们在业务代码中以为直接操作了内存,但其实并不然,操作系统为我们屏蔽了总线寻址、虚地址空间、缺页中断等一系列细节,这样我们才能将注意力放在怎么使用内存上,而不是这些跟业务无关的细节。

随着框架对底层的抽象越来越高,框架的入门门槛在变低,以前我们需要逐步学习框架的各种概念之后才能开始写业务代码,到现在,很多框架都提供了非常简洁好用的工具链,使用者很快就能专注输出业务代码。不过这也使得使用者更难以懂得框架背后发生的事情,想要做一些更深层次定制和优化时变得相对困难很多,这使得框架的学习曲线越发趋近于“阶跃式”。

随着技术进步,框架也从代码框架变成一种运行环境,框架代码与业务代码也不断解耦。这时候就体现出Go的一些优越性了,在容器生态里面,Go占据着先发优势,同时Go的interface也非常适合于实现duck-typing模式,避免业务代码显式的与框架耦合,同时Go的语法相对简单,也比较容易用一些编译器技巧来透明的增强业务代码。

▍?道?简:?型微服务框架的设计要点▍站在全局视角观察微服务架构

服务框架的演进过程是有历史必然性的。

传统Web网站最开始只是在简单的呈现内容和完成一些单纯的业务流程,传统的“三层结构”(网站、中间件、存储)就可以非常好的满足需求。

Web.0时代,随着网络带宽和浏览器技术升级,更多的网站开始使用前端渲染,服务端则更多的退化成APIGateway,前后端有了明显的分层。同时,由于互联网业务越来越复杂,存储变得越来越多,不同业务模块之间的存储隔离势在必行,这种场景催生了微服务架构,并且让微服务框架、服务发现、全链路跟踪、容器化等技术日渐兴盛,成为现在讨论的热点话题,并且也出现了大量成熟可用的技术方案。

再往后呢?我们在滴滴的实践中发现,当一个公司的组织结构成长为多事业群架构,每个事业群里面又有很多事业部,下面还有各种独立的部门,在这种场景下,微服务之间也需要进行隔离和分层,一个部门往往会需要提供一个API或broker服务来屏蔽公司内其他服务对这个部门服务的调用,在逻辑上就形成了由多个独立微服务构成的“大型微服务”。

在大型微服务架构中,技术挑战会发生什么变化?

据我所知,国内某一线互联网公司的一个事业群里部署了超过0,个微服务。大家可以思考一下,假如一个项目里面有0,个class并且互相会有各种调用关系,要设计好这样的项目并且让它容易扩展和维护是不是很困难?这是一定的。如果我们把一个微服务类比成一个class,为了能够让这么复杂的体系可以正常运转,我们必须给class进行更进一步的分类,形成各种class之上的设计模式,比如MVC。以我们开发软件的经验来看,当开发单个class不再成为一件难事的时候,如何架构这些class会变成我们设计的焦点。

我们看到前面是框架,更多解决是日常基础的东西,但是对于人与人之间如何高效合作、非常复杂的软件架构如何设计与维护,这些方面并没有解决太好。

大型微服务的挑战恰好就在于此。当我们解决了最基本的微服务框架所面临的挑战之后,如何进一步方便架构师像操作class一样来重构微服务架构,这成了大型微服务框架应该解决的问题。这对于互联网公司来说是一个问题,比如我所负责的业务整个代码量几百万行,看起来听多了,但跟传统软件比就没那么吓人。以前Windows7操作系统,整体代码量一亿行,其中 的单体应用是IE有几百万行代码,里面的class也有上万个了。对于这样规模的软件要注意什么呢?是各种重构工具,要能一键生成或合并或拆分class,要让软件的组织形式足够灵活。这里面的解决方法可以借鉴传统软件的开发思路。

▍大型微服务框架的设计目标

结合上面这些分析,我们意识到大型微服务框架实际上是开发人员的“效率产品”,我们不但要让一线研发专注于业务开发,也要让大家几乎无感知的使用公司各种基础设计,还要让架构师能够非常轻易的调整微服务整体架构,方便像重构代码一样重构微服务整体架构,从而提升架构的可维护性。

公司现有架构就是业务软件的操作系统,不管公司现有架构是什么,所有业务架构必须基于公司现有基础进行构建,没有哪个部门会在做业务的时候分精力去做运维系统。现在所有的开源微服务框架都不知道大家底层实际在用什么,只解决一些通用性问题,要想真的落地使用还需要做很多改造以适应公司现有架构,典型的例子就是dubbo和阿里内部的HSF。为什么内部不直接使用dubbo?因为HSF做了很多跟内部系统绑定的事情,这样可以让开发人员用的更爽,但也就跟开源的系统渐行渐远了。

大型微服务框架是微服务框架之上的东西,它是在一个或多个微服务框架之上,进一步解决效率问题的框架。提升效率的核心是让所有业务方真正专注于业务本身,而不是想很多很重复的问题。如果0,个服务花5,人维护,每个人都思考怎么接公司系统和怎么做好稳定性,就算每次开发过程中花0%的时间思考这些,也浪费了5,人的0%时间,想想都很多,省下来可以做很多业务。

▍Ruleofleastpower

要想设计好大型微服务框,我们必须遵循“Ruleofleastpower”(够用就好)的原则。

这个原则是由WWW发明者TimBerners-Lee提出的,它被广泛用于指导各种W3C标准制定。TimBL说, 的设计不是解决所有问题,而是恰好解决当下问题。就是因为我们面对的需求实际上是多变的,我们也不确定别人会怎么用,所以我们要尽可能只设计最本质的东西,减少复杂性,这样做反而让框架具有更多可能性。

Ruleofleastpower其实跟我们通常的设计思想相左,一般在设计框架的时候,架构师会比较倾向于“大而全”,由于我们一般都很难预测框架的使用者会如何使用,于是自然而然的会提供想象中“可能会被用到”的各种功能,导致设计越来越可扩展的同时也越来越复杂。各种软件框架的演进历史告诉我们,“大而全”的框架最终都会被使用者抛弃,而且抛弃它的理由往往都是“太重了”,非常具有讽刺意味。

框架要想设计的“好”,就需要抓住需求的本质,只有真正不变的东西才能进入框架,还没想清楚的部分不要轻易纳入框架,这种思想就是Ruleofleastpower的一种应用方式。

▍大型微服务框架的设计要点

结合Ruleofleastpower设计思想,我们在这里列举了大型微服务框架的设计要点。

最基本的,我们需要实现各种微服务框架必有的功能,例如服务治理、水平扩容等。需要注意的是,在这里我们并不会再次重复造轮子,而是大量使用公司内外已有的技术积累,框架所做的事情是统一并抽象相关接口,让业务代码与具体实现解耦。

从工具链层面来说,我们让业务无需操心开发调试之外的事情,这也要求与公司各种进行无缝集成,降低使用难度。

从设计风格上来说,我们提供非常有限度的扩展度,仅在必要的地方提供interceptor模式的扩展接口,所有框架组件都是以“组合”(







































治白癜风的外用药
治白癜风的外用药



转载请注明:http://www.xxcyfilter.com/zytd/9870.html