微服务是传统企业电商解决方案的银弹吗?成功实施微服务的先决条件挑战和风险业务方面的思考演进路线结论

近几年,微服务成为最流行的技术名词之一,尤其受到亚马逊、阿里等电商巨头的影响,很多传统企业在实施电商过程中也纷纷往微服务架构靠拢,相比单体架构,微服务确实有很多优点,就像 Sam Newman 在“Building Microservices”[1] 中所阐述的那样:

技术异构性

弹性

伸缩性

容易部署

但是计算机科学作为一门平衡的科学,任何技术架构在带来收益的同时也会有其局限性,作为系统架构师或者决策人员,一定要对此有清醒的认识。本文将重点阐述成功实施微服务的先决条件,所面临的主要挑战和风险,传统企业在实施电商过程中的决策要素以及正确的实施策略。BTW,作者本人对微服务没有任何成见,我在 amazon 工作期间一直接触的就是微服务架构,而且本人也是 Adrian Cockcroft 的超级粉丝。所以各位微服务控们千万不要拍砖。

成功实施微服务的先决条件

一般而言,成功实施微服务的先决条件包括:

匹配的组织架构

实力雄厚的技术团队(包括开发 / 测试 / 运维)

清晰的业务边界

其中第一条换个洋气点的说法就是康维定律(Conway’s Law[2]),这是我最喜欢的定律之一,现实中接触到的各个案例无一例外:

"organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations."

康维定律简单来说,就是任何软件都反映出制造它的团队的组织结构,这是因为人们会以反映他们组织形式的方式工作。 换句话说,采用微服务架构的组织结构也应该是分散的。看看现实中成功实施微服务的那些公司:Amazon、Netflix、阿里那个不是分散的组织结构。

至于后面两条的原因我将在下面一节深入探讨。

挑战和风险

 更长的学习曲线

主要包括:

除了需要了解业务逻辑外,也需要花大量精力去学习底层微服务框架提供的各种服务并遵从其契约,以下图为例,为了实施一个基于微服务架构的电商,技术团队需要掌握以下:

业务逻辑及其之间的接口

基于容器的部署和工具,比如 Docker、Kubernetes 等

微服务框架本身的学习,包括 API 网关、服务发现和注册机制、熔断、分布式配置等等

甚至背后的理论 / 设计模式,诸如 CAP、BASE 等等

更多的开发 / 测试工作

例如:

因为常见微服务架构都是每个服务拥有自己的数据库,导致需要跨表实现统计报表等功能将变得很复杂

对于哪些需要依赖其他微服务的微服务开发及测试,你不得不在本地也安装所有需要依赖的微服务,即使采用 Docker 容器,根本问题并没有改变,与单体服务的开发相比较而言,开发测试变得很繁琐

代码本身也要遵从微服务框架的各种契约,例如一个使用 Hystrix 熔断机制的代码如下:

@ServicepublicclassMyService{@AutowiredRestTemplate restTemplate;@HystrixCommand(fallbackMethod ="errorHandler")publicString myService(String name) {returnrestTemplate.getForObject("http://MYSERVICE/myservie?name="+name,String.class);}publicString errorHandler(String name) {return"There is an error for service "+name;}}

 重构的代价

由于各种原因(特别是在对业务的理解不够或者业务变动频繁的情况下),已经上线的微服务发现并不合适从而需要重构,例如需要把计价服务重新合并回产品服务,至少遵循以下步骤(请参考下图):

首先在产品数据库中建立与计价有关的表,建立导入工具吧计价数据库中的数据导入到产品数据库中,需要注意的是,如果产品服务和计价服务采用不同的数据库,还需要额外的开发成本编写导入工具。在本步骤完成后,产品服务并不提供任何计价功能,只是所有计价服务中的数据会被不断(同步或异步)导入到产品数据库中。

在产品服务中引入计价功能并暴露相应接口,在充分测试后配置 API 网关(如 Zuul 或者 Istio)对计价功能调用进行分流,期间所有流入老的计价数据库的数据依然会被导入到产品数据库中。

经过一段时间的金丝雀发布后,最终所有的计价功能调用都进入产品 / 计价服务,老的计价服务和相应的数据库被卸载。

当然这是在非常理想的情况下,现实情况比这个复杂的多,例如部分需要合并部分需要拆分,采用不同的编程语言,采用不同的数据库技术,其它微服务对相关微服务的依赖等等。另外典型的微服务架构中不同的微服务由不同的组 / 部门去维护,相关的沟通协作也是一个不容忽视的成本,所以在业务不稳定或者理解不充分的情况下贸然实施微服务的代价是非常巨大的!

 更严谨的设计

微服务架构比单体服务更容易发生问题,不但是因为分布式计算本身复杂性带来的各种问题(如一致性问题),而且各种流行的微服务框架都有这样那样的坑,以电商业务为例,用户 1 需要上架一批新产品,为了提高并发性以及降低服务之间的耦合度,当前的微服务架构采用消息总线去通知计价服务 / 仓库服务 / 产品服务进行相应处理,不幸的是,由于消息的异步性,很可能对于某个产品而言,产品服务最后被通知到,期间如果用户 2 查询到了对应的库存但却发现相关的产品不存在(如下图所示),这显然违反了因果一致性(casual consistency)!

 纠错的难度

想象一下订单服务的实现需要调用仓库服务,计价服务,支付服务等多个服务,中间任何一个环节出错都将导致订单处理失败,有时为了提高处理的并发量,往往采用基于消息总线的异步方式,这样想做到快速定位到错误根源对开发人员是一个不小的挑战,一般而言,我们不得不从两个方面入手:

应用级别的关联,所有异步调用都必须引入消息标识关联

借助于微服务框架的分布式追踪机制,日志聚合等功能(如 zipkin,CloudWatch 等)

即便这样,出错调试的困难度和需要的时间也和单体服务不是一个量级的,而且大部分情况下,在单体服务中很容易重现并在本地通过单步跟踪快速解决的问题,对于微服务而言就变得不那么容易了。

 依赖自动化的部署能力

在很多介绍微服务架构优点的文章中,常见的一条就是“易于部署”,实际上之所以“易于部署”,是拿单个“微服务“和单体服务相比较而言的,但是部署构成企业业务的几十个甚至上百个微服务的总体复杂度绝对比单体服务大的多,这就是为什么所有基于微服务架构的应用都必须依赖自动化的部署能力,这对体术团队提出了两方面要求:

掌握自动化运维工具(如 Ansible)和相关的设计模式 (如服务器提供模式、服务器模版管理模式、基础架构定义模式等 [3])

微服务本身是快速部署匹配的,如果不是则需要进行重构 [4]。

业务方面的思考

从业务角度我们必须思考以下这些问题:

你的业务体量到底有多大,会不会成长为类似于 / 接近于 Amazon/Netflix/Google/ 阿里 / 腾讯这些巨头体量的下一个巨头?

如果会,那么多长时间,几年还是几十年?

实施电商后的产品升级 / 运维 / 扩展谁来做,能否提供足够的技术实力来应付微服务框架中的各种潜在风险

对业务的理解是否非常深刻,还是只停留在初级阶段?

公司组织结构是否有利于实施微服务架构?

是否有其他更为简单的解决方案

总之,作为系统架构师或者决策人员,我们要做的就是透过“绚丽包装”的外表理解各种技术架构的本质从而避免过度设计给企业带来巨大的风险,在这点上 Jeff Dean 在其稳重“challenges in building large-scale information retrieval systems”中的经典名言值得我们借鉴 [5]:

Design for ~10*growth, plan to rewrite before ~100*

演进路线

Martin Fowler 在其“MonolithFirst”一文 [5] 中明确指出:

几乎所有成功的微服务案例全部来源于业务足够复杂的单体服务

几乎所有不成功的微服务案例都是直接从头开发

实际上作为传统行业实施电商一个稳妥的方案是从单体开始,随着业务变得越来越复杂逐步慢慢演进到微服务,具体来说:

单体服务的实施中需要采用良好的编程习惯,使得整个系统模块化而且业务边界清晰,如果一开始对业务不太熟悉,这需要不断的重构。

单体服务本身应该尽量遵循云部署的那些基本原则,诸如无状态、通过环境变量注入配置信息等 [4]。

在电商业务变得足够复杂的情况下,逐步对有关服务进行拆分,需要注意的是此处只是逻辑上的拆分

加强对自动化运维能力的建设。

最终随着企业组织结构的逐步调整过渡到微服务架构。

结论

微服务的出现给传统企业实施电商业提供了强大 / 灵活 / 敏捷的框架,但同时也对无论技术还是业务上都提出了更高 / 更严格的要求,不重视这些潜在风险将带来巨大风险,所以微服务不是企业电商解决方案的银弹,通常只有采取更为务实严谨的演进路线才能实现我们的目标。

我大概在 2006 年开始参与架构设计,原以为学习架构就像学习编程语言一样,先了解基本的语法,再研究细节和原理,然后实践一下就能够快速掌握。 但真正深入后才发现,架构设计的难度和复杂度要高很多。

从最早开始接触架构设计,到自我感觉彻底掌握架构设计的精髓,我至少花费了 8 年的时间。 我曾经以为是自己天资愚笨才会这样,后来我带了团队,看到几乎每个程序员在尝试架构设计的时候,都面临着我曾经遇到过的各种困惑和瓶颈。

今天,我想把我过去所有的经验都分享在裙69-75-79-75-1里,里面都是我精心录制成视频供大家免费下载,希望能帮你快速成为一名架构师。

参考资料

Building Microservices: Designing Fine-Grained Systems, Publisher: O'Reilly Media; 1 edition (February 20, 2015)

https://en.wikipedia.org/wiki/Conway%27s_law

Infrastructure as Code: Managing Servers in the Cloud, Publisher: O'Reilly Media; 1 edition (June 27, 2016)

https://12factor.net

https://static.googleusercontent.com/media/research.google.com/en//people/jeff/WSDM09-keynote.pdf

https://martinfowler.com/bliki/MonolithFirst.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构

微服务是传统企业电商解决方案的银弹吗?

近几年,微服务成为最流行的技术名词之一,尤其受到亚马逊、阿里等电商巨头的影响,很多传统企业在实施电商过程中也纷纷往微服务架构靠拢,相比单体架构,微服务确实有很多...

2036
来自专栏华章科技

你真的知道怎么用大数据来驱动产品和运营吗?

本文作者为桑文锋,Sensors Data创始人&CEO,前百度大数据部技术经理。2005 毕业于浙江大学计算机系,2007年加入百度并负责组建并带领团队,从零...

662
来自专栏灯塔大数据

荐读|数据科学家和工程师的“五诫”

在实际的工作中,数据科学家们不仅要学会如何实用工具,还要懂得如何与同事合作。The Yhat Blog这篇文章探讨了在实际的数据建模和数据处理的过程中数据科学家...

3314
来自专栏区块链领域

Datawallet的与众不同之处

很多人会问“Datawallet到底是什么,它与那些宣称要为我的数据提供托管服务并创建市场的公司有什么不同?”这篇文章就解答了这些疑惑。这些公司运行的共同点在于...

1054
来自专栏杨建荣的学习笔记

对于技术焦虑的一点想法

有一个公众号是 吃草的罗汉,最近看他的一篇文章,我被里面的一小段内容吸引了,他这样写道: 在成长的道路上,有时你越是不喜欢的事,越会阴差阳错的让你遇见 在《我也...

3349
来自专栏大数据挖掘DT机器学习

入门数据分析,我应该学习什么编程语言?

很多时候,当和人们讨论怎么开始学习数据科学,一个疑惑总是出现在我们面前: 我不知道应该学什么编程语言。 不仅仅是编程语言,这还包括软件系统,例如TABLEAU,...

3207
来自专栏云计算D1net

“云”领生活:触手可及的云计算

有一个楚国人出门远行.他在乘船过江的时候,一不小心,把随身带着的剑落到江中的急流里去了.船上的人都大叫:“剑掉进水里了!这个楚国人马上用一把小刀在船舷上刻了个记...

3844
来自专栏用户3246163的专栏

你做的是微服务还是小单体?

先讲一个关于微服务的小故事:第一次接触到微服务这个概念的时候,我的第一反应以为微服务就是微信提供的某种服务。那段时间正是微信生态开始爆炸繁衍的时候,全中国好像把...

1185
来自专栏PPV课数据科学社区

数据分析那些事(数据分析师入门必看)

经常有网友会对数据分析方面有一些困惑,并且咨询我该怎么办?并且经常是同样的问题,所以觉得有必要对一些经典共性的问题进行整理,与大家分享,这里并非标准答案,仅作参...

3885
来自专栏新智元

清华大学突破量子纠缠接口新纪录,首次实现25个量子接口之间的量子纠缠

1555

扫码关注云+社区